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 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 __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 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 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 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 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 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 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
% (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
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)
#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)
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 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 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)
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 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 classFactory(iface): from contour import Contour return Contour(iface)