def __init__( self, BW ): #Constructor. BW es una imagen binaria en forma de una matriz numpy self.BW = BW cs = cv.FindContours(cv.fromarray(self.BW.astype(np.uint8)), cv.CreateMemStorage(), mode=cv.CV_RETR_EXTERNAL) #Finds the contours counter = 0 """ Estas son listas dinamicas usadas para almacenar variables """ centroid = list() cHull = list() contours = list() cHullArea = list() contourArea = list() while cs: #Iterar a traves de CvSeq, cs. if abs( cv.ContourArea(cs) ) > 2000: #Filtra contornos de menos de 2000 pixeles en el area contourArea.append( cv.ContourArea(cs) ) #Se agrega contourArea con el area de contorno mas reciente m = cv.Moments( cs) #Encuentra todos los momentos del contorno filtrado try: m10 = int(cv.GetSpatialMoment(m, 1, 0)) #Momento espacial m10 m00 = int(cv.GetSpatialMoment(m, 0, 0)) #Momento espacial m00 m01 = int(cv.GetSpatialMoment(m, 0, 1)) #Momento espacial m01 centroid.append( (int(m10 / m00), int(m01 / m00)) ) #Aniade la lista de centroides con las coordenadas mas nuevas del centro de gravedad del contorno convexHull = cv.ConvexHull2( cs, cv.CreateMemStorage(), return_points=True ) #Encuentra el casco convexo de cs en el tipo CvSeq cHullArea.append( cv.ContourArea(convexHull) ) #Agrega el area del casco convexo a la lista cHullArea cHull.append( list(convexHull) ) #Agrega la lista del casco convexo a la lista de cHull contours.append( list(cs) ) #Agrega la forma de lista del contorno a la lista de contornos counter += 1 #Agrega al contador para ver cuantos blobs hay except: pass cs = cs.h_next() #Pasa al siguiente contorno en cs CvSeq """ A continuacion, las variables se convierten en campos para hacer referencias posteriores """ self.centroid = centroid self.counter = counter self.cHull = cHull self.contours = contours self.cHullArea = cHullArea self.contourArea = contourArea
def find_biggest_region(self): """ this code should find the biggest region and then determine some of its characteristics, which will help direct the drone """ # copy the thresholded image cv.Copy( self.threshed_image, self.copy ) # copy self.threshed_image # this is OpenCV's call to find all of the contours: contours = cv.FindContours(self.copy, self.storage, cv.CV_RETR_EXTERNAL, cv.CV_CHAIN_APPROX_SIMPLE) # Next we want to find the *largest* contour if len(contours)>0: biggest = contours biggestArea=cv.ContourArea(contours) while contours != None: nextArea=cv.ContourArea(contours) if biggestArea < nextArea: biggest = contours biggestArea = nextArea contours=contours.h_next() #Use OpenCV to get a bounding rectangle for the largest contour self.br = cv.BoundingRect(biggest,update=0) #Publish the data. self.publishBoxData()
def __init__( self, BW ): #Constructor. BW is a binary image in the form of a numpy array self.BW = BW cs = cv.FindContours(cv.fromarray(self.BW.astype(np.uint8)), cv.CreateMemStorage(), mode=cv.CV_RETR_EXTERNAL) #Finds the contours counter = 0 """ These are dynamic lists used to store variables """ centroid = list() cHull = list() contours = list() cHullArea = list() contourArea = list() while cs: #Iterate through the CvSeq, cs. if abs( cv.ContourArea(cs) ) > 2000: #Filters out contours smaller than 2000 pixels in area contourArea.append(cv.ContourArea( cs)) #Appends contourArea with newest contour area m = cv.Moments( cs) #Finds all of the moments of the filtered contour try: m10 = int(cv.GetSpatialMoment(m, 1, 0)) #Spatial moment m10 m00 = int(cv.GetSpatialMoment(m, 0, 0)) #Spatial moment m00 m01 = int(cv.GetSpatialMoment(m, 0, 1)) #Spatial moment m01 centroid.append( (int(m10 / m00), int(m01 / m00)) ) #Appends centroid list with newest coordinates of centroid of contour convexHull = cv.ConvexHull2( cs, cv.CreateMemStorage(), return_points=True ) #Finds the convex hull of cs in type CvSeq cHullArea.append( cv.ContourArea(convexHull) ) #Adds the area of the convex hull to cHullArea list cHull.append( list(convexHull) ) #Adds the list form of the convex hull to cHull list contours.append( list(cs) ) #Adds the list form of the contour to contours list counter += 1 #Adds to the counter to see how many blobs are there except: pass cs = cs.h_next() #Goes to next contour in cs CvSeq """ Below the variables are made into fields for referencing later """ self.centroid = centroid self.counter = counter self.cHull = cHull self.contours = contours self.cHullArea = cHullArea self.contourArea = contourArea
def largestContour(contourCluster): # print len(contourCluster) if len(contourCluster) != 0: largest_contour = contourCluster while True: contourCluster = contourCluster.h_next() if (not contourCluster): return largest_contour if (cv.ContourArea(contourCluster) > cv.ContourArea(largest_contour)): largest_contour = contourCluster
def largestContour(self,contourCluster): if len(contourCluster) != 0: largest_contour = contourCluster while True: contourCluster = contourCluster.h_next() if (not contourCluster): # print type(largest_contour) return largest_contour # break if (cv.ContourArea(contourCluster) > cv.ContourArea(largest_contour)): largest_contour = contourCluster
def find_biggest_region(): """ finds all the contours in threshed image, finds the largest of those, and then marks in in the main image """ # get D so that we can change values in it global D cv.Copy(D.threshed_image, D.copy) # copy threshed image # this is OpenCV's call to find all of the contours: contours = cv.FindContours(D.copy, D.storage, cv.CV_RETR_EXTERNAL, \ cv.CV_CHAIN_APPROX_SIMPLE) # Next we want to find the *largest* contour if len(contours) > 0: biggest = contours biggestArea = cv.ContourArea(contours) while contours != None: nextArea = cv.ContourArea(contours) if biggestArea < nextArea: biggest = contours biggestArea = nextArea contours = contours.h_next() # Use OpenCV to get a bounding rectangle for the largest contour br = cv.BoundingRect(biggest, update=0) #print "in find_regions, br is", br # Example of drawing a red box # Variables: ulx ~ upper left x, lry ~ lower right y, etc. ulx = br[0] lrx = br[0] + br[2] uly = br[1] lry = br[1] + br[3] cv.PolyLine(D.image, [[(ulx, uly), (lrx, uly), (lrx, lry), (ulx, lry)]], 1, cv.RGB(255, 0, 0)) # Example of drawing a yellow circle # Variables: cenx, ceny cenx = (ulx + lrx) / 2 ceny = (uly + lry) / 2 cv.Circle(D.image, (cenx, ceny), 8, cv.RGB(255, 255, 0), thickness=1, lineType=8, shift=0)
def motion_detector(): global max_area, avg, prev_pos, largest_contour contour = cv.FindContours( temp_image, store, mode=cv.CV_RETR_EXTERNAL, method=cv.CV_CHAIN_APPROX_NONE) #Findling contours cv.Copy(img, render_image) #Copying for painting on the image if len(contour) != 0: temp_contour = contour area = 0 max_area_test = max_area while temp_contour != None: #Routine to find the largest contour area = cv.ContourArea(temp_contour) if area > max_area_test: largest_contour = temp_contour max_area_test = area temp_contour = temp_contour.h_next() rect = cv.BoundingRect(largest_contour) cv.DrawContours(render_image, largest_contour, (0, 255, 0), (0, 0, 255), 1, 3) cv.Rectangle(render_image, (rect[0], rect[1]), (rect[0] + rect[2], rect[1] + rect[3]), (255, 0, 0)) avg = rect[0] + rect[2] / 2 else: avg = img.width / 2
def getStandardizedRects(self): ''' @return: the boxes centered on the target center of mass +- n_sigma*std @note: You must call detect() before getStandardizedRects() to see updated results. ''' #create a list of the top-level contours found in the contours (cv.Seq) structure rects = [] if len(self._contours) < 1: return (rects) seq = self._contours while not (seq == None): (x, y, w, h) = cv.BoundingRect(seq) if (cv.ContourArea(seq) > self._minArea): # and self._filter(rect) r = pv.Rect(x, y, w, h) moments = cv.Moments(seq) m_0_0 = cv.GetSpatialMoment(moments, 0, 0) m_0_1 = cv.GetSpatialMoment(moments, 0, 1) m_1_0 = cv.GetSpatialMoment(moments, 1, 0) mu_2_0 = cv.GetCentralMoment(moments, 2, 0) mu_0_2 = cv.GetCentralMoment(moments, 0, 2) cx = m_1_0 / m_0_0 cy = m_0_1 / m_0_0 w = 2.0 * self._rect_sigma * np.sqrt(mu_2_0 / m_0_0) h = 2.0 * self._rect_sigma * np.sqrt(mu_0_2 / m_0_0) r = pv.CenteredRect(cx, cy, w, h) rects.append(r) seq = seq.h_next() if self._filter != None: rects = self._filter(rects) return rects
def getWatershedMask(self): ''' Uses the watershed algorithm to refine the foreground mask. Currently, this doesn't work well on real video...maybe grabcut would be better. ''' cvMarkerImg = cv.CreateImage(self._fgMask.size, cv.IPL_DEPTH_32S, 1) cv.SetZero(cvMarkerImg) #fill each contour with a different gray level to label connected components seq = self._contours c = 50 while not (seq == None) and len(seq) != 0: if cv.ContourArea(seq) > self._minArea: c += 10 moments = cv.Moments(seq) m00 = cv.GetSpatialMoment(moments, 0, 0) m01 = cv.GetSpatialMoment(moments, 0, 1) m10 = cv.GetSpatialMoment(moments, 1, 0) centroid = (int(m10 / m00), int(m01 / m00)) cv.Circle(cvMarkerImg, centroid, 3, cv.RGB(c, c, c), cv.CV_FILLED) seq = seq.h_next() if (c > 0): img = self._annotateImg.asOpenCV() cv.Watershed(img, cvMarkerImg) tmp = cv.CreateImage(cv.GetSize(cvMarkerImg), cv.IPL_DEPTH_8U, 1) cv.CvtScale(cvMarkerImg, tmp) return pv.Image(tmp)
def is_square(contour): """ Squareness checker Square contours should: -have 4 vertices after approximation, -have relatively large area (to filter out noisy contours) -be convex. -have angles between sides close to 90deg (cos(ang) ~0 ) Note: absolute value of an area is used because area may be positive or negative - in accordance with the contour orientation """ area = math.fabs( cv.ContourArea(contour) ) isconvex = cv.CheckContourConvexity(contour) s = 0 if len(contour) == 4 and area > 1000: for i in range(1, 4): # find minimum angle between joint edges (maximum of cosine) pt1 = contour[i] pt2 = contour[i-1] pt0 = contour[i-2] t = math.fabs(angle(pt0, pt1, pt2)) if s <= t:s = t # if cosines of all angles are small (all angles are ~90 degree) # then its a square if s < 0.3:return True return False
def validate_contour(c): #x_min = min(pt[0] for pt in c) #x_max = max(pt[0] for pt in c) #y_min = min(pt[1] for pt in c) #y_max = max(pt[1] for pt in c) #dx = x_max - x_min #dy = y_max - y_min #d = dy!=0 and dx/dy or 0 #return dx != 0 and dy != 0 and d>0.25 and d<4.0 return cv.ContourArea(c) > 6
def __init__( self, BW ): #Constructor. BW is a binary image in the form of a numpy array self.BW = BW cs = cv.FindContours(cv.fromarray(self.BW.astype(np.uint8)), cv.CreateMemStorage(), mode=cv.CV_RETR_EXTERNAL) #Finds the contours counter = 0 centroid = list() cHull = list() contours = list() cHullArea = list() contourArea = list() while cs: #Iterate through the CvSeq, cs. if abs(cv.ContourArea(cs)) > 2000: contourArea.append(cv.ContourArea(cs)) m = cv.Moments(cs) try: m10 = int(cv.GetSpatialMoment(m, 1, 0)) #Spatial moment m10 m00 = int(cv.GetSpatialMoment(m, 0, 0)) #Spatial moment m00 m01 = int(cv.GetSpatialMoment(m, 0, 1)) #Spatial moment m01 centroid.append((int(m10 / m00), int(m01 / m00))) convexHull = cv.ConvexHull2(cs, cv.CreateMemStorage(), return_points=True) cHullArea.append(cv.ContourArea(convexHull)) cHull.append(list(convexHull)) contours.append(list(cs)) counter += 1 except: pass cs = cs.h_next() self.centroid = centroid self.counter = counter self.cHull = cHull self.contours = contours self.cHullArea = cHullArea self.contourArea = contourArea
def contourCenter(thisContour, smoothness=4): positions_x, positions_y = [0] * smoothness, [0] * smoothness if cv.ContourArea(thisContour) > 2.0: moments = cv.Moments(thisContour, 1) positions_x.append(cv.GetSpatialMoment(moments, 1, 0) / cv.GetSpatialMoment(moments, 0, 0)) positions_y.append(cv.GetSpatialMoment(moments, 0, 1) / cv.GetSpatialMoment(moments, 0, 0)) positions_x, positions_y = positions_x[-smoothness:], positions_y[-smoothness:] pos_x = (sum(positions_x) / len(positions_x)) pos_y = (sum(positions_y) / len(positions_y)) return (int(pos_x * smoothness), int(pos_y * smoothness))
def contours_area_sort(seq, nr_returned=None): if not seq: None largest = {} while seq: largest[cv.ContourArea(seq)] = seq seq = seq.h_next() sorted_keys = largest.keys() sorted_keys.sort() nr_returned = nr_returned or len(sorted_keys) sorted_keys = sorted_keys[-nr_returned:] return [largest[key] for key in sorted_keys]
def top_two_max_contours(contours): max_contours = [(0, None), (0, None)] try: while True: area = cv.ContourArea(contours) if area > max_contours[0][0]: max_contours[0] = (area, contours) max_contours.sort(cmp_contours) contours = contours.h_next() except (TypeError, cv.error), e: return max_contours
def getSlicedCenter(self,src_region,image): centers = [] # src_region = cv.iplimage(src_region) contourx = cv.FindContours(src_region, cv.CreateMemStorage(), cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE) # print len(contourx) if cv.ContourArea(contourx)> 2: for i in range(len(contourx)): if contourx: centers.append(self.contourCenter(contourx, 4)) contourx = contourx.h_next() for i in range(len(centers)): self.drawPointOnImage(image, centers[i]) print centers return image
def max_area(contours): ''' returns the contour with maximal area. @return: (max_area, max_contour) ''' max_area = 0 max_contours = contours try: while True: area = cv.ContourArea(contours) if area > max_area: max_area = area max_contours = contours contours = contours.h_next() except (TypeError, cv.error), e: return max_area, max_contours
def find_largest_contour(seq, exclude=None): max_area = 0 largest = None try: while seq: if seq != exclude: area = cv.ContourArea(seq) if max_area < area: max_area = area largest = seq seq = seq.h_next() return largest except: Debug.print_stacktrace() return None
def detecta(imagem): cv.Smooth(imagem, imagem, cv.CV_GAUSSIAN, 3) maiorArea = 0 listaContornos = [] listaVertices = [] cv.AbsDiff(imagem, fundo, mascara) cv.CvtColor(mascara, cinza, cv.CV_BGR2GRAY) cv.Threshold(cinza, cinza, 50, 255, cv.CV_THRESH_BINARY) cv.Dilate(cinza, cinza, None, 18) cv.Erode(cinza, cinza, None, 18) armazenamento = cv.CreateMemStorage(0) contorno = cv.FindContours(cinza, armazenamento, cv.CV_RETR_LIST, cv.CV_LINK_RUNS) while contorno: vertices_do_retangulo = cv.BoundingRect(list(contorno)) listaVertices.append(vertices_do_retangulo) listaContornos.append(cv.ContourArea(contorno)) maiorArea = max(listaContornos) maiorArea_index = listaContornos.index(maiorArea) retangulo_de_interesse = listaVertices[maiorArea_index] contorno = contorno.h_next() ponto1 = (retangulo_de_interesse[0], retangulo_de_interesse[1]) ponto2 = (retangulo_de_interesse[0] + retangulo_de_interesse[2], retangulo_de_interesse[1] + retangulo_de_interesse[3]) cv.Rectangle(imagem, ponto1, ponto2, cv.CV_RGB(0, 0, 0), 2) cv.Rectangle(cinza, ponto1, ponto2, cv.CV_RGB(255, 255, 255), 1) largura = ponto2[0] - ponto1[0] altura = ponto2[1] - ponto1[1] cv.Line(cinza, (ponto1[0] + largura / 2, ponto1[1]), (ponto1[0] + largura / 2, ponto2[1]), cv.CV_RGB(255, 255, 255), 1) cv.Line(cinza, (ponto1[0], ponto1[1] + altura / 2), (ponto2[0], ponto1[1] + altura / 2), cv.CV_RGB(255, 255, 255), 1) global x x = ((640 / 2 - (ponto1[0] + (largura / 2))) * -1) / 5 cv.ShowImage("Webcam", imagem) cv.ShowImage("Mascara", mascara) cv.ShowImage("Cinza", cinza)
def get_contour_from_thresh(image_thresh): storage = cv.CreateMemStorage(0) contour = cv.FindContours(image_thresh, storage, cv.CV_RETR_LIST, cv.CV_CHAIN_APPROX_NONE, (0, 0)) max_length = 0 max_contour = None while contour != None: length = abs(cv.ContourArea(contour)) if length > max_length: max_length = length max_contour = contour contour = contour.h_next() if max_contour == None: print "Couldn't find any contours" return None else: return max_contour
def _check_rectangle(self, rect, scale_factor): ''' Checks if rectangle is a good square marker @param rect: ''' if cv.CheckContourConvexity(rect) != 1: return False, 'conv' area = abs(cv.ContourArea(rect)) if area < SQ_SIZE: return False, 'area %d' % area orientation, code = self._decode_rect(rect) if orientation == self.FAILED: return False, 'no_corner: ' + str(code) else: return True, (code, orientation)
def __init__(self, bid, contour): self.bid = int(bid) self.name = self.label_text_map[bid] while (ishole(contour)): contour = contour.h_next() self.contour = contour self.area = cv.ContourArea(contour) self.center_of_mass = im.center_of_mass(contour) l, t, w, h = cv.BoundingRect(contour) self.bbox = (l, t, l + w, t + h) self.width = w self.height = h self.near_set = set([]) self.north_set = set([]) self.south_set = set([]) self.east_set = set([]) self.west_set = set([])
def CenterFunction(R, imghsv): imgyellowthresh=getthresholdedimgRGeneric(R, imghsv) # creaza mastile de culoare, aici specifice robotului R4 cv.Erode(imgyellowthresh,imgyellowthresh,None,3)#filtru cv.Dilate(imgyellowthresh,imgyellowthresh,None,6)#filtru img2=cv.CloneImage(imgyellowthresh)#cloneaza imaginea in img2, useless storage = cv.CreateMemStorage(0)#creaza un loc in memorie unde sa stocheze, necesar ptr FindContours contour = cv.FindContours(imgyellowthresh, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE)#gaseste contururile robotilor points = [] # This is the new part here. ie Use of cv.BoundingRect() while contour: # Draw bounding rectangles bound_rect = cv.BoundingRect(list(contour)) #creaza un patratel din punctele din contur, ptr afisare/debug #bound_rect = cv.BoundingRect(contour) # for more details about cv.BoundingRect,see documentation pt1 = (bound_rect[0], bound_rect[1]) # pt2 = (bound_rect[0] + bound_rect[2], bound_rect[1] + bound_rect[3]) points.append(pt1) points.append(pt2) cv.Rectangle(color_image, pt1, pt2, cv.CV_RGB(255,0,0), 1) #pana aici s-a desenat patratul # Calculating centroids centroidx=cv.Round((pt1[0]+pt2[0])/2) centroidy=cv.Round((pt1[1]+pt2[1])/2) area = cv.ContourArea(list(contour)) #print "CentroidXY:" + str(centroidx) +":" +str(centroidy) + "A:" + str(area) if(area > 100): print "CentroidXY:" + str(centroidx) +":" +str(centroidy) + "A:" + str(area) coords = pack('iiiii', 4,centroidx, centroidy, 0, int(time.time())) mosq.publish("coords", coords, 0) contour = contour.h_next() print contour # Identifying if blue or yellow blobs and adding centroids to corresponding lists if (169<cv.Get2D(imghsv,centroidy,centroidx)[0]<180): red.append((centroidx,centroidy)) elif (100<cv.Get2D(imghsv,centroidy,centroidx)[0]<120): blue.append((centroidx,centroidy)) elif (67<cv.Get2D(imghsv,centroidy,centroidx)[0]<100): green.append((centroidx, centroidy)) return
def getBoundingRects(self): ''' @return: the bounding boxes of the external contours of the foreground mask. @note: You must call detect() before getBoundingRects() to see updated results. ''' #create a list of the top-level contours found in the contours (cv.Seq) structure rects = [] if len(self._contours) < 1: return (rects) seq = self._contours while not (seq == None): (x, y, w, h) = cv.BoundingRect(seq) if (cv.ContourArea(seq) > self._minArea): r = pv.Rect(x, y, w, h) rects.append(r) seq = seq.h_next() if self._filter != None: rects = self._filter(rects) return rects
def set_new_position(self, points_or_corners, offset=True, scale=1): ''' Sets new position for this marker using points (in order) @param points_or_corners: list of points or corners @param offset: if true, image ROI is checked and points are shifted ''' if len(points_or_corners) > 0 and type(points_or_corners[0]) == tuple: self.predicted = -1 points = points_or_corners img = self.m_d.img (x, y, _, _) = rect = cv.GetImageROI(img) if offset and (x, y) <> (0, 0): points = map(lambda z: add((x, y), z), points) cv.ResetImageROI(img) crit = (cv.CV_TERMCRIT_EPS + cv.CV_TERMCRIT_ITER, 30, 0.1) if (scale > 1): points = cv.FindCornerSubPix(self.m_d.gray_img, points, (scale * 2 + 4, scale * 2 + 4), (-1, -1), crit) else: points = cv.FindCornerSubPix(self.m_d.gray_img, points, (3, 3), (-1, -1), crit) ncorners = Corner.get_corners(points, self.m_d.time) if len(self.corners) <> 0: for i, cor in enumerate(ncorners): cor.compute_change(self.corners[i]) cv.SetImageROI(img, rect) else: ncorners = points_or_corners self.predicted += len(filter(lambda x: x.is_predicted, ncorners)) for i, c in enumerate(ncorners): c.black_inside = self.black_inside # if len(self.corners)==4: # if dist_points(c.p, self.corners[i].p)<4: # c.p=self.corners[i].p self.corners = ncorners self.area = abs(cv.ContourArea(self.points)) self.last_seen = self.m_d.time self.model_view = None
def getPolygons(self, return_all=False): ''' @param return_all: return all contours regardless of min area. @return: the polygon contours of the foreground mask. The polygons are compatible with pv.Image annotatePolygon() method. @note: You must call detect() before getPolygons() to see updated results. ''' #create a list of the top-level contours found in the contours (cv.Seq) structure polys = [] if len(self._contours) < 1: return (polys) seq = self._contours while not (seq == None): if return_all or (cv.ContourArea(seq) > self._minArea): poly = [pv.Point(*each) for each in seq] poly.append(poly[0]) polys.append(poly) seq = seq.h_next() return polys
def segment(self, cv_source_image): self.get_tracker().flush() hue = self.pre_process_source(cv_source_image) size = (hue.width, hue.height) cv_out = cv.CreateImage(size, 8, 3) cv.Zero(cv_out) bounds = self.find_color_bounds(hue) for bound in bounds: (tmp1d, avg_hue) = self.extract_hue_channel(hue, bound) contours = cv.FindContours(tmp1d, cv.CreateMemStorage(), cv.CV_RETR_CCOMP) while contours: cSize = abs(cv.ContourArea(contours)) if cSize < self.min_contour_size: contours = contours.h_next() continue (_, center, radius) = cv.MinEnclosingCircle(contours) center = (int(center[0]), int(center[1])) id = self.get_tracker().add(center, radius, avg_hue, size) cv.DrawContours(cv_out, contours, cv.CV_RGB(255, 255, avg_hue), cv.CV_RGB(255, 255, avg_hue), 1, -1, 1) contours = contours.h_next() #font = cv.InitFont(cv.CV_FONT_HERSHEY_PLAIN, 0.8, 1, 0, 1, 4); #cv.Circle( cv_out, (x,y), int(radius), cv.CV_RGB(255,255,int(avg_hue)), 1 ); #cv.PutText( cv_out, "%d:%d"%(id, avg_hue), (x,y), font, cv.CV_RGB(255,255,150)); return cv_out
def __detect(self, img): '''Detect objects in the image. It will classify the left and right arms and filter out small 'objects'. Returns an instance of Observation.''' storage = cv.CreateMemStorage(0) contours = cv.FindContours(img, storage, cv.CV_RETR_LIST, cv.CV_CHAIN_APPROX_SIMPLE) observation = self.Observation() # for every group of lines while contours: area = abs(cv.ContourArea(contours)) rect = Rectangle.from_cv_rect(cv.BoundingRect(contours)) rect.contour = contours contours = contours.h_next() # Find the arms based on their expected position. If the found # rectangle contains the pixel, it might be the arm you're looking # for. #small stuff, which has almost no surface, is ignored if area < self.mininum_surface: continue #left arm elif rect.contains(self.left_arm_point): observation.left_arm = rect #right arm elif rect.contains(self.right_arm_point): observation.right_arm = rect #anything else that isn't eeny teeny tiny small, is an object. else: observation.objects.append(rect) return observation
def camera(): print "# Starting initialization..." #camera capture #cap = cv.CaptureFromCAM(0) intrinsics = cv.CreateMat(3, 3, cv.CV_64FC1) cv.Zero(intrinsics) #camera data intrinsics[0, 0] = 1100.850708957251072 intrinsics[1, 1] = 778.955239997982062 intrinsics[2, 2] = 1.0 intrinsics[0, 2] = 348.898495232253822 intrinsics[1, 2] = 320.213734835526282 dist_coeffs = cv.CreateMat(1, 4, cv.CV_64FC1) cv.Zero(dist_coeffs) dist_coeffs[0, 0] = -0.326795877008420 dist_coeffs[0, 1] = 0.139445565548056 dist_coeffs[0, 2] = 0.001245710462327 dist_coeffs[0, 3] = -0.001396618726445 #pFrame = cv.QueryFrame(cap) print "# intrinsics loaded!" #prepare memory capture = cv.CaptureFromCAM(0) src = cv.QueryFrame(capture) size = GetSize(src) dst0 = cv.CreateImage(size, src.depth, src.nChannels) # bg = cv.LoadImage("00000005.jpg") image_ROI = (0,70,640,340) size = (640,340) red = cv.CreateImage(size, 8, 1) green = cv.CreateImage(size, 8, 1) blue = cv.CreateImage(size, 8, 1) hue = cv.CreateImage(size, 8, 1) sat = cv.CreateImage(size, 8, 1) val = cv.CreateImage(size, 8, 1) ball = cv.CreateImage(size, 8, 1) yellow = cv.CreateImage(size, 8, 1) ballx = 0 bally = 0 ballmiss = 0 yellowmiss = 0 bluemiss = 0 dst2 = cv.CreateImage(size, 8, 3) hsv = cv.CreateImage(size,8,3) print "# base images created..." #####------------------ajustment data---------------------############### #shadow high = 40 low = 300 #threshold thresBallInit = 116 thresYellowInit = 94 thresBlueInit = 18 ballRangeInit = 8.0 yellowRangeInit = 5.0 blueRangeInit = 8.0 ballRange = ballRangeInit yellowRange = yellowRangeInit blueRange = blueRangeInit ballMinRange = 1.5 yellowMinRange = 2.5 blueMinRange = 8.0 thresBall = thresBallInit thresYellow = thresYellowInit thresBlue = thresBlueInit #dilate ex = cv.CreateStructuringElementEx(3,3,1,1,cv.CV_SHAPE_RECT) ex2 = cv.CreateStructuringElementEx(2,2,1,1,cv.CV_SHAPE_RECT) ex5 = cv.CreateStructuringElementEx(5,5,1,1,cv.CV_SHAPE_RECT) #ball ballcount = 15.0 ballAreaInit = 105.0 ballAreaRangeInit = 60.0 ballArea = ballAreaInit ballAreaRange = ballAreaRangeInit ballMinAreaRange = 40.0 ballcompact = 3.0 #blue bluecount = 30.0 blueAreaInit = 300.0 blueAreaRangeInit = 150.0 blueArea = blueAreaInit blueAreaRange = blueAreaRangeInit blueMiniAreaRange = 50.0 bluemaxdepth = 8.0 blueminidepth = 2.5 #yellow yellowcount = 30.0 yellowAreaInit = 450.0 yellowAreaRangeInit = 200.0 yellowArea = yellowAreaInit yellowAreaRange = yellowAreaRangeInit yellowMinAreaRange = 50.0 yellowmaxdepth = 10.0 yellowminidepth = 3.2 #####---------------------------------------- #create window NamedWindow("camera",cv.CV_WINDOW_AUTOSIZE) #NamedWindow("ball",cv.CV_WINDOW_AUTOSIZE) #NamedWindow("yellow",cv.CV_WINDOW_AUTOSIZE) #NamedWindow("blue",cv.CV_WINDOW_AUTOSIZE) #NamedWindow("hue",cv.CV_WINDOW_AUTOSIZE) #NamedWindow("sat",cv.CV_WINDOW_AUTOSIZE) #NamedWindow("val",cv.CV_WINDOW_AUTOSIZE) timecount = 0 onesec = time.clock() storage = cv.CreateMemStorage() print "# starting capture..." print '' capture = cv.CaptureFromCAM(0) aa = time.clock() while(True): timecount = timecount + 1 src = cv.QueryFrame(capture) #barrel undistortion cv.Undistort2(src, dst0, intrinsics, dist_coeffs) #ROI = Region of Interests, crop the image cv.SetImageROI(dst0,image_ROI) dst = GetImage(dst0) CvtColor(dst,hsv,CV_RGB2HSV) cv.Split(hsv,hue,sat,val,None) # ShowImage("hue",hue) # ShowImage("val",val) # ShowImage("sat",sat) # BALL cv.Threshold(hue,ball,thresBallInit+ballRange, 255,cv.CV_THRESH_TOZERO_INV) cv.Threshold(hue,ball,thresBallInit-ballRange, 255,cv.CV_THRESH_BINARY) cv.Erode(ball,ball,ex2,1) cv.Dilate(ball,ball,ex2,1) ShowImage("ball",ball) # YELLOW cv.Threshold(hue,yellow,thresYellowInit+yellowRange,255,cv.CV_THRESH_TOZERO_INV) cv.Threshold(yellow,yellow,thresYellowInit-yellowRange,255,cv.CV_THRESH_BINARY) cv.Erode(yellow,yellow,ex2,1) cv.Dilate(yellow,yellow,ex2,1) ShowImage("yellow",yellow) # BLUE # CvtColor(dst,hsv,CV_BGR2HSV) # cv.Split(hsv,hue,sat,val,None) cv.Threshold(hue,blue,thresBlue+blueRange,255,cv.CV_THRESH_BINARY_INV) # cv.Threshold(blue,blue,4,255,cv.CV_THRESH_BINARY) cv.Erode(blue,blue,ex2,1) cv.Dilate(blue,blue,ex2,1) ShowImage("blue",blue) cv.Threshold(val,val,80,255,cv.CV_THRESH_BINARY_INV) cv.Threshold(sat,sat,80,255,cv.CV_THRESH_BINARY_INV) ShowImage("sat2",sat) ShowImage("val2",val) # Removes the walls Sub(blue,val,blue) Sub(blue,sat,blue) Sub(yellow,val,yellow) Sub(yellow,sat,yellow) Sub(ball,val,ball) Sub(ball,sat,ball) Set2D(ball,4,4,255) Set2D(blue,4,4,255) Set2D(yellow,4,4,255) ShowImage("yellow3",yellow) ShowImage("ball3",ball) ShowImage("blue3",blue) #find ball seq = cv.FindContours(ball,storage,cv.CV_RETR_LIST, cv.CV_LINK_RUNS) if seq != None: count = 0 while (seq != None and count <= ballcount): count =count + 1 area = cv.ContourArea(seq)+0.01 compact = ArcLength(seq)*ArcLength(seq)/(4*area*math.pi) if (area < 4 or area > (ballArea+ballAreaRange) or area < (ballArea-ballAreaRange)): #or compact >= ballcompact ): seq = seq.h_next() continue else: ballx = 0 bally = 0 for p in seq: ballx = ballx + p[0] bally = bally + p[1] ballx = int(float(ballx)/len(seq)) bally = int(float(bally)/len(seq)) ###############--------------Auto ajustment print "ball area %f" %area print "ball hue: %f" %hue[bally,ballx] # thresBall = 0.2*hue[bally,ballx]+0.2*thresBall + 0.5*thresBallInit # ballArea = area # if(ballRange > ballMinRange): # ballRange = ballRange -0.1 # if(ballAreaRange > ballMinAreaRange): # ballAreaRange = ballAreaRange -1.0 cv.Circle(dst,(ballx,bally),4,cv.CV_RGB(255,255,255),2,8,0) cv.Circle(dst,(ballx,bally),10,cv.CV_RGB(255,0,0),9,8,0) break if(count > ballcount or seq == None): # thresBall = thresBallInit # ballRange = 0.5*ballRange + 0.5*ballRangeInit # ballArea = ballArea + 10.0 # ballAreaRange = ballAreaRange + 0.1 print ballAreaRange ballx = 0 bally = 0 ballmiss = ballmiss + 1 print "\r# error: ball not found " #find blue seq = cv.FindContours(blue,storage,cv.CV_RETR_LIST, cv.CV_LINK_RUNS) if seq != None: count = 0 while (seq != None and count <= bluecount): count =count + 1 area = cv.ContourArea(seq) if(area < blueArea-blueAreaRange or area > blueArea+blueAreaRange): seq = seq.h_next() continue else: hull = None convex = None hull =cv.ConvexHull2(seq,storage) convex = cv.ConvexityDefects(seq,hull,storage) if (len(convex) > 1): convex = sorted(convex , key = lambda(k1,k2,k3,k4):k4)#sort by depth of the convex defect if (convex[len(convex)-1][3] < blueminidepth or convex[len(convex)-2][3] < blueminidepth or convex[len(convex)-1][3] > bluemaxdepth or convex[len(convex)-2][3] > bluemaxdepth ): seq = seq.h_next() continue else: #find the T blue_start1 = convex[len(convex)-1][0] blue_end1 = convex[len(convex)-1][1] blue_depth1 = convex[len(convex)-1][2] #draw the side line of T blue_start2 = convex[len(convex)-2][0] blue_end2 = convex[len(convex)-2][1] blue_depth2 = convex[len(convex)-2][2] blue_from = ((blue_depth1[0]+blue_depth2[0])/2,(blue_depth1[1]+blue_depth2[1])/2)#calculate the center of robot #calculate the end of direction vector, the two end point of the smaller distans if math.hypot(blue_start1[0]-blue_end2[0],blue_start1[1]-blue_end2[1])>math.hypot(blue_end1[0]-blue_start2[0],blue_end1[1]-blue_start2[1]): blue_to = ((blue_end1[0]+blue_start2[0])/2,(blue_end1[1]+blue_start2[1])/2) else: blue_to = ((blue_start1[0]+blue_end2[0])/2,(blue_start1[1]+blue_end2[1])/2) cv.Line(dst,blue_from,blue_to,cv.CV_RGB(255,0,255),2,8,0) cv.Circle(dst,blue_from,1,cv.CV_RGB(255,0,0),2,8,0) cv.Circle(dst,blue_to,1,cv.CV_RGB(0,0,0),2,8,0) cv.Circle(dst,blue_from,10,cv.CV_RGB(255,0,0),9,8,0) #######---------------------------Auto Ajusting print "blue area %f" %area # print "blue hue: %f" %hue[blue_from[1],blue_from[0]] # thresBlue = hue[blue_from[1],blue_from[0]] #+ 0.4*thresBlue + 0.5*thresBlueInit # blueArea = area # if(blueAreaRange > blueMiniAreaRange): # blueAreaRange = blueAreaRange -1.0 # if(blueRange > blueMinRange): # blueRange = blueRange - 0.1 break else: seq = seq.h_next() continue if(count > bluecount or seq == None): # thresBlue = thresBlueInit # blueAreaRange = blueAreaRange + 10.0 # blueArea = blueArea + 10.0 # blueRange = 0.5*blueRange + 0.5*blueRangeInit bluemiss = bluemiss + 1 blue_from = (0,0); blue_to = (0,0); print "\r# error: blue not found " #find yellow seq = cv.FindContours(yellow,storage,cv.CV_RETR_LIST, cv.CV_LINK_RUNS) if seq != None: count = 0 while (seq != None and count <= yellowcount): count =count + 1 area = cv.ContourArea(seq) if(area < yellowArea-yellowAreaRange or area > yellowArea + yellowAreaRange): seq = seq.h_next() continue else: hull = None convex = None hull =cv.ConvexHull2(seq,storage) convex = cv.ConvexityDefects(seq,hull,storage) if (len(convex) > 1): convex = sorted(convex , key = lambda(k1,k2,k3,k4):k4)#sort by depth of the convex defect if (convex[len(convex)-1][3] < yellowminidepth or convex[len(convex)-2][3] < yellowminidepth or convex[len(convex)-1][3] > yellowmaxdepth or convex[len(convex)-2][3] > yellowmaxdepth ): seq = seq.h_next() continue else: #find the T yellow_start1 = convex[len(convex)-1][0] yellow_end1 = convex[len(convex)-1][1] yellow_depth1 = convex[len(convex)-1][2] #draw the side line of T yellow_start2 = convex[len(convex)-2][0] yellow_end2 = convex[len(convex)-2][1] yellow_depth2 = convex[len(convex)-2][2] yellow_from = ((yellow_depth1[0]+yellow_depth2[0])/2,(yellow_depth1[1]+yellow_depth2[1])/2)#calculate the center of robot #calculate the end of direction vector, the two end point of the smaller distans if math.hypot(yellow_start1[0]-yellow_end2[0],yellow_start1[1]-yellow_end2[1])>math.hypot(yellow_end1[0]-yellow_start2[0],yellow_end1[1]-yellow_start2[1]): yellow_to = ((yellow_end1[0]+yellow_start2[0])/2,(yellow_end1[1]+yellow_start2[1])/2) else: yellow_to = ((yellow_start1[0]+yellow_end2[0])/2,(yellow_start1[1]+yellow_end2[1])/2) ###########------------------------------Auto Ajusting # print cv.ContourArea(seq) print "yellow area %f" %area print "yellow hue: %f" %hue[yellow_from[1],yellow_from[0]] # thresYellow = hue[yellow_from[1],yellow_from[0]] #+ 0.4*thresYellow + 0.5*thresYellowInit # yellowArea = area # if(yellowRange > yellowMinRange): # yellowRange = yellowRange -0.1 # if(yellowAreaRange > yellowMinAreaRange): # yellowAreaRange = yellowAreaRange - 1.0 # yellow_miss = ((yellow_from[0]+yellow_to[0])/2,(yellow_from[1]+yellow_to[1])/2) cv.Line(dst,yellow_from,yellow_to,cv.CV_RGB(255,0,255),2,8,0) cv.Circle(dst,yellow_from,1,cv.CV_RGB(255,0,0),2,8,0) cv.Circle(dst,yellow_to,1,cv.CV_RGB(0,0,0),2,8,0) cv.Circle(dst,yellow_from,10,cv.CV_RGB(255,0,0),9,8,0) break else: seq = seq.h_next() continue if(count > yellowcount or seq == None): #thresYellow = thresYellowInit # yellowRange = 0.5*yellowRange + 0.5*yellowRangeInit #yellowArea = yellowArea # yellowAreaRange = yellowAreaRange + 10.0 print "area:%d" %yellowArea yellowmiss = yellowmiss + 1 yellow_from = (0,0); yellow_to = (0,0); print "\r# error: yellow not found" ballpos = (ballx,bally) #output(ballpos,blue_from,blue_to,yellow_from,yellow_to) ShowImage("camera",dst) cv.SetImageROI(dst0,(0,0,640,480)) # ShowImage("camera",dst0) if( cv.WaitKey(2) >= 0 ): bb = time.clock() print "frame rate: %f" %(timecount/(bb-aa)) print "ball miss rate: %f" %(ballmiss) print "blue miss rate: %f" %(bluemiss) print "yellow miss rate: %f" %(yellowmiss) break;
def find_biggest_region(pub): """ finds all the contours in threshed image, finds the largest of those, and then marks in in the main image """ # get D so that we can change values in it global D # Create a copy image of thresholds then find contours on that image cv.Copy(D.threshed_image, D.copy) # copy threshed image # this is OpenCV's call to find all of the contours: contours = cv.FindContours(D.copy, D.storage, cv.CV_RETR_EXTERNAL, cv.CV_CHAIN_APPROX_SIMPLE) # Next we want to find the *largest* contour # this is the standard algorithm: # walk the list of all contours, remembering the biggest so far: if len(contours) > 0: biggest = contours biggestArea = cv.ContourArea(contours) while contours != None: nextArea = cv.ContourArea(contours) if biggestArea < nextArea: biggest = contours biggestArea = nextArea contours = contours.h_next() # Use OpenCV to get a bounding rectangle for the largest contour br = cv.BoundingRect(biggest, update=0) # Draw a red box from (42,42) to (84,126), for now (you'll change this): x = br[0] y = br[1] w = br[2] h = br[3] upper_left = (x, y) lower_left = (x, y + h) lower_right = (x + w, y + h) upper_right = (x + w, y) cv.PolyLine(D.image, [[upper_left, lower_left, lower_right, upper_right]], 1, cv.RGB(255, 0, 0)) # Draw the circle, at the image center for now (you'll change this) center = ((2 * x + w) / 2, (2 * y + h) / 2) cv.Circle(D.image, center, 10, cv.RGB(255, 255, 0), thickness=2, lineType=8, shift=0) # Draw matching contours in white with inner ones in green cv.DrawContours(D.image, biggest, cv.RGB(255, 255, 255), cv.RGB(0, 255, 0), 1, thickness=2, lineType=8, offset=(0, 0)) # publish the rectangle vertex coordinates pub.publish(','.join(map(str, [upper_left, lower_right])))