def ellipseFitting(points): PointArray2D32f = cv.CreateMat(1, points.shape[0], cv.CV_32FC2) for i in range(points.shape[0]): PointArray2D32f[0, i] = (points[i, 0], points[i, 1]) center, diameter, angle = cv.FitEllipse2(PointArray2D32f) angle /= 180 * npy.pi return (center, diameter, angle)
def fitEllipse(cvImg): """ Use OpenCV to find the contours of the input cvImage and then proceed to find best bit ellipses around the contours. This is a rough approach to identifying the primary 'objects of interest' within an image. Render the results as ellipses onto a copy of the input image and return this cvImage as the result of the method call. @param cvImg: input OpenCV image to find best fit ellipses. @return: a copy of the input image with ellipse results rendered onto it. """ def contourIterator(contour): """ Helper method to iterate over cvContours. """ while contour: yield contour contour = contour.h_next() # Find all contours. stor = cv.CreateMemStorage() cont = cv.FindContours(cvImg, stor, cv.CV_RETR_LIST, cv.CV_CHAIN_APPROX_NONE, (0, 0)) cimg = cv.CreateImage((cvImg.width,cvImg.height), cv.IPL_DEPTH_8U, 3) cv.CvtColor(cvImg, cimg, cv.CV_GRAY2BGR) # clen = 0 # for c in contourIterator(cont): # clen += len(c) # ptMat = cv.CreateMat(1, clen, cv.CV_32FC2) # ci = 0 for c in contourIterator(cont): # for (i, (x, y)) in enumerate(c): # ptMat[0, i+ci] = (x, y) # ci += len(c) # Number of points must be more than or equal to 6 for cv.FitEllipse2 if len(c) >= 6: # Copy the contour into an array of (x,y)s ptMat = cv.CreateMat(1, len(c), cv.CV_32FC2) for (i, (x, y)) in enumerate(c): ptMat[0, i] = (x, y) # Draw the current contour in gray gray = cv.CV_RGB(150, 150, 150) cv.DrawContours(cimg, c, gray, gray,0,1,8,(0,0)) # Fits ellipse to current contour. (center, size, angle) = cv.FitEllipse2(ptMat) # Convert ellipse data from float to integer representation. center = (cv.Round(center[0]), cv.Round(center[1])) size = (cv.Round(size[0] * 0.5), cv.Round(size[1] * 0.5)) #angle = -angle # Draw ellipse in random color color = cv.CV_RGB(0,0,255) cv.Ellipse(cimg, center, size, angle, 0, 360, color, 1, cv.CV_AA, 0) return cimg
def process_image(self, slider_pos): """ This function finds contours, draws them and their approximation by ellipses. """ stor = cv.CreateMemStorage() # Create the destination images image02 = cv.CloneImage(self.source_image) cv.Zero(image02) image04 = cv.CreateImage(cv.GetSize(self.source_image), cv.IPL_DEPTH_8U, 3) cv.Zero(image04) # Threshold the source image. This needful for cv.FindContours(). cv.Threshold(self.source_image, image02, slider_pos, 255, cv.CV_THRESH_BINARY) # Find all contours. cont = cv.FindContours(image02, stor, cv.CV_RETR_LIST, cv.CV_CHAIN_APPROX_NONE, (0, 0)) for c in contour_iterator(cont): # Number of points must be more than or equal to 6 for cv.FitEllipse2 if len(c) >= 6: # Copy the contour into an array of (x,y)s PointArray2D32f = cv.CreateMat(1, len(c), cv.CV_32FC2) for (i, (x, y)) in enumerate(c): PointArray2D32f[0, i] = (x, y) # Draw the current contour in gray gray = cv.CV_RGB(100, 100, 100) cv.DrawContours(image04, c, gray, gray, 0, 1, 8, (0, 0)) # Fits ellipse to current contour. (center, size, angle) = cv.FitEllipse2(PointArray2D32f) # Convert ellipse data from float to integer representation. center = (cv.Round(center[0]), cv.Round(center[1])) size = (cv.Round(size[0] * 0.5), cv.Round(size[1] * 0.5)) angle = -angle # Draw ellipse in random color color = cv.CV_RGB(random.randrange(256), random.randrange(256), random.randrange(256)) cv.Ellipse(image04, center, size, angle, 0, 360, color, 2, cv.CV_AA, 0) # Show image. HighGUI use. cv.ShowImage("Result", image04)
def track_lk(self, cv_image, face): feature_box = None """ Initialize intermediate images if necessary """ if not face.pyramid: face.grey = cv.CreateImage(cv.GetSize(cv_image), 8, 1) face.prev_grey = cv.CreateImage(cv.GetSize(cv_image), 8, 1) face.pyramid = cv.CreateImage(cv.GetSize(cv_image), 8, 1) face.prev_pyramid = cv.CreateImage(cv.GetSize(cv_image), 8, 1) face.features = [] """ Create a grey version of the image """ cv.CvtColor(cv_image, face.grey, cv.CV_BGR2GRAY) """ Equalize the histogram to reduce lighting effects """ cv.EqualizeHist(face.grey, face.grey) if face.track_box and face.features != []: """ We have feature points, so track and display them """ """ Calculate the optical flow """ face.features, status, track_error = cv.CalcOpticalFlowPyrLK( face.prev_grey, face.grey, face.prev_pyramid, face.pyramid, face.features, (self.win_size, self.win_size), 3, (cv.CV_TERMCRIT_ITER | cv.CV_TERMCRIT_EPS, 20, 0.01), self.flags) """ Keep only high status points """ face.features = [p for (st, p) in zip(status, face.features) if st] elif face.track_box and self.is_rect_nonzero(face.track_box): """ Get the initial features to track """ """ Create a mask image to be used to select the tracked points """ mask = cv.CreateImage(cv.GetSize(cv_image), 8, 1) """ Begin with all black pixels """ cv.Zero(mask) """ Get the coordinates and dimensions of the track box """ try: x, y, w, h = face.track_box except: return None if self.auto_face_tracking: # """ For faces, the detect box tends to extend beyond the actual object so shrink it slightly """ # x = int(0.97 * x) # y = int(0.97 * y) # w = int(1 * w) # h = int(1 * h) """ Get the center of the track box (type CvRect) so we can create the equivalent CvBox2D (rotated rectangle) required by EllipseBox below. """ center_x = int(x + w / 2) center_y = int(y + h / 2) roi_box = ((center_x, center_y), (w, h), 0) """ Create a filled white ellipse within the track_box to define the ROI. """ cv.EllipseBox(mask, roi_box, cv.CV_RGB(255, 255, 255), cv.CV_FILLED) else: """ For manually selected regions, just use a rectangle """ pt1 = (x, y) pt2 = (x + w, y + h) cv.Rectangle(mask, pt1, pt2, cv.CV_RGB(255, 255, 255), cv.CV_FILLED) """ Create the temporary scratchpad images """ eig = cv.CreateImage(cv.GetSize(self.grey), 32, 1) temp = cv.CreateImage(cv.GetSize(self.grey), 32, 1) if self.feature_type == 0: """ Find keypoints to track using Good Features to Track """ face.features = cv.GoodFeaturesToTrack( face.grey, eig, temp, self.max_count, self.quality, self.good_feature_distance, mask=mask, blockSize=self.block_size, useHarris=self.use_harris, k=0.04) elif self.feature_type == 1: """ Get the new features using SURF """ (surf_features, descriptors) = cv.ExtractSURF( face.grey, mask, cv.CreateMemStorage(0), (0, self.surf_hessian_quality, 3, 1)) for feature in surf_features: face.features.append(feature[0]) # if self.auto_min_features: """ Since the detect box is larger than the actual face or desired patch, shrink the number of features by 10% """ face.min_features = int(len(face.features) * 0.9) face.abs_min_features = int(0.5 * face.min_features) """ Swapping the images """ face.prev_grey, face.grey = face.grey, face.prev_grey face.prev_pyramid, face.pyramid = face.pyramid, face.prev_pyramid """ If we have some features... """ if len(face.features) > 0: """ The FitEllipse2 function below requires us to convert the feature array into a CvMat matrix """ try: self.feature_matrix = cv.CreateMat(1, len(face.features), cv.CV_32SC2) except: pass """ Draw the points as green circles and add them to the features matrix """ i = 0 for the_point in face.features: if self.show_features: cv.Circle(self.marker_image, (int(the_point[0]), int(the_point[1])), 2, (0, 255, 0, 0), cv.CV_FILLED, 8, 0) try: cv.Set2D(self.feature_matrix, 0, i, (int(the_point[0]), int(the_point[1]))) except: pass i = i + 1 """ Draw the best fit ellipse around the feature points """ if len(face.features) > 6: feature_box = cv.FitEllipse2(self.feature_matrix) else: feature_box = None """ Publish the ROI for the tracked object """ # try: # (roi_center, roi_size, roi_angle) = feature_box # except: # logger.info("Patch box has shrunk to zeros...") # feature_box = None # if feature_box and not self.drag_start and self.is_rect_nonzero(face.track_box): # self.ROI = RegionOfInterest() # self.ROI.x_offset = min(self.image_size[0], max(0, int(roi_center[0] - roi_size[0] / 2))) # self.ROI.y_offset = min(self.image_size[1], max(0, int(roi_center[1] - roi_size[1] / 2))) # self.ROI.width = min(self.image_size[0], int(roi_size[0])) # self.ROI.height = min(self.image_size[1], int(roi_size[1])) # self.pubROI.publish(self.ROI) if feature_box is not None and len(face.features) > 0: return feature_box else: return None
cv.Sub(fgim, fbg, fim) cv.Scale(fim, fim, -255.) #print cv.MinMaxLoc(fim) cv.Threshold(fim, bim, 100., 255, cv.CV_THRESH_BINARY) cv.Erode(bim, bim, iterations=1) cbim = bim[mazeybb[0]:mazeybb[1], mazexbb[0]:mazexbb[1]] #area = cv.ContourArea(pts) rect = cv.BoundingRect(cbim) if False: # len(pts) >= 6: logging.debug("Ellipse") pts = cv.FindContours(cbim, cv.CreateMemStorage(), \ cv.CV_RETR_LIST, cv.CV_LINK_RUNS) m = cv.CreateMat(1, len(pts), cv.CV_32FC2) for (i, (x, y)) in enumerate(pts): m[0, i] = (x, y) e = cv.FitEllipse2(m) (ecenter, esize, eangle) = e cv.Ellipse(im, (int(ecenter[0] + mazexbb[0]), \ int(ecenter[1] + mazeybb[0])), (int(esize[0] * 0.5), \ int(esize[1] * 0.5)), -eangle, 0, 360, \ (0, 0, 255), 2, cv.CV_AA, 0) x = ecenter[0] + mazexbb[0] y = ecenter[1] + mazeybb[0] m = 1 else: #logging.debug("Rectangle") x, y = (int(mazexbb[0] + rect[0]), int(mazeybb[0] + rect[1])) w, h = (rect[2], rect[3]) cv.Rectangle(im, (x, y), (x + w, y + h), (255, 0, 0)) x = x + w / 2. y = y + h / 2.
def contour_iterator(contour): while contour: yield contour contour = contour.h_next() for c in contour_iterator(contours): # Qde de pontos deve ser ≥ 6 para cv.FitEllipse2 if len(c) >= 6: # Copiar o contorno em um array de (x,y)'s PointArray = cv.CreateMat(1, len(c), cv.CV_32FC2) for (i, (x, y)) in enumerate(c): PointArray[0, i] = (x, y) # Encaixar elipse ao contorno (center, size, angle) = cv.FitEllipse2(PointArray) # Converter dados float da elipse para inteiros center = (cv.Round(center[0]), cv.Round(center[1])) size = (cv.Round(size[0] * 0.5), cv.Round(size[1] * 0.5)) # Plot elipse cv.Ellipse(orig, center, size, angle, 0, 360, cv.RGB(255, 0, 0), 2, cv.CV_AA, 0) cv.ShowImage("imagem original", orig) #cv.ShowImage("post-process", processed) cv.WaitKey(0)