def calculateKDE(self, kernel='gaussian', bandwidth=None): """ Calculate the Kernel Density Estimation. This will generate a high-resolution "image" of the localisations based on the kernel density estimate of the point localisations. If no bandwidth is specified an optimal bandwidth parameter is estimated using cross-validation. This is the default behaviour. Input: kernel (str): Kernel to be used for the kernel density estimation Possible values are 'gaussian' (default) and 'tophat' bandwidth (float,None): The bandwidth for the kernel density estimation If set to None cross-validation will be used to find the optimal parameter. """ if not self.runCluster: print('You need to run the clustering first!') return if self.contour is not None: print("It seems as if you already set up a pixel image.") print("Use resetImage() and try again") return self.contour = Contour() self.contour.setData(self.cluster.getResult(self.edgePoints)) self.contour.kernelDensityEstimate(kernel=kernel, bandwidth=bandwidth)
def test_internal_diagonals(self): cseg1 = Contour([0, 2, 3, 1]) cseg2 = Contour([1, 0, 4, 3, 2]) self.assertEqual(cseg1.internal_diagonals(1), InternalDiagonal([1, 1, -1])) self.assertEqual(cseg1.internal_diagonals(2), InternalDiagonal([1, -1])) self.assertEqual(cseg2.internal_diagonals(1), InternalDiagonal([-1, 1, -1, -1])) self.assertEqual(cseg2.internal_diagonals(2), InternalDiagonal([1, 1, -1]))
def add_date_2d(self, x_values, y_values, z_values, dates_ticks=[], stns_ticks=[], cmap='', time_unit='month', interval="equal", value_type="raw", colorbar_max=30, colorbar_min=0, colorbar_interval=2): levels = np.linspace(colorbar_min, colorbar_max, (colorbar_max - colorbar_min) + 1) cont = Contour(self) plt.xticks(x_values[0], dates_ticks, fontsize=11) plt.yticks(zip(*y_values)[0], stns_ticks, fontproperties=font, fontsize=9) cmap = plt.get_cmap(cmap) #print z_values #print x_values #print y_values cs = cont.contour_plotting(x_values, y_values, z_values, levels, cmap) cbar = self.fig.colorbar(cs) colorbar_range = list( self.get_colorbar_range(colorbar_max, colorbar_min, colorbar_interval)) cbar.set_ticks(colorbar_range) cbar.set_ticklabels(map(str, colorbar_range))
def test_comparison_matrix(self): cseg1 = Contour([0, 2, 3, 1]) cseg2 = Contour([1, 2, 3, 0, 3, 1]) result1 = ComparisonMatrix([[0, 1, 1, 1], [-1, 0, 1, -1], [-1, -1, 0, -1], [-1, 1, 1, 0]]) result2 = ComparisonMatrix([[0, 1, 1, -1, 1, 0], [-1, 0, 1, -1, 1, -1], [-1, -1, 0, -1, 0, -1], [1, 1, 1, 0, 1, 1], [-1, -1, 0, -1, 0, -1], [0, 1, 1, -1, 1, 0]]) self.assertEqual(cseg1.comparison_matrix(), result1) self.assertEqual(cseg2.comparison_matrix(), result2)
def __add_contour(): self.is_fit = False cont = Contour(pil_image=self.canvas_initial_state, name='Contour' + str(len(self.contours) + 1)) if cont.size() > 0: self.contours.append(cont) cont.dump(self.project_path) self.apply_contours()
def test_subsets_normal(self): cseg = Contour([0, 3, 1, 4, 2]) result = {(0, 1, 3, 2): [Contour([0, 1, 4, 2])], (0, 2, 1, 3): [Contour([0, 3, 1, 4])], (0, 2, 3, 1): [Contour([0, 3, 4, 2])], (0, 3, 1, 2): [Contour([0, 3, 1, 2])], (2, 0, 3, 1): [Contour([3, 1, 4, 2])]} self.assertEqual(cseg.subsets_normal(4), result)
def __init__(self, name="", samples=0, use_spline=False): Contour.__init__(self) self.name = "" self.description = "" # parametric representation of the airfoil dist along surface # vs. x and vs. y self.parax = [] self.paray = [] self.nosedist = 0.0 if (name != ""): self.load(name, samples, use_spline)
def __init__(self, name = "", samples = 0, use_spline = False): Contour.__init__(self) self.name = "" self.description = "" # parametric representation of the airfoil dist along surface # vs. x and vs. y self.parax = [] self.paray = [] self.nosedist = 0.0 if ( name != "" ): self.load(name, samples, use_spline)
def test_reduction_bor(self): cseg1 = Contour([0, 6, 1, 4, 3, 5, 2]) cseg2 = Contour([12, 10, 13, 11, 7, 9, 8, 6, 3, 5, 4, 1, 0, 2]) cseg3 = Contour([7, 10, 9, 0, 2, 3, 1, 8, 6, 2, 4, 5]) self.assertEqual(cseg1.reduction_bor(53), [Contour([0, 2, 1]), 2]) self.assertEqual(cseg1.reduction_bor(35), [Contour([0, 3, 2, 1]), 2]) self.assertEqual(cseg2.reduction_bor(53, False), [Contour([12, 10, 13, 0, 2]), 2]) self.assertEqual(cseg3.reduction_bor(35, False), [Contour([7, 10, 0, 8, 5]), 2]) self.assertEqual(cseg3.reduction_bor(35, True), [Contour([2, 4, 0, 3, 1]), 2]) self.assertEqual(cseg2.reduction_bor(53, False), [Contour([12, 10, 13, 0, 2]), 2]) self.assertEqual(cseg3.reduction_bor(355, False), [Contour([7, 10, 0, 5]), 3]) self.assertEqual(cseg3.reduction_bor(555, True), [Contour([2, 3, 0, 1]), 3])
def get_contour(reset=False): """ Gets existing contour data """ contour = Contour() if reset: return contour contour_data_file = os.path.join(cli.world_dir, cli.contour_file_name) try: contour.read(contour_data_file) except (EnvironmentError, ContourLoadError), e: if e.errno != errno.ENOENT: error('could not read contour data: %s' % e)
def __init__(self, name="", samples=0, use_spline=False): Contour.__init__(self) # locate airfoils data path relative to top level script datapath = os.path.split(os.path.abspath(sys.argv[0]))[0] + "/data" self.datapath = datapath self.name = "" self.description = "" # parametric representation of the airfoil dist along surface # vs. x and vs. y self.parax = [] self.paray = [] self.nosedist = 0.0 if (name != ""): self.load(name, samples, use_spline)
def __init__(self, name = "", samples = 0, use_spline = False): Contour.__init__(self) # locate airfoils data path relative to top level script datapath = os.path.split(os.path.abspath(sys.argv[0]))[0] + "/data" self.datapath = datapath self.name = "" self.description = "" # parametric representation of the airfoil dist along surface # vs. x and vs. y self.parax = [] self.paray = [] self.nosedist = 0.0 if ( name != "" ): self.load(name, samples, use_spline)
def test_fuzzy_membership_matrix(self): cseg1 = Contour([0, 2, 3, 1]) cseg2 = Contour([1, 2, 3, 0, 3, 1]) result1 = FuzzyMatrix([[0, 1, 1, 1], [0, 0, 1, 0], [0, 0, 0, 0], [0, 1, 1, 0]]) result2 = FuzzyMatrix([[0, 1, 1, 0, 1, 0], [0, 0, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0], [1, 1, 1, 0, 1, 1], [0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 1, 0]]) self.assertEqual(cseg1.fuzzy_membership_matrix(), result1) self.assertEqual(cseg2.fuzzy_membership_matrix(), result2)
def process(self, frame, name="TrainingSamples/Image_"): # preprocessing for contour detection preprocessed = PreProcessing().background_contour_removal(frame) # find contours using algorithm by Suzuki et al. (1985) contours, hierarchy = cv.findContours(preprocessed, cv.RETR_TREE, cv.CHAIN_APPROX_NONE) # limit observed contours if len(contours) > 500: contours = contours[:500] # ignore first contour, as it is outer border of the frame contours = contours[1:] hierarchy = hierarchy[0][1:] - 1 hierarchy = np.where(hierarchy < 0, -1, hierarchy) if len(contours) == 0: return preprocessed # initialize contour object from each contour in contour list binarized = PreProcessing().custom_binarize(frame) contourList = [ Contour(contour=cnt, imgShape=frame.shape, frameBinary=binarized) for cnt in contours ] # filter, classify and group segmented contours sg = Segmentation(contourList, hierarchy, frame.shape) sg.group_and_classify() filtered = sg.get_contours() if len(filtered) == 0: return preprocessed # colouring preprocessing for ease in debugging preprocessed = cv.cvtColor(preprocessed, cv.COLOR_GRAY2BGR) lines = LineOrdering(filtered).get_lines(frame) # label contours with additional positional information lines = sg.label_contours(lines) for l in range(len(lines)): line = lines[l] for i in range(len(line)): cnt = line[i] cv.putText(frame, str(l) + str(i), (cnt.center[0], cnt.center[1]), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 1) solutions = [ self.solver.solve([cnt.unwrap() for cnt in line], frame) for line in lines if len(line) > 2 ] return preprocessed # orderedImage
def addAIPolygon(self, points): qPoints = [QtCore.QPoint(x,y) for x,y in points]# if len(self.polys) ==0: if self.QGitem is None: self.QGitem = Contour(point_size=1.5) self.addItem(self.QGitem) self.updatePolyPoint(self.QGitem, qPoints[0]) self.QGitem.setZValue(len(self.polys) + 1) self.QGitem.prepareGeometryChange() self.QGitem.points = qPoints self.QGitem.addPoint((qPoints[0])) else: self.QGitem = self.polys[0] self.QGitem.prepareGeometryChange() self.QGitem.points = qPoints self.QGitem.addPoint((qPoints[0])) self.finalisePolygon() self.update()
def add_date_2d(self, x_values, y_values, z_values, dates_ticks=[], stns_ticks=[], cmap='', time_unit='month', interval="equal", value_type="raw", colorbar_max=30, colorbar_min=0, colorbar_interval=2): levels = np.linspace(colorbar_min, colorbar_max, (colorbar_max-colorbar_min)+1) cont = Contour(self) plt.xticks(x_values[0], dates_ticks, fontsize=11) plt.yticks(zip(*y_values)[0], stns_ticks, fontproperties=font, fontsize=9) cmap = plt.get_cmap(cmap) #print z_values #print x_values #print y_values cs = cont.contour_plotting(x_values, y_values, z_values, levels, cmap) cbar = self.fig.colorbar(cs) colorbar_range = list(self.get_colorbar_range(colorbar_max, colorbar_min, colorbar_interval)) cbar.set_ticks(colorbar_range) cbar.set_ticklabels(map(str, colorbar_range))
def find_contours(self, method=cv2.CHAIN_APPROX_NONE): image_rgb = self._blur_original_image() channels = self._get_single_channel_images(image_rgb) edges = self._combined_edges(channels) _, contours, hierarchy = cv2.findContours(edges, mode=cv2.RETR_EXTERNAL, method=method) contours = [Contour(points) for points in contours] contours = [cont for cont in contours if self.area_filter_accept(cont)] return sorted(contours, key=lambda c: c.measurements().area, reverse=True), edges
def main(onlyfiles=None): if (onlyfiles == None): mypath = getcwd() + r'/pdfs/' onlyfiles = [f for f in listdir(mypath) if isfile(join(mypath, f))] print(onlyfiles) for file in onlyfiles: if (utils.getFileType(file) == '.PDF' or utils.getFileType(file) == '.pdf'): utils.pdfToImg(file) else: utils.saveImgOnRightFolder(file) utils.invertColor(file) a = Contour(file) a.start() newContours = a.filterCountours() a.saveContours(newContours) a.saveCSVs(newContours)
def computeMask(self): self.corners = np.array(self.corners) self.contour = Contour( np.array([self.corners[:, 1], self.corners[:, 0]]).transpose(), (self.height, self.width)) self.mask = self.contour.interior if (debug): plt.figure(figsize=(15, 30)) plt.subplot(131) plt.imshow(self.contour.array, cmap="gray") plt.title("Hull") plt.subplot(132) plt.imshow(self.mask, cmap="gray") plt.title("Mask") plt.subplot(133) if (self.n == 1): plt.imshow(self.image * self.mask, cmap="gray") else: im = mycv2.cvtBGRtoRGB(self.image) * np.array( [self.mask for i in range(self.n)]).transpose(1, 2, 0) plt.imshow(im.astype(np.float32), norm=None) plt.title("Masked image") plt.show()
def test_class_vector_ii(self): cseg = Contour([0, 1, 3, 2]) self.assertEqual(cseg.class_vector_ii(), [5, 1])
% (len(shapefiles), len(intensity), len(be), len(hh))) # Maybe I can collect all the shapefiles into one database? # All the intensity files can be in a VRT print("Processing Bare Earth") be_folder = os.path.join(datadir, "be") if not os.path.exists(be_folder): os.mkdir(be_folder) s = Surface(overwrite=False) betiff = s.grid_to_tiff(be, be_folder) s = None print("Building mosaic") vrt = gdal.BuildVRT(os.path.join(datadir,"be.vrt"), betiff) print("Processing Highest Hits") hh_folder = os.path.join(datadir, "hh") if not os.path.exists(hh_folder): os.mkdir(hh_folder) s = Surface(overwrite=False) hhtiff = s.grid_to_tiff(hh, hh_folder) s = None print("Building mosaic") vrt = gdal.BuildVRT(os.path.join(datadir,"hh.vrt"), hhtiff) c = Contour() c.build() pass
import cv2 from preprocessing import Preprocess from thresholding import Threshold from smoothing import Smooth from contour import Contour from decision import Decision import os SAMPLE_IMAGE = 'thresh1.jpg' frame = cv2.imread(SAMPLE_IMAGE, cv2.IMREAD_UNCHANGED) thresholded_image = frame smooth_image = Smooth().smoothing(thresholded_image) contour = Contour().find_contours(smooth_image) center, radius, probability = Decision().decision(contour, smooth_image) if radius is not 0: # cv2.putText(frame, str(probability * 100) + '%', center, cv2.FONT_HERSHEY_PLAIN, 1, (255, 0, 0), 2) print("Probability: " + str(probability * 100) + '%') cv2.circle(frame, center, radius, (255, 0, 0), 2) cv2.imshow('Main video', frame) cv2.waitKey(0) cv2.destroyAllWindows()
def add_map(self, values, selected_stations, map_lat_max, map_lat_min, map_lon_max, map_lon_min, color="#000000", filled=True): map = Map(self) self.fig.subplots_adjust(top=0.93) ulat, llat, ulon, llon = map_lat_max, map_lat_min, map_lon_max, map_lon_min m = Basemap(projection='merc', llcrnrlat=llat, urcrnrlat=ulat, llcrnrlon=llon, urcrnrlon=ulon, resolution='i') #cm = mpl.cm.get_cmap(self.colorbar_type) # cdict = {'red': ((0., 0, 0), (0.4, 1, 1),(0.6, 1, 1),(1, 0.5, 0.5)), # 'green': ((0., 0, 0),(0.4, 1, 1), (0.6, 1, 1), (1, 0, 0)), # 'blue': ((0., 1, 1),(0.4, 1, 1), (0.6, 1, 1), (1, 0, 0))} # cm = mpl.colors.LinearSegmentedColormap('my_colormap', cdict, 256) if 'TWN_COUNTY' in self.shapefile: m.readshapefile(self.shapefile['TWN_COUNTY']['path'], 'TWN_COUNTY', color=self.shapefile['TWN_COUNTY']['color']) if 'TWN_adm0' in self.shapefile: m.readshapefile(self.shapefile['TWN_adm0']['path'], 'TWN_adm0', color=self.shapefile['TWN_adm0']['color']) m.fillcontinents(color="#FFFFFF", zorder=0) xlist, ylist, clist, stlist = self._read_coordinate(m, values, selected_stations) s = plt.scatter(xlist, ylist, s=14, marker='x', zorder=2, color=color) m.drawmapboundary(fill_color="#F0F8FF", zorder=5) if filled: levels = np.linspace(0, 40, 41) cont = Contour(self) cm = mpl.cm.get_cmap('YlGnBu') cmap = plt.get_cmap(cm) x_min, y_min = m(map_lon_min, map_lat_min+0.0000001) x_max, y_max = m(map_lon_max, map_lat_max) x2 = np.array(np.linspace(x_min, x_max, (map_lon_max-map_lon_min)*10+1)) y2 = np.array(np.linspace(y_min, y_max, (map_lat_max-map_lat_min)*10+1)) x3, y3 = np.meshgrid(x2, y2) wait_to_fill_values = [True] * len(clist) #z_values = np.zeros((len(y2), len(x2))) z_values = np.random.randint(40, size=(len(y2), len(x2))) # 先判斷是否有在裡面 沒有的話畫空白值? # 也許不要contourf,用polygon # 內插的方法 for i, x in enumerate(x2): for j, y in enumerate(y2): for idx, value in enumerate(clist): #stlist if wait_to_fill_values[idx] and x > xlist[idx] and y> ylist[idx]: wait_to_fill_values[idx] = False z_values[j][i] = float(value) break cs = cont.contour_plotting(x3, y3, z_values, levels, cmap) cbar = self.fig.colorbar(cs) colorbar_range = list(self.get_colorbar_range(40, 0, 5)) cbar.set_ticks(colorbar_range) #cbar.set_ticklabels(map(str, colorbar_range)) # add text self._add_station_texts({'x':xlist, 'y':ylist, 'stn':stlist, 'value':clist})
def mousePressEvent(self, event): pos = event.scenePos() if event.button() == QtCore.Qt.LeftButton and self.mode == self.modes[1]: self.overrideCursor(QtCore.Qt.CrossCursor) if self.line is None or self.polyFinished: self.line = Contour(point_size=1.5) self.addItem(self.line) self.updatePolyPoint(self.line, pos) elif self.line and not self.polyFinished: self.line.prepareGeometryChange() self.line.points[0] = pos self.line.setPos(pos) if self.QGitem: self.QGitem.prepareGeometryChange() if len(self.QGitem.points) >1 and self.isClose(pos, self.QGitem.points[0]): self.overrideCursor(QtCore.Qt.PointingHandCursor) pos = self.QGitem.points[0] self.QGitem.highlightVertex(0) #need to add to close the polygone self.QGitem.addPoint(pos) if self.QGitem.points[0] == pos: self.finalisePolygon() else: self.QGitem = Contour(point_size=1.5) self.addItem(self.QGitem) self.updatePolyPoint(self.QGitem, pos) self.QGitem.setZValue(len(self.polys)+1) event.accept() self.update() if event.button() == QtCore.Qt.RightButton and self.mode == self.modes[1]: self.overrideCursor(QtCore.Qt.CrossCursor) if self.line: if len(self.line.points) > 1 and self.QGitem: self.QGitem.prepareGeometryChange() self.QGitem.remove(-1) if self.QGitem.points==1: self.removeItem(self.QGitem) self.removeItem(self.line) self.line=None return self.line.prepareGeometryChange() self.line.points[0] =self.QGitem.points[-1] event.accept() self.update() if self.mode == self.modes[2] and event.button() == QtCore.Qt.LeftButton: self.overrideCursor(QtCore.Qt.ClosedHandCursor) self.selectShapeByPoint(pos) event.accept() self.update() if self.mode == self.modes[2] and event.button() == QtCore.Qt.MiddleButton: self.overrideCursor(QtCore.Qt.CrossCursor) if len(self.polys) > 0: self.selectedContour = self.polys[0] pts = self.getClosestPoint(pos) self.selectedContour.points.insert(pts[1], pos) if self.vertexSelected() and event.button() == QtCore.Qt.RightButton and self.mode == self.modes[2]: self.overrideCursor(QtCore.Qt.PointingHandCursor) self.selectedContour.prepareGeometryChange() self.selectedContour.remove(self.selectedVertex) if len(self.selectedContour.points) ==1: self.removeItem(self.selectedContour) self.update()
def test_interval_succession(self): cseg = Contour([0, 1, 3, 2]) self.assertEqual(cseg.interval_succession(), [1, 2, -1])
def loadPixelImage(self, fname, pixelSize=1.0, start=None, end=None, padding=[20, 20]): """ Load a pixel image into the pipeline. Instead of generating a super-resolved image from point localisation data the pipeline can load any pixel image instead. The consecutive steps of contour fitting and curvature calculation can then be used on this input. Input: fname (str): Image file to load pixelSize (float): Set the pixel size in nm start (int): The first frame to load end (int): The last frame to include padding (list): Must be a list of two int specifying the width in pixels of the dark region that will be added to the images at the outside edges. This is done to allow the constricting contour fitting to fully close on objects even if they are extending out of the frame. """ if self.contour is not None: print("It seems as if you already set up a pixel image.") print("Use resetImage() and try again") return # Set the name of the object self.name = fname # Load the image file using tifffile.py tmpImage = Tiff.TiffFile(fname) self.images = [tmpImage[i].asarray() for i in range(len(tmpImage))] self.images = self.RGBtoGreyscale(self.images) # Select the frame range if start is None: start = 1 if end is None: end = len(self.images) self.images = self.images[start - 1:end] # Save the number of frames self.nrOfFrames = len(self.images) # Add some dark pixel paddings around the image. This makes contour # detection easier if the object is extending out of the image border. if padding: xpad, ypad = padding newImages = list() for image in self.images: # Create arrays containing zeros zerosX = np.zeros([np.shape(image)[0], xpad]) zerosY = np.zeros([ypad, np.shape(image)[1] + 2 * xpad]) # Add them to the original image newImage = np.concatenate([zerosX, image, zerosX], axis=1) newImage = np.concatenate([zerosY, newImage, zerosY], axis=0) # Add the padded image to the list newImages.append(newImage) # Replace the original images with the padded ones. self.images = newImages # Initialise the Contour class and set the images self.contour = Contour() self.contour.images = self.images self.contour.pixelSize = [float(pixelSize), 0.0, float(pixelSize), 0.0] print("Finished loading %d frames from %s" % (len(self.images), fname)) return
def add_map(self, values, selected_stations, map_lat_max, map_lat_min, map_lon_max, map_lon_min, color="#000000", filled=True): map = Map(self) self.fig.subplots_adjust(top=0.93) ulat, llat, ulon, llon = map_lat_max, map_lat_min, map_lon_max, map_lon_min m = Basemap(projection='merc', llcrnrlat=llat, urcrnrlat=ulat, llcrnrlon=llon, urcrnrlon=ulon, resolution='i') #cm = mpl.cm.get_cmap(self.colorbar_type) # cdict = {'red': ((0., 0, 0), (0.4, 1, 1),(0.6, 1, 1),(1, 0.5, 0.5)), # 'green': ((0., 0, 0),(0.4, 1, 1), (0.6, 1, 1), (1, 0, 0)), # 'blue': ((0., 1, 1),(0.4, 1, 1), (0.6, 1, 1), (1, 0, 0))} # cm = mpl.colors.LinearSegmentedColormap('my_colormap', cdict, 256) if 'TWN_COUNTY' in self.shapefile: m.readshapefile(self.shapefile['TWN_COUNTY']['path'], 'TWN_COUNTY', color=self.shapefile['TWN_COUNTY']['color']) if 'TWN_adm0' in self.shapefile: m.readshapefile(self.shapefile['TWN_adm0']['path'], 'TWN_adm0', color=self.shapefile['TWN_adm0']['color']) m.fillcontinents(color="#FFFFFF", zorder=0) xlist, ylist, clist, stlist = self._read_coordinate( m, values, selected_stations) s = plt.scatter(xlist, ylist, s=14, marker='x', zorder=2, color=color) m.drawmapboundary(fill_color="#F0F8FF", zorder=5) if filled: levels = np.linspace(0, 40, 41) cont = Contour(self) cm = mpl.cm.get_cmap('YlGnBu') cmap = plt.get_cmap(cm) x_min, y_min = m(map_lon_min, map_lat_min + 0.0000001) x_max, y_max = m(map_lon_max, map_lat_max) x2 = np.array( np.linspace(x_min, x_max, (map_lon_max - map_lon_min) * 10 + 1)) y2 = np.array( np.linspace(y_min, y_max, (map_lat_max - map_lat_min) * 10 + 1)) x3, y3 = np.meshgrid(x2, y2) wait_to_fill_values = [True] * len(clist) #z_values = np.zeros((len(y2), len(x2))) z_values = np.random.randint(40, size=(len(y2), len(x2))) # 先判斷是否有在裡面 沒有的話畫空白值? # 也許不要contourf,用polygon # 內插的方法 for i, x in enumerate(x2): for j, y in enumerate(y2): for idx, value in enumerate(clist): #stlist if wait_to_fill_values[ idx] and x > xlist[idx] and y > ylist[idx]: wait_to_fill_values[idx] = False z_values[j][i] = float(value) break cs = cont.contour_plotting(x3, y3, z_values, levels, cmap) cbar = self.fig.colorbar(cs) colorbar_range = list(self.get_colorbar_range(40, 0, 5)) cbar.set_ticks(colorbar_range) #cbar.set_ticklabels(map(str, colorbar_range)) # add text self._add_station_texts({ 'x': xlist, 'y': ylist, 'stn': stlist, 'value': clist })
def test_reduction_window(self): cseg1 = Contour([7, 10, 9, 0, 2, 3, 1, 8, 6, 2, 4, 5]) cseg2 = Contour([7, 10, 0, 1, 8, 2, 5]) cseg3 = Contour([7, 10, 0, 8, 5]) cseg4 = Contour([7, 10, 0, 5]) cseg5 = Contour([0, 3, 3, 1, 2, 4]) cseg6 = Contour([0, 3, 1, 4]) cseg7 = Contour([0, 3, 3, 1, 2]) cseg8 = Contour([0, 3, 1, 2]) cseg9 = Contour([12, 10, 13, 11, 7, 9, 8, 6, 3, 5, 4, 1, 0, 2]) cseg10 = Contour([12, 10, 13, 7, 3, 0, 2]) cseg11 = Contour([0, 2, 1, 3]) self.assertEqual(cseg1.reduction_window(3, False), Contour([7, 10, 0, 3, 1, 8, 2, 5])) self.assertEqual(cseg1.reduction_window(3, True), Contour([5, 7, 0, 3, 1, 6, 2, 4])) self.assertEqual(cseg1.reduction_window(5, False), cseg2) self.assertEqual(cseg2.reduction_window(5, False), cseg3) self.assertEqual(cseg3.reduction_window(5, False), cseg4) self.assertEqual(cseg5.reduction_window(5, False), cseg6) self.assertEqual(cseg7.reduction_window(5, False), cseg8) self.assertEqual(cseg9.reduction_window(5, False), cseg10) self.assertEqual(cseg5.reduction_window(5, True), cseg11)
def test_cps_position(self): cseg = Contour([2, 8, 12, 9, 5, 7, 3, 12, 3, 7]) result = [(2, 0), (8, 1), (12, 2), (9, 3), (5, 4), (7, 5), (3, 6), (12, 7), (3, 8), (7, 9)] self.assertEqual(cseg.cps_position(), result)
def test_adjacency_series_vector(self): cseg1 = Contour([0, 2, 3, 1]) cseg2 = Contour([1, 2, 3, 0, 3, 1]) self.assertEqual(cseg1.adjacency_series_vector(), [2, 1]) self.assertEqual(cseg2.adjacency_series_vector(), [3, 2])
def test_class_representatives(self): cseg = Contour([0, 1, 3, 2]) result = [Contour([0, 1, 3, 2]), Contour([3, 2, 0, 1]), Contour([2, 3, 1, 0]), Contour([1, 0, 2, 3])] self.assertEqual(cseg.class_representatives(), result)
class ActiveContours(): def __init__(self, frames, path, spechist=False): self.path = path self.frames = self.preprocess(frames, spechist) if (len(self.frames[0].shape) == 2): self.shape = self.frames[0].shape elif (len(self.frames[0].shape) == 3): self.shape = self.frames[0].shape[:-1] else: raise ValueError("Frames shapes unvalid : " + str(self.frames[0].shape)) def preprocess(self, frames, spechist=False): if (spechist): specification = SpecHist(frames[0]) return [ cv2.blur( mycv2.resize(specification.specify(image), PARAMS["activeContours"]["maxwidth"]), (7, 7)) for image in frames ] else: self.noblurframes = [ mycv2.resize(image, PARAMS["activeContours"]["maxwidth"]) for image in frames ] return [cv2.blur(image, (7, 7)) for image in self.noblurframes] def run(self): self.mask = Mask(self.frames[0]) if (PARAMS["verbose"]): self.mask.render("contour") self.mask.computeDensity() if (PARAMS["debug"]): self.mask.render("density") self.currentcontour = self.mask.contour RESULT = [] for i in range(0, len(self.frames)): RESULT += [self.computeSimpleFlow(i)] print(RESULT[0].shape, "SHAPE ", vid.getFPS(self.path), "FPS") print([r.shape for r in RESULT]) shape = (int(RESULT[0].shape[0] * 2), int(RESULT[0].shape[1])) print(shape) out = cv2.VideoWriter('output.avi', cv2.VideoWriter_fourcc(*'XVID'), vid.getFPS(self.path), (512, 512)) print(vid.getFPS(self.path), shape) for f, res in zip(self.noblurframes, RESULT): res3 = np.array([res, res, res]).transpose(1, 2, 0) * 255 newf = cv2.resize(np.uint8(np.concatenate([f, res3], axis=0)), (512, 512)) #plt.imshow(newf[:, :, ::-1]) #plt.show() out.write(newf) out.release() def computeSimpleFlow(self, i): print("computeSimpleFlow", i, " ", int(100 * i / len(self.frames)), "%") frame = self.frames[i] #plt.imshow(frame[:, :, ::-1]) #plt.show() """ FD = np.zeros(self.shape) for px in range(self.shape[0]): for py in range(self.shape[1]): FD[px, py] = self.mask.getDensity(frame[px, py]) plt.figure(figsize = (10, 5)) plt.subplot(121) plt.imshow(FD, cmap = "gray") plt.subplot(122) plt.imshow(FD > 0, cmap = "gray") plt.show() """ """ while(nchanges > 0 and nite < 10): nadded, nremoved = 0, 0 newpoints = self.currentcontour.get("points").copy() normals = self.currentcontour.get("normals").copy() for i in range(len(newpoints)): dc = self.mask.getDensity(frame[newpoints[i][0], newpoints[i][1]]) - self.mask.lambd if(dc < 0): newpoints[i] = self.currentcontour.getPixelToNormal(newpoints[i], - normals[i]).copy() nremoved += 1 else: p_n = self.currentcontour.getPixelToNormal(newpoints[i], normals[i]).copy() dc_p_n = self.mask.getDensity(frame[p_n[0], p_n[1]]) - self.mask.lambd if(dc_p_n > 0): newpoints[i] = p_n.copy() nadded += 1 self.currentcontour = Contour(newpoints, self.shape) nite += 1 nchanges = nadded + nremoved print(nite, nadded, nremoved, len(self.currentcontour.get("points"))) #if(PARAMS["verbose"]):self.currentcontour.render() #if(PARAMS["verbose"]):self.currentcontour.render() """ def getPiDC(pi, ni, nax): DC = np.zeros(2 * nax + 1) Pi = np.zeros((2 * nax + 1, 2)) DC[nax] = np.sign( self.mask.getDensity(frame[pi[0], pi[1]]) - self.mask.lambd) Pi[nax] += pi for j in range(1, nax + 1): temppi = self.currentcontour.getPixelToNormal( Pi[nax + j - 1], ni).copy().astype(int) Pi[nax + j] = temppi.copy() tempdc = self.mask.getDensity( frame[temppi[0] % self.shape[0], temppi[1] % self.shape[1]]) - self.mask.lambd DC[nax + j] += np.sign(tempdc) temppi = self.currentcontour.getPixelToNormal( Pi[nax - j + 1], -ni).copy().astype(int) Pi[nax - j] = temppi.copy() tempdc = self.mask.getDensity( frame[temppi[0] % self.shape[0], temppi[1] % self.shape[1]]) - self.mask.lambd DC[nax - j] += np.sign(tempdc) return Pi, DC points = self.currentcontour.get("points").copy() normals = self.currentcontour.get("normals").copy() print(len(points)) findeps = [] #findepm1 = 0 changepoints = [] #for i in range(len(newpoints)): nbloc = 10 nax = 10 nnewpoints = max(10, int(0.05 * len(points))) for i in np.linspace(0, len(points), nnewpoints + 1).astype(int)[:-1]: findepii = [] for ii in range(-nbloc, nbloc + 1): pi = points[(i + ii) % len(points)].copy() ni = normals[(i + ii) % len(normals)].copy() Pi, DC = getPiDC(pi, ni, nax) if (ii == 0): Pi0 = Pi.copy() dep = [] for j in range(nax): if (DC[j] < 0 and DC[j + 1] > 0): dep += [j + 1] for j in range(1, nax + 1): if (DC[nax + j] < 0 and DC[nax + j - 1] > 0): dep += [nax + j - 1] if (np.sum(DC) == len(DC)): dep += [len(DC) - 1] if (np.sum(DC) == -len(DC)): dep += [0] if (len(dep) == 0): dep += [nax] dep = np.array(dep) if (np.sum(dep < nax) > np.sum(dep > nax)): dep = dep[dep < nax] elif (np.sum(dep < nax) < np.sum(dep > nax)): dep = dep[dep > nax] else: dep = [nax] findepii += [np.median(dep)] findep = int(np.median(findepii)) """ if(i != 0): if(findep > findepm1 + 5): findep = findepm1 + 5 elif(findep < findepm1 - 5): findep = findepm1 - 5 findepm1 = findep """ findeps += [findep] #newpoints[i] = Pi[findep].copy() changepoints += [Pi0[findep].copy()] """ dc = self.mask.getDensity(frame[pi[0], pi[1]]) - self.mask.lambd nite = 0 if(dc < 0): while(dc < 0 and nite < 50): pi = self.currentcontour.getPixelToNormal(pi, - ni).copy() dc = self.mask.getDensity(frame[pi[0] % self.shape[0], pi[1] % self.shape[1]]) - self.mask.lambd nite += 1 else: while(dc > 0 and nite < 50): pi = self.currentcontour.getPixelToNormal(pi, ni).copy() dc = self.mask.getDensity(frame[pi[0], pi[1]]) - self.mask.lambd nite += 1 if(nite < 50):newpoints[i] = pi.copy() """ #plt.plot(np.arange(len(findeps)), np.array(findeps) - 25) #plt.show() self.currentcontour = Contour(changepoints, self.shape) if (PARAMS["verbose"]): self.currentcontour.render() return self.currentcontour.interior.copy()
def simulateContours(self, contour, numberContours, centroid): """! Metodo que genera poligonos de shapely en base a una simulacion de crecimiento/decrecimiento de un contorno de forma sinusoidal @param contour Contorno inicial @param numberContours Numero de contornos a simular @param centroid Punto del centroide @return Lista de poligonos de shapely construidos. """ contours_list = [] distances = [] N = numberContours # number of data points times = np.linspace(0, 2 * np.pi, N) f = 1.15247 # Optional!! Advised not to use data = 3.0 * np.sin(f * times + 0.001) + 0.5 + np.random.randn( N) # create artificial data with noise guess_mean = np.mean(data) guess_std = 3 * np.std(data) / (2**0.5) / (2**0.5) guess_phase = 0 oscillationSine = guess_std * np.sin(times + guess_phase) + guess_mean print("TIMES : " + str(len(times)) + "tipo " + str(times[0])) print(times) print("SINE : " + str(len(oscillationSine)) + "tipo " + str(oscillationSine[0])) print(oscillationSine) firstContour = Contour(contour, self.blueColor, "first") contours_list.append(firstContour) maxValue = -100.0 for i, value in enumerate(oscillationSine): if i + 1 < len(oscillationSine): sinusoidePoint = (times[i], oscillationSine[i]) distance = self.calculateDistanceBetweenTwoPoints( centroid[0], centroid[1], sinusoidePoint[0], sinusoidePoint[1]) distances.append(distance) print("Distance : ") print(distance) scale = random.uniform(1.1, 1.4) list_size = len(contours_list) last_contour = contours_list[list_size - 1] scaled_contour = None print("value: " + str(value)) print("maxValue: " + str(maxValue)) if value > maxValue: print("crece") new_contour = self.scaleContour(last_contour.contour, scale) scaled_contour = Contour(new_contour, self.blueColor, "increace") else: if value < maxValue: print("decrece") new_contour = self.scaleContour( last_contour.contour, scale, 1) scaled_contour = Contour(new_contour, self.pinkColor, "decreace") else: print("Se mantiene ") if scaled_contour != None: contours_list.append(scaled_contour) maxValue = value plt.plot(distances) #plt.scatter(times, oscillationSine) plt.show() #self.linearRegression(times,distances) return self.generatePolygons(contours_list)
class PointObject(IPyNotebookStyles): """ Handles super-resolution data and allows the outline (shaoe) finding """ def __init__(self): super(PointObject, self).__init__() self.name = None self.dataFrame = None self.data = None self.images = None self.originalDataFrame = None self.nrOfFrames = None self.movieMade = False self.runCluster = False self.edgePoints = True self.ROIedges = None self.cluster = None self.contour = None self.backbone = None self.curvature = None def loadFile(self, fname, dataType='rapdistorm'): """ Load a localisation file into PointObject. Currently supported input formats are rapidstorm and xyt. For xyt data has to be tab separated file with one header line containing 'x, 'y', 'frame' as labels for the columns. Additional columns may be present which will be ignored. Input: frame (str): File that should be loaded into PointObject dataType (str): Data type of the input file. Possible values are 'rapidstorm' and 'xyt'. """ if not isinstance(fname, DataFrame): self.name = fname # set the name of the object if dataType == 'rapdistorm': data = rapidstormLocalisations() elif dataType == 'xyt': data = XYTLocalisations() data.readFile(fname) self.dataFrame = data.data # we only need the DataFrame else: self.dataFrame = fname # you can also handover the DataFrame directly # Add the movieFrame column self.dataFrame['movieFrame'] = 1 # Make a backup of the original data without ROI information self.originalDataFrame = deepcopy(self.dataFrame) # Convert the DataFrame to the Dictionary lookup self.data = self._convertDataFrameToDict() # Save the number of frames self.nrOfFrames = len(self.data) def save(self, folderName=None): warnings.warn("save() is deprecated. Please use export() instead.", DeprecationWarning) self.export(folderName) def export(self, folderName=None): """ Save the extracted structure (i.e. clusters), contour lines, and curvature values to a text file. Export the caluculated data to a folder. For each step of the calculation a single file will be created containing the frame number and the relevant values. See the header for more information. The output files will be named based on the input data file name if no folderName is given. The input file name will be appended by "_clusterData.dat", "_contourData.dat", and "_curvatureData.dat" respectively. Input: folderName (str, None): Export data into this folder (will be created if it does not exist. Existing files will be overwritten!) """ # Use the input folder if not specified otherwise if folderName is None: folderName, _ = os.path.split(self.name) # Check if the folder exists, and if not ask if it should be created if not os.path.isdir(folderName): print("The specified folder doe not exist") answer = input("Create folder %s ? (y/n)" % folderName) if answer.lower() == 'y' or answer.lower() == 'yes': os.mkdir(folderName) else: print("Not saving the data.") return # Get the results try: clusterData = self.cluster.getResult() except AttributeError: clusterData = None print("Clustering data not present. Not saving cluster data.") try: contourData = self.contour.getResult(smoothed=True) except AttributeError: contourData = None print("Contour data not present. Not saving contour data.") try: curvatureData = self.curvature.getResult() curvatureDataSelected = self.curvature.contourSelected except AttributeError: curvatureData = None print("Curvature data not present. Not saving curvature data.") # Get the name of the object _, objectName = os.path.split(self.name) # Define open the file hooks if clusterData is not None: clusterFile = open( os.path.join(folderName, '%s_clusterData.dat' % objectName), 'w') clusterFile.write('x_in_nm\ty_in_nm\tframe\n') if contourData is not None: contourFile = open( os.path.join(folderName, '%s_contourData.dat' % objectName), 'w') contourFile.write('x_in_nm\ty_in_nm\tframe\n') if curvatureData is not None: curvatureFile = open( os.path.join(folderName, '%s_curvatureData.dat' % objectName), 'w') curvatureFileSelected = open( os.path.join(folderName, '%s_curvatureDataSelected.dat' % objectName), 'w') curvatureFile.write( 'x_in_nm\ty_in_nm\tcurvature_in_(1/nm)\tframe\n') curvatureFileSelected.write( 'x_in_nm\ty_in_nm\tcurvature_in_(1/nm)\tside\tframe\n') # Save the data for frame in range(1, (self.nrOfFrames + 1)): # Save the cluster data if clusterData is not None: XY = clusterData[frame] for row in range(np.shape(XY)[0]): clusterFile.write("%.3f\t%.3f\t%d\n" % (XY[row, 0], XY[row, 1], frame)) # Save the contour data if contourData is not None: contourPaths = contourData[frame] for path in contourPaths: XY = path.vertices for row in range(np.shape(XY)[0]): contourFile.write("%.3f\t%.3f\t%d\n" % (XY[row, 0], XY[row, 1], frame)) # Save the curvature data if curvatureData is not None: # Write the full curvature data for contourPath, curvature in curvatureData[frame]: XY = contourPath.vertices for row, value in enumerate(curvature): curvatureFile.write( "%.3f\t%.3f\t%.6f\t%d\n" % (XY[row, 0], XY[row, 1], value, frame)) # Write the selected region only for side, (contourPath, curvature, _, _, _) in curvatureDataSelected[frame]: XY = contourPath.vertices for row, value in enumerate(curvature): curvatureFileSelected.write( "%.3f\t%.3f\t%.6f\t%d\t%d\n" % (XY[row, 0], XY[row, 1], value, side, frame)) print("Saving data to %s done." % folderName) return def clusterData(self, eps, min_samples, frame=None, clusterSizeFiler=50, askUser=True): """ Run DBSCAN to identify the objects of interest and supress noise. The density based clustering algorithm DBSCAN is used to cluster the point localisations within each movie frame. The user is then asked to select the clusters that correspond to the object of interest (multiple selections are allowed) and the selection will be kept and used for future calculations. Each movie frame will be run on one CPU core thus making use of multi-core systems. The user can restrict the frames that should be computed to optimse the clustering parameters. Input: eps (float): The eps parameter of the sklearn DBSCAN implementation min_samples (int): The min_samples parameter of the sklearn DBSCAN implementation For more details on the implementation see: http://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html frame (int,None): If not None specifies the frame that should used clusterSizeFiler (int): Display filter for small clusters. CLusters below the specified size will not be displayed askUser (bool): Whether or not prompt the user to select the clusters """ self.cluster = Cluster() # initialise the cluster object self.cluster.setData(self.dataFrame) self.cluster.cluster(eps, min_samples, frame, clusterSizeFiler, askUser) # run DBSCAN self.runCluster = True # set the cluster flag so that subsequent calls now it was run def resetImage(self): """ Reset the contour finding routine. """ self.contour = None return def calculateKDE(self, kernel='gaussian', bandwidth=None): """ Calculate the Kernel Density Estimation. This will generate a high-resolution "image" of the localisations based on the kernel density estimate of the point localisations. If no bandwidth is specified an optimal bandwidth parameter is estimated using cross-validation. This is the default behaviour. Input: kernel (str): Kernel to be used for the kernel density estimation Possible values are 'gaussian' (default) and 'tophat' bandwidth (float,None): The bandwidth for the kernel density estimation If set to None cross-validation will be used to find the optimal parameter. """ if not self.runCluster: print('You need to run the clustering first!') return if self.contour is not None: print("It seems as if you already set up a pixel image.") print("Use resetImage() and try again") return self.contour = Contour() self.contour.setData(self.cluster.getResult(self.edgePoints)) self.contour.kernelDensityEstimate(kernel=kernel, bandwidth=bandwidth) def loadPixelImage(self, fname, pixelSize=1.0, start=None, end=None, padding=[20, 20]): """ Load a pixel image into the pipeline. Instead of generating a super-resolved image from point localisation data the pipeline can load any pixel image instead. The consecutive steps of contour fitting and curvature calculation can then be used on this input. Input: fname (str): Image file to load pixelSize (float): Set the pixel size in nm start (int): The first frame to load end (int): The last frame to include padding (list): Must be a list of two int specifying the width in pixels of the dark region that will be added to the images at the outside edges. This is done to allow the constricting contour fitting to fully close on objects even if they are extending out of the frame. """ if self.contour is not None: print("It seems as if you already set up a pixel image.") print("Use resetImage() and try again") return # Set the name of the object self.name = fname # Load the image file using tifffile.py tmpImage = Tiff.TiffFile(fname) self.images = [tmpImage[i].asarray() for i in range(len(tmpImage))] self.images = self.RGBtoGreyscale(self.images) # Select the frame range if start is None: start = 1 if end is None: end = len(self.images) self.images = self.images[start - 1:end] # Save the number of frames self.nrOfFrames = len(self.images) # Add some dark pixel paddings around the image. This makes contour # detection easier if the object is extending out of the image border. if padding: xpad, ypad = padding newImages = list() for image in self.images: # Create arrays containing zeros zerosX = np.zeros([np.shape(image)[0], xpad]) zerosY = np.zeros([ypad, np.shape(image)[1] + 2 * xpad]) # Add them to the original image newImage = np.concatenate([zerosX, image, zerosX], axis=1) newImage = np.concatenate([zerosY, newImage, zerosY], axis=0) # Add the padded image to the list newImages.append(newImage) # Replace the original images with the padded ones. self.images = newImages # Initialise the Contour class and set the images self.contour = Contour() self.contour.images = self.images self.contour.pixelSize = [float(pixelSize), 0.0, float(pixelSize), 0.0] print("Finished loading %d frames from %s" % (len(self.images), fname)) return def RGBtoGreyscale(self, images): """ Convert RGB images to greyscale The SIM images seem to be returned as RGB TIFF images containing three channels containing each the same information. The pipeline expects greyscale images. If images of the described are detected they are converted to simple greyscale images. Input: images (list): List containing np.arrays holding the image data """ assert (isinstance(images, list)) if len(np.shape(images[0])) == 4: # i.e. RGB # Assert that all color channels are actually the same assert (np.all(images[0][:, :, :, 0] == images[0][:, :, :, 1])) assert (np.all(images[0][:, :, :, 0] == images[0][:, :, :, 2])) images = [item[:, :, :, 0] for item in images] if len(images) == 1: images = [ images[0][frame, :, :] for frame in range(np.shape(images[0])[0]) ] return images def calculateContour(self, iterations=1500, smoothing=2, lambda1=1, \ lambda2=1, startPoints="min"): """ Find the contour of a super-resolved pixel image. The contour is fitted using a morphological contour fitting algorithm (https://github.com/pmneila/morphsnakes). The contour fitting is controlled using three parameters, i.e. smoothing, lamda1, and lambda2. Here the description given in the original source code smoothing : scalar The number of repetitions of the smoothing step (the curv operator) in each iteration. In other terms, this is the strength of the smoothing. This is the parameter µ. lambda1, lambda2 : scalars Relative importance of the inside pixels (lambda1) against the outside pixels (lambda2). Furthermore the parameter iterations is used to select the number of iterations the contour fitting should run. If it did not converge yet, further steps might be excecuted by calling contour.advanceContourMorph() Input: iterations (int): Number of steps the morphological contour fitting algorithm should advance. smoothing (scalar): See above lambda1 (scalar): See above lambda2 (scalar): See above startPoints (list or str) This determines the seed point for the contour fitting algorithm, i.e. the starting point. Can be either "max" or "min" and one correspdoning pixel is choses based of the condition. If individual frames require different starting points this can be specified using a list. Each element in the list will then be taken for the corresponding frame. E.g. ["max","max,"min"] would take the "max" for frame 1 and 2 and "min" for frame 3. """ if self.contour is None: print("The image is not yet set yet.") return self.contour.findContourMorph(iterations=iterations ,\ smoothing=smoothing ,\ lambda1=lambda1 ,\ lambda2=lambda2 ,\ startPoints=startPoints ) self.contour.selectContour() def calculateCurvature(self, smooth=True, window=2, smoothedContour=False, percentiles=[99, 1]): """ Calculate the curvature based on the expression for local curvature ( see https://en.wikipedia.org/wiki/Curvature#Local_expressions ) Input: smooth (bool): Smooth the curvature data using the gaussian weighted rolling window approach. window (float): Sigma of the gaussian (The three sigma range of the gaussian will be used for the averaging with each localisation weighted according to the value of the gaussian). smoothedContour (boolean): Use the smoothed contour for the calculation? Default is False. isclosed (boolean): REMOVED Each contour is checked if it closed, i.e. start and end point fall close in space and treated accordingly. For open contours the endings are ignored to avoid bias from the edges. Treat the contour as closed path. Default is True and should always be the case if padding was added to the image when loading image files or when the FOV was sufficiently large when loading point localisation data. Note that there might be unexpected if the contour is not closed. percentiles (list): Must be a list of two floats. Specifies the max and min values for displaying the curvature on a color scale. This can be important if unnatural kinks are observed which would dominate the curvature to an extent that the color scale would be skewed. By setting the percentiles one can set the range in a "smart" way. """ if self.contour is None: print('You need to run the contour selection first!') return self.curvature = Curvature() self.curvature.setData( self.contour.getResult(smoothed=smoothedContour)) self.curvature.calculateCurvature(smooth=smooth, window=window, percentiles=percentiles) def skeletonize(self, thres, binSize=10.0, sigma=5.0): """ Initialise the backbone finding routine. The "backbone" is approximated by using a skeletonization algorithm. It will thus find a backbone with with branches. To find the skeleton, the localisations are binned in a 2D histogram, blurred by a gaussian and the resulting image is binarized using the threshold value. From the binary images pixel at the edges are taken away until only the skeleton remains. """ if not self.runCluster: print('You need to run the clustering first!') return self.backbone = Skeleton() self.backbone.setData(self.cluster.getResult()) self.backbone.threshold(thres, binSize=binSize, sigma=sigma) def initShape(self): shape = Shape() shape.setData(self.contour.getResult(), self.backbone.getResult(), self.cluster.getResult()) shape.show() def makeMovie(self, nrFrames=2000, stepSize=500): """ Bin the localisations into frames. Sampling density can be controlled by selecting the number of frames that should be grouped. Imaging live objects implies that the object moves and changes during acquisiton time. By selecting a time gap (i.e. nrFrames) in which the object can be assumed to be static, a snapshot at this "time point" can be generated and a super-resolution image can be created. To increase the temporal "resolution" stepSize can be specified which is the gap between the first frames of consecutive movie frames. If the stepSize is smaller than nrFrames there will consequently an overlap of data between consecutive points. This will however, effectivly increase the frames/sec of the movie that will be produced and will increase the chance of resolving the event of interest. Here a brief schematic of the movie frame generation: -------------------------------------------- (frames) | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | | (movie frames without overlap) | | | | | | | | | | | (additional movie frames due to overlap) Input: nrFrames How long should one movie frame be, i.e. number of original TIFF frames stepSize Gap between to frames, if stepSize < nrFrames there will be overlap """ assert (self.dataFrame is not None) startTime = datetime.now() # set the calculation start time movie = LocalisationsToMovie(self.dataFrame) self.dataFrame = movie.create(nrFrames, stepSize) self.movieMade = True # Make a backup of the original data without ROI information self.originalDataFrame = deepcopy(self.dataFrame) # We're done, print some interesting messages time = datetime.now() - startTime print("Finished making the movie in:", str(time)[:-7]) print("Generated {:.0f} frames".format( self.dataFrame['movieFrame'].max())) def movieFrames(self): """ Iterate over the localisation data in the movie frames. """ assert (self.movieMade) for name, group in self.data.groupby('movieFrame'): yield name, group def getFrame(self, frame): """ Return the localisations in the given frame. """ return self.data.groupby('movieFrame').get_group(frame) def saveMovie(self, fname, plotContour=True, plotCurvature=True, lw=10, alpha=0.8): """ Create an .mp4 file showing the progression of the PointObject. Requires the ffmpeg binaries to work. It will create a movie file showing the frame-by-frame result as a movie. Input: fname (str): The filename of the movie plotContour (bool): Plot the contour plotCurvature (bool): Color code the contour line based on the local curvature. lw (int): Width of the contour line alpha (float): Transparency of the contour line """ if self.data is None or not self.movieMade: print('You need to load data and make a movie first') return if self.contour is None: print( 'You need to run the KDE estimate first and generate the "image"' ) return try: movieData = self.contour.kdfEstimate assert (movieData is not None) except: print( "It looks as if something went wrong with getting the KDE image." ) print("Did you run the kernel density estimation already?") return try: movieContour = self.contour.getResult() except: movieContour = None try: movieCurvature = self.curvature.getResult() except: movieCurvature = None if not plotCurvature: movieCurvature = None m = MovieGenerator(movieData, movieContour, movieCurvature, plotContour=plotContour, lw=lw, alpha=alpha) m.make(fname) def setFOV(self, frame=1, convert=True): """ Depreceated. Please use setROI() instead! Only kept for backwards compatibility """ warnings.warn("Depreceated. Please use setROI() instead!", DeprecationWarning) self.setROI(frame=frame, convert=convert) def setROI(self, frame=1, convert=True): """ Use one frame to set a ROI for further analysis. Note: Cannot be used with %pylab inline Input: frame (int): Frame number that will be used to select the ROI convert (bool): Do set the selected ROI as new data """ # Check if switched to qt mode if not mpl.get_backend() == 'Qt4Agg': print('Switch to the Qt backend first by executing "%pylab qt"') return False # Reset any prior ROI selection self.dataFrame = self.originalDataFrame # Select first frame frameData = self.dataFrame[self.dataFrame['movieFrame'] == frame] XY = np.asarray(frameData[['x', 'y']]) fig = plt.figure(figsize=self.singleFigure) ax = fig.add_subplot(111) ax.set_title("Frame %d" % frame) ax.set_xlabel("x position in nm", size=self.axesLabelSize) ax.set_ylabel("y position in nm", size=self.axesLabelSize) ax.set_xlim([np.min(XY[:, 0]), np.max(XY[:, 0])]) ax.set_ylim([np.min(XY[:, 1]), np.max(XY[:, 1])]) ax.scatter(x=XY[:, 0], y=XY[:, 1], edgecolor='none', facecolor='blue', s=2) rect = RoiSelector(ax) self.ROIedges = rect.edges # These will always be x1,y1,x2,y2 with x1,y2 bottom left, x2,y2 top right # The ROI was drawn, let the user look at it for a second and then go on sleep(1) plt.close(fig) # Select the ROI self._selectFOVdata() if convert: self.data = self._convertDataFrameToDict() def _selectFOVdata(self): if self.ROIedges is None: print('No ROI selected yet. Run setROI() first') return # Filter the data xbl, ybl, xtr, ytr = self.ROIedges self.dataFrame = self.dataFrame[self.dataFrame.x >= xbl] self.dataFrame = self.dataFrame[self.dataFrame.x <= xtr] self.dataFrame = self.dataFrame[self.dataFrame.y >= ybl] self.dataFrame = self.dataFrame[self.dataFrame.y <= ytr] def _convertDataFrameToDict(self): data = dict() if self.movieMade: for movieFrame in set(self.dataFrame.movieFrame): XY = np.asarray( self.dataFrame[self.dataFrame.movieFrame == movieFrame][[ 'x', 'y' ]]) data[movieFrame] = [movieFrame, XY, None] else: XY = np.asarray(self.dataFrame[['x', 'y']]) data[1] = [1, XY, None] return data
def test_rotation(self): cseg = Contour([1, 4, 9, 9, 2, 1]) self.assertEqual(cseg.rotation(), Contour([4, 9, 9, 2, 1, 1])) self.assertEqual(cseg.rotation(1), Contour([4, 9, 9, 2, 1, 1])) self.assertEqual(cseg.rotation(2), Contour([9, 9, 2, 1, 1, 4])) self.assertEqual(cseg.rotation(20), Contour([9, 9, 2, 1, 1, 4]))
def classFactory(iface): from contour import Contour return Contour(iface)
def test_retrogression(self): cseg = Contour([1, 4, 9, 9, 2, 1]) self.assertEqual(cseg.retrogression(), Contour([1, 2, 9, 9, 4, 1]))
class SubScene(QtWidgets.QGraphicsScene): def __init__(self, parent=None, dist = distance, eps=30, modes = [0,1,2]): super().__init__(parent) self.mode = modes[0] self.modes = modes self.QGitem=None self.line = None self.polys = [] self.dist_func = dist self.eps = eps self.polyFinished = False self.selectedContour = None self.selectedVertex=None self.overrideCursor(QtCore.Qt.ArrowCursor) def setDrawing(self): self.mode = self.modes[1] def setEdit(self): self.mode = self.modes[2] def setMovement(self): self.mode = self.modes[0] def updatePolyPoint(self, poly, pos): poly.setPos(pos) poly.addPoint(pos) def clearContours(self): if self.selectedContour: self.selectedContour.highlightClear() self.selectedContour = None self.forceClearContours() self.update() def forceClearContours(self): for contour in self.items()[:-1]: contour.highlightClear() self.update() def returnPoints(self): if self.QGitem is not None: pts = self.QGitem.points elif len(self.polys) > 0: pts = self.polys[0].points else: return None return [[p.x(), p.y()] for p in pts] def addAIPolygon(self, points): qPoints = [QtCore.QPoint(x,y) for x,y in points]# if len(self.polys) ==0: if self.QGitem is None: self.QGitem = Contour(point_size=1.5) self.addItem(self.QGitem) self.updatePolyPoint(self.QGitem, qPoints[0]) self.QGitem.setZValue(len(self.polys) + 1) self.QGitem.prepareGeometryChange() self.QGitem.points = qPoints self.QGitem.addPoint((qPoints[0])) else: self.QGitem = self.polys[0] self.QGitem.prepareGeometryChange() self.QGitem.points = qPoints self.QGitem.addPoint((qPoints[0])) self.finalisePolygon() self.update() def mouseReleaseEvent(self, event): if self.mode == self.modes[0]: self.overrideCursor(QtCore.Qt.ArrowCursor) self.update() def isClose(self, p1, p2): return self.dist_func(p1-p2) <self.eps def finalisePolygon(self, premature=False): if self.QGitem: # if premature: something to do but will add later if self.line: self.removeItem(self.line) self.line.popPoint() self.QGitem.editable=False self.polys.append(self.QGitem) self.QGitem = None self.mode = self.modes[0] self.update() def selectContour(self, contour): contour.selected=True self.selectedContour = contour self.update() def selectShapeByPoint(self, pos): if self.vertexSelected(): self.selectedContour.highlightVertex(self.selectedVertex) return itemundermouse = self.itemAt(pos, QtGui.QTransform()) if itemundermouse in self.items()[:-1]: self.selectContour(itemundermouse) return def moveVertex(self, pos): self.selectedContour.prepareGeometryChange() self.selectedContour.moveBy(self.selectedVertex, pos - self.selectedContour[self.selectedVertex]) def vertexSelected(self): return self.selectedVertex is not None def ptDist(self, pt1, pt2): # A line between both line = QtCore.QLineF(pt1, pt2) # Length lineLength = line.length() return lineLength def getClosestPoint(self, pt): closest = (-1, -1) distTh = 4.0 dist = 1e9 # should be enough item_under_mouse = self.itemAt(pt, QtGui.QTransform()) for i in range(self.selectedContour.size()): pt1 = self.selectedContour.points[i] j = i+1 if j == self.selectedContour.size(): j=0 pt2 = self.selectedContour.points[j] edge = QtCore.QLineF(pt1, pt2) normal = edge.normalVector() normalTrhoughPos = QtCore.QLineF(pt.x(), pt.y(), pt.x()+(normal.dx()*10), pt.y()+(normal.dy()*10)) normalTrhoughPos2 = QtCore.QLineF(pt.x(), pt.y(), pt.x() - (normal.dx() * 10), pt.y() - (normal.dy() * 10)) for norm in [normalTrhoughPos, normalTrhoughPos2]: # if item_under_mouse in self.items()[:-1]: # normalTrhoughPos = QtCore.QLineF(pt.x(), pt.y(), pt.x()-(normal.dx()*10), pt.y()-(normal.dy()*10)) intersectionPt = QtCore.QPointF() intersectionType = edge.intersect( norm, intersectionPt) currDist = self.ptDist(intersectionPt, pt) if intersectionType ==QtCore.QLineF.BoundedIntersection: currDist = self.ptDist(intersectionPt, pt) if currDist < dist: closest = (i,j) dist = currDist return closest def reset(self): self.clearContours() self.forceClearContours() if self.line: self.removeItem(self.line) self.line=None if self.QGitem: self.removeItem(self.QGitem) self.QGitem = None for polys in self.polys: self.removeItem(polys) self.polys = [] self.mode = self.modes[0] self.update() def mousePressEvent(self, event): pos = event.scenePos() if event.button() == QtCore.Qt.LeftButton and self.mode == self.modes[1]: self.overrideCursor(QtCore.Qt.CrossCursor) if self.line is None or self.polyFinished: self.line = Contour(point_size=1.5) self.addItem(self.line) self.updatePolyPoint(self.line, pos) elif self.line and not self.polyFinished: self.line.prepareGeometryChange() self.line.points[0] = pos self.line.setPos(pos) if self.QGitem: self.QGitem.prepareGeometryChange() if len(self.QGitem.points) >1 and self.isClose(pos, self.QGitem.points[0]): self.overrideCursor(QtCore.Qt.PointingHandCursor) pos = self.QGitem.points[0] self.QGitem.highlightVertex(0) #need to add to close the polygone self.QGitem.addPoint(pos) if self.QGitem.points[0] == pos: self.finalisePolygon() else: self.QGitem = Contour(point_size=1.5) self.addItem(self.QGitem) self.updatePolyPoint(self.QGitem, pos) self.QGitem.setZValue(len(self.polys)+1) event.accept() self.update() if event.button() == QtCore.Qt.RightButton and self.mode == self.modes[1]: self.overrideCursor(QtCore.Qt.CrossCursor) if self.line: if len(self.line.points) > 1 and self.QGitem: self.QGitem.prepareGeometryChange() self.QGitem.remove(-1) if self.QGitem.points==1: self.removeItem(self.QGitem) self.removeItem(self.line) self.line=None return self.line.prepareGeometryChange() self.line.points[0] =self.QGitem.points[-1] event.accept() self.update() if self.mode == self.modes[2] and event.button() == QtCore.Qt.LeftButton: self.overrideCursor(QtCore.Qt.ClosedHandCursor) self.selectShapeByPoint(pos) event.accept() self.update() if self.mode == self.modes[2] and event.button() == QtCore.Qt.MiddleButton: self.overrideCursor(QtCore.Qt.CrossCursor) if len(self.polys) > 0: self.selectedContour = self.polys[0] pts = self.getClosestPoint(pos) self.selectedContour.points.insert(pts[1], pos) if self.vertexSelected() and event.button() == QtCore.Qt.RightButton and self.mode == self.modes[2]: self.overrideCursor(QtCore.Qt.PointingHandCursor) self.selectedContour.prepareGeometryChange() self.selectedContour.remove(self.selectedVertex) if len(self.selectedContour.points) ==1: self.removeItem(self.selectedContour) self.update() def overrideCursor(self, cursor): QtWidgets.QApplication.setOverrideCursor(cursor) def mouseMoveEvent(self, event): pos = event.scenePos() if self.mode == self.modes[1]: self.overrideCursor(QtCore.Qt.CrossCursor) if self.QGitem: if len(self.QGitem.points)==1: #intilaise line to the pooint self.line.points = [self.QGitem.points[0],self.QGitem.points[0] ] colorLine = QtGui.QColor(3,252,66) if len(self.QGitem.points) >1 and self.isClose(pos, self.QGitem.points[0]): self.overrideCursor(QtCore.Qt.PointingHandCursor) colorLine = self.QGitem.line_color pos = self.QGitem[0] self.QGitem.highlightVertex(0) if len(self.line.points)==2: self.line.points[1] = pos else: self.line.addPoint = pos self.line.line_color = colorLine return if self.mode == self.modes[2] and QtCore.Qt.LeftButton & event.buttons(): if self.vertexSelected(): self.overrideCursor(QtCore.Qt.ClosedHandCursor) self.selectedContour.prepareGeometryChange() self.moveVertex(pos) self.update() return elif self.mode == self.modes[2]: self.overrideCursor(QtCore.Qt.OpenHandCursor) id_point = [[i for i, y in enumerate(poly.points) if distance(pos - y) <= self.eps] for poly in self.polys] id_shape = [i for i, y in enumerate(id_point) if y != []] item_under_mouse = self.itemAt(pos, QtGui.QTransform()) self.clearContours() if id_shape!=[]: self.selectedVertex = id_point[id_shape[0]][0] self.selectContour(self.items()[:-1][::-1][id_shape[0]]) self.selectedContour.highlightVertex(self.selectedVertex) elif item_under_mouse in self.items()[:-1]: self.selectedVertex=None self.selectContour(item_under_mouse) self.selectedContour.hIndex=None else: self.selectedVertex = None self.update()
def test_inversion(self): cseg = Contour([1, 4, 9, 9, 2, 1]) self.assertEqual(cseg.inversion(), Contour([8, 5, 0, 0, 7, 8]))
def addScene(self, scene): logging.debug("In MultiSliceContour::addScene()") contour = Contour(scene) self._replyList.append(contour) for rContour in self._replyList: rContour.replyList.append(contour) replyList = self._replyList[:] replyList.append(self) contour.replyList = replyList points = [] i = 0 while i < self._representation.GetNumberOfNodes(): addPosition = [0,0,0] self._representation.GetNthNodeWorldPosition(i, addPosition) if self.pointMap.has_key((addPosition[0], addPosition[1], addPosition[2])): addPosition = self._pointMap[(addPosition[0], addPosition[1], addPosition[2])] else: addPosition = self._scene.toOriginalView(addPosition) points.append(addPosition) i = i + 1 contour.loadPoints(points) contour.lineColor = self.lineColor contour.visible = self.visible if self.locked: contour.lock() else: contour.unlock() contour.radius = self.getRadius()
def test_translation(self): cseg = Contour([1, 4, 9, 9, 2, 1]) self.assertEqual(cseg.translation(), Contour([0, 2, 3, 3, 1, 0]))
#Configuring the camera to look the way we want config_microsoft_cam() #init_UDP_client() #init_network_tables() M_HFOV = find_fov(M_HA, M_VA, M_DFOV) #print(M_HFOV) pipeline = GripPipeline() vision_math = Math() #Video Capture stuff cam = cv2.VideoCapture(0) #Set Camera resoultion cam.set(3, HRES) cam.set(4, VRES) cnt1 = Contour() cnt2 = Contour() count = 0 t_end = time.time() + 10 while time.time() <= t_end: count = count + 1 captureStartTime = cv2.getTickCount() s, im = cam.read() # captures image captureEndTime = cv2.getTickCount() captureTime = (captureEndTime - captureStartTime) / cv2.getTickFrequency() cv2.imshow("Test Picture", im) # displays captured image processStartTime = cv2.getTickCount() pipeline.process(im) processEndTime = cv2.getTickCount() processTime = (processEndTime - processStartTime) / cv2.getTickFrequency() find_target(cnt1, cnt2)
def test_prime_form_marvin_laprade(self): cseg1 = Contour([1, 4, 9, 2]) cseg2 = Contour([5, 7, 9, 1]) cseg3 = Contour([5, 7, 9, 1]) cseg4 = Contour([0, 2, 1, 3, 4]) cseg5 = Contour([0, 1, 2, 3, 2]) cseg6 = Contour([1, 2, 3, 0, 3, 1]) cseg7 = Contour([0, 1, 2, 1, 2]) self.assertEqual(cseg1.prime_form_marvin_laprade(), Contour([0, 2, 3, 1])) self.assertEqual(cseg2.prime_form_marvin_laprade(), Contour([0, 3, 2, 1])) self.assertEqual(cseg3.prime_form_marvin_laprade(), Contour([0, 3, 2, 1])) self.assertEqual(cseg4.prime_form_marvin_laprade(), Contour([0, 2, 1, 3, 4])) self.assertEqual(cseg5.prime_form_marvin_laprade(), [Contour([0, 1, 2, 4, 3]), Contour([0, 1, 3, 4, 2])]) ## FIXME: wrong test # self.assertEqual(cseg6.prime_form_marvin_laprade(), [Contour([1, 3, 4, 0, 5, 2]), Contour([1, 4, 0, 5, 3, 2])]) self.assertEqual(cseg7.prime_form_marvin_laprade(), [Contour([0, 1, 3, 2, 4]), Contour([0, 2, 4, 1, 3])])
pymclevel_log.setLevel(logging.CRITICAL) print print "Finished shifting, shifted: %d chunks" % shifted # Attempt to merge new chunks with old chunks elif mode == Modes.merge: contour_data_file = os.path.join(cli.world_dir, cli.contour_file_name) if 'gauss' in (ChunkShaper.filt_name_river, ChunkShaper.filt_name_even): if not hasattr(filter, 'scipy'): print "You must install SciPy to use the '%s' filter" % 'gauss' sys.exit(1) print "Getting saved world contour..." contour = Contour() try: contour.read(contour_data_file) except (EnvironmentError, ContourLoadError), e: if e.errno == errno.ENOENT: if os.path.exists(cli.world_dir): error("no contour data to merge with (use trace mode to generate)") else: error('could not read world data: File not found: %s' % cli.world_dir) else: error('could not read contour data: %s' % e) def save_contour(): try: if contour.empty: os.remove(contour_data_file)
def computeSimpleFlow(self, i): print("computeSimpleFlow", i, " ", int(100 * i / len(self.frames)), "%") frame = self.frames[i] #plt.imshow(frame[:, :, ::-1]) #plt.show() """ FD = np.zeros(self.shape) for px in range(self.shape[0]): for py in range(self.shape[1]): FD[px, py] = self.mask.getDensity(frame[px, py]) plt.figure(figsize = (10, 5)) plt.subplot(121) plt.imshow(FD, cmap = "gray") plt.subplot(122) plt.imshow(FD > 0, cmap = "gray") plt.show() """ """ while(nchanges > 0 and nite < 10): nadded, nremoved = 0, 0 newpoints = self.currentcontour.get("points").copy() normals = self.currentcontour.get("normals").copy() for i in range(len(newpoints)): dc = self.mask.getDensity(frame[newpoints[i][0], newpoints[i][1]]) - self.mask.lambd if(dc < 0): newpoints[i] = self.currentcontour.getPixelToNormal(newpoints[i], - normals[i]).copy() nremoved += 1 else: p_n = self.currentcontour.getPixelToNormal(newpoints[i], normals[i]).copy() dc_p_n = self.mask.getDensity(frame[p_n[0], p_n[1]]) - self.mask.lambd if(dc_p_n > 0): newpoints[i] = p_n.copy() nadded += 1 self.currentcontour = Contour(newpoints, self.shape) nite += 1 nchanges = nadded + nremoved print(nite, nadded, nremoved, len(self.currentcontour.get("points"))) #if(PARAMS["verbose"]):self.currentcontour.render() #if(PARAMS["verbose"]):self.currentcontour.render() """ def getPiDC(pi, ni, nax): DC = np.zeros(2 * nax + 1) Pi = np.zeros((2 * nax + 1, 2)) DC[nax] = np.sign( self.mask.getDensity(frame[pi[0], pi[1]]) - self.mask.lambd) Pi[nax] += pi for j in range(1, nax + 1): temppi = self.currentcontour.getPixelToNormal( Pi[nax + j - 1], ni).copy().astype(int) Pi[nax + j] = temppi.copy() tempdc = self.mask.getDensity( frame[temppi[0] % self.shape[0], temppi[1] % self.shape[1]]) - self.mask.lambd DC[nax + j] += np.sign(tempdc) temppi = self.currentcontour.getPixelToNormal( Pi[nax - j + 1], -ni).copy().astype(int) Pi[nax - j] = temppi.copy() tempdc = self.mask.getDensity( frame[temppi[0] % self.shape[0], temppi[1] % self.shape[1]]) - self.mask.lambd DC[nax - j] += np.sign(tempdc) return Pi, DC points = self.currentcontour.get("points").copy() normals = self.currentcontour.get("normals").copy() print(len(points)) findeps = [] #findepm1 = 0 changepoints = [] #for i in range(len(newpoints)): nbloc = 10 nax = 10 nnewpoints = max(10, int(0.05 * len(points))) for i in np.linspace(0, len(points), nnewpoints + 1).astype(int)[:-1]: findepii = [] for ii in range(-nbloc, nbloc + 1): pi = points[(i + ii) % len(points)].copy() ni = normals[(i + ii) % len(normals)].copy() Pi, DC = getPiDC(pi, ni, nax) if (ii == 0): Pi0 = Pi.copy() dep = [] for j in range(nax): if (DC[j] < 0 and DC[j + 1] > 0): dep += [j + 1] for j in range(1, nax + 1): if (DC[nax + j] < 0 and DC[nax + j - 1] > 0): dep += [nax + j - 1] if (np.sum(DC) == len(DC)): dep += [len(DC) - 1] if (np.sum(DC) == -len(DC)): dep += [0] if (len(dep) == 0): dep += [nax] dep = np.array(dep) if (np.sum(dep < nax) > np.sum(dep > nax)): dep = dep[dep < nax] elif (np.sum(dep < nax) < np.sum(dep > nax)): dep = dep[dep > nax] else: dep = [nax] findepii += [np.median(dep)] findep = int(np.median(findepii)) """ if(i != 0): if(findep > findepm1 + 5): findep = findepm1 + 5 elif(findep < findepm1 - 5): findep = findepm1 - 5 findepm1 = findep """ findeps += [findep] #newpoints[i] = Pi[findep].copy() changepoints += [Pi0[findep].copy()] """ dc = self.mask.getDensity(frame[pi[0], pi[1]]) - self.mask.lambd nite = 0 if(dc < 0): while(dc < 0 and nite < 50): pi = self.currentcontour.getPixelToNormal(pi, - ni).copy() dc = self.mask.getDensity(frame[pi[0] % self.shape[0], pi[1] % self.shape[1]]) - self.mask.lambd nite += 1 else: while(dc > 0 and nite < 50): pi = self.currentcontour.getPixelToNormal(pi, ni).copy() dc = self.mask.getDensity(frame[pi[0], pi[1]]) - self.mask.lambd nite += 1 if(nite < 50):newpoints[i] = pi.copy() """ #plt.plot(np.arange(len(findeps)), np.array(findeps) - 25) #plt.show() self.currentcontour = Contour(changepoints, self.shape) if (PARAMS["verbose"]): self.currentcontour.render() return self.currentcontour.interior.copy()
def test_reduction_morris(self): cseg1 = Contour([0, 4, 3, 2, 5, 5, 1]) cseg2 = Contour([7, 10, 9, 0, 2, 3, 1, 8, 6, 2, 4, 5]) self.assertEqual(cseg1.reduction_morris(), [Contour([0, 2, 1]), 2]) self.assertEqual(cseg2.reduction_morris(), [Contour([2, 3, 0, 1]), 3])
def test_interval_array(self): cseg = Contour([0, 1, 3, 2]) self.assertEqual(cseg.interval_array(), ([2, 2, 1], [1, 0, 0]))