def find_connected_components(frame): """Find connected components from an image. :: iplimage -> [ dict(box<CvBox2D>, rect<CvRect>) ] Takes as input a grayscale image that should have some blobs in it. Outputs a data structure containing the 'centers' of the blobs and minimal rectangles enclosing them. A maximum of 3 blobs are returned. The input frame is modified in place. """ contours = get_contours(frame) #out = draw_contours(frame, contours) candidates = [] for contour in contours: storage = cv.CreateMemStorage(0) minBox = cv.MinAreaRect2(contour, storage) boundingRect = cv.BoundingRect(contour, 0) candidates.append({'box': minBox, 'rect': boundingRect}) candidates = sorted(candidates, key=lambda x: getArea(x['box']), reverse=True) return candidates
def draw_common(points): success, center, radius = cv.MinEnclosingCircle(points) if success: cv.Circle(img, roundxy(center), cv.Round(radius), cv.CV_RGB(255, 255, 0), 1, cv.CV_AA, 0) box = cv.MinAreaRect2(points) box_vtx = [roundxy(p) for p in cv.BoxPoints(box)] cv.PolyLine(img, [box_vtx], 1, cv.CV_RGB(0, 255, 255), 1, cv.CV_AA)
def __init__(self, cont): self.cont = cont self.color = random_color() self.count = -1 self.id = random.randint(1, 2**31) self.frames = None self.desc = None self.ids = None box = cv.MinAreaRect2(cont) self.box_points = [(int(x), int(y)) for x, y in cv.BoxPoints(box)]
def minAreaRectImage(image, returnPoints=True): points = [] for x in xrange(image.width): for y in xrange(image.height): if image[y, x] > 128: points.append((x, y)) box = cv.MinAreaRect2(points) if not returnPoints: return box box_vtx = map(roundXY, cv.BoxPoints(box)) return box_vtx
def get_rectangle(contour): '''根据一个矩形内轮廓角点集识别出此矩形''' rect = cv.MinAreaRect2(contour) #get the uniform angle if rect[2]<-45: rect = [rect[0],(rect[1][1],rect[1][0]),rect[2]+90] elif rect[2]>45: rect = [rect[0],(rect[1][1],rect[1][0]),rect[2]-90] else: rect = [rect[0],rect[1],rect[2]] return rect
def dewarp(image,window,corners): debug = image.copy() print(corners) # draw red line around edges for debug purposes cv2.polylines(debug, np.int32([[corners[0],corners[1], corners[3],corners[2]]]), True, (0,255,0),7) #show results if DISPLAY: cv2.imshow(window,debug) cv2.cv.ResizeWindow(window,960,640) cv2.waitKey(WAIT_TIME) # Assemble a rotated rectangle out of that info # Todo: move to cV2 np_corners = np.array(corners) rot_box = cv.MinAreaRect2(corners) enc_box = cv.BoundingRect(corners) scaling = 1.0 border = 10 pt_x = enc_box[2]*scaling pt_y = enc_box[3]*scaling new_corners = [(border,border),(pt_x-1+border,border), (border,pt_y-1+border),(pt_x-1+border,pt_y-1+border)] corners = np.array(corners,np.float32) new_corners = np.array(new_corners,np.float32) warp_mat = cv2.getPerspectiveTransform(corners, new_corners) rotated = cv2.warpPerspective(image, warp_mat, (int(round(pt_x+border*2)), int(round(pt_y+border*2)))) #show results if DISPLAY: cv2.imshow(window,rotated) cv2.cv.ResizeWindow(window,960,640) cv2.waitKey(WAIT_TIME) return rotated
def plot_contours(src_image, dest_image): cv.NamedWindow("debug", cv.CV_WINDOW_AUTOSIZE) # Better to use HSV when doing extraction (rows, cols) = cv.GetSize(src_image) image_hsv = cv.CreateImage((rows, cols), cv.IPL_DEPTH_8U, 3) h_plane = cv.CreateImage((rows, cols), 8, 1) s_plane = cv.CreateImage((rows, cols), 8, 1) image_bin = cv.CreateImage((rows, cols), 8, 1) cv.CvtColor(src_image, image_hsv, cv.CV_RGB2HSV) cv.Laplace(h_plane, h_plane, 3) cv.Threshold(h_plane, h_plane, 40.0, 255.0, cv.CV_THRESH_BINARY) cv.Smooth(h_plane, h_plane, cv.CV_BLUR, 5, 5) # Its suggested that smoothing first gives better results cv.ShowImage("debug", h_plane) # Create binary image to be used for contour detection # image_gray = cv.CreateImage(cv.GetSize(src_image), 8, 1) # cv.CvtColor(image_hsv, image_gray, cv.CV_BGR2GRAY) # cv.Laplace(image_gray, image_gray, 3) # cv.Threshold(image_gray, image_gray, 40.0, 255.0, cv.CV_THRESH_BINARY) # cv.Smooth(image_gray, image_gray, cv.CV_BLUR, 5, 5) # Its suggested that smoothing first gives better results # cv.ShowImage("debug", image_gray) contours = cv.FindContours(image_gray, cv.CreateMemStorage(), cv.CV_RETR_LIST, cv.CV_CHAIN_APPROX_SIMPLE) #cv.DrawContours(dest_image, contours, (255,0,0), (0,255,0), 1, 2) # Draw bounding box + mass center of shape while contours: rect = cv.MinAreaRect2(contours) box = cv.BoxPoints(rect) for i in range(4): cv.Line(dest_image, box[i], box[(i + 1) % 4], (0, 0, 255), 1, 8) mom = cv.Moments(contours) for j in mom: print j # momPoint = cv.CvPoint(mom.m10/mom.m00,mom.m01/mom.m00) # cv.Circle(dest_image, (mom.m10/mom.m00,mom.m01/mom.m00), 2, (0,255,255)) # r0 = cv.BoundingRect(cnt) # Rectangle(dest_image, pt1, pt2, (0,255,0)) contours = contours.h_next()
def find_connected_components(frame): """Find connected components from an image. :: iplimage -> [ dict(box<CvBox2D>, rect<CvRect>) ] Takes as input a grayscale image that should have some blobs in it. Outputs a data structure containing the 'centers' of the blobs and minimal rectangles enclosing them. A maximum of 3 blobs are returned. The input frame is modified in place. """ # A workaround for OpenCV 2.0 crash on receiving a (nearly) black image nonzero = cv.CountNonZero(frame) if nonzero < 20: return [] logging.debug("Segmentation got an image with %d nonzero pixels", nonzero) contours = get_contours(frame) #out = draw_contours(frame, contours) if contours is None: return [] candidates = [] while contours: storage = cv.CreateMemStorage(0) minBox = cv.MinAreaRect2(contours, storage) boundingRect = cv.BoundingRect(contours, 0) candidates.append({ 'box' : minBox, 'rect' : boundingRect }) contours = contours.h_next() candidates = sorted( candidates, key=lambda x:getArea(x['box']), reverse=True ) return candidates
def filter_red(src_img, dest_img): cv.Smooth(src_img, src_img) # Histogram # h = np.zeros((300,256,3)) # b,g,r = cv.Split(src_img) # bins = np.arange(256).reshape(256,1) # color = [ (255,0,0),(0,255,0),(0,0,255) ] # CalcHist(image, hist, accumulate=0, mask=NULL) # histogram = cv.CalcHist(h_plane,[0],None,[256],[0,255]) # # cv.NormalizeHist(histogram, 1) # hist=np.int32(np.around(hist_item)) # pts = np.column_stack((bins,hist)) # cv2.polylines(h,[pts],False,col) # h_bins = 30 # s_bins = 32 # hist_size = [h_bins, s_bins] # # hue varies from 0 (~0 deg red) to 180 (~360 deg red again */ # h_ranges = [0, 180] # # saturation varies from 0 (black-gray-white) to # # 255 (pure spectrum color) # s_ranges = [0, 255] # ranges = [h_ranges, s_ranges] # scale = 10 # hist = cv.CreateHist(h_bins, cv.CV_HIST_ARRAY, ranges, 1) # cv.CalcHist(src_img, hist) # (_, max_value, _, _) = cv.GetMinMaxHistValue(hist) # for h in range(h_bins): # bin_val = cv.QueryHistValue_2D(hist, h, s) # intensity = cv.Round(bin_val * 255 / max_value) # cv.Rectangle(hist_img, # (h*scale, s*scale), # ((h+1)*scale - 1, (s+1)*scale - 1), # cv.RGB(intensity, intensity, intensity), # cv.CV_FILLED) (rows, cols) = cv.GetSize(src_img) img_hsv = cv.CreateImage((rows, cols), cv.IPL_DEPTH_8U, 3) h_plane = cv.CreateImage((rows, cols), 8, 1) s_plane = cv.CreateImage((rows, cols), 8, 1) img_binary = cv.CreateImage((rows, cols), 8, 1) cv.CvtColor(src_img, img_hsv, cv.CV_RGB2HSV) # cv.Split(img_hsv, h_plane, s_plane, None, None) # cv.EqualizeHist(h_plane, h_plane) # Gives better result in form of less flickering cv.InRangeS(img_hsv, cv.Scalar(COLOR_RANGE_LOW, 100, 100), cv.Scalar(COLOR_RANGE_HIGH, 255, 255), h_plane) # create temps used by algorithm images # eig = cv.CreateImage(cv.GetSize(src_img), cv.IPL_DEPTH_32F, 1) # temp = cv.CreateImage(cv.GetSize(src_img), cv.IPL_DEPTH_32F, 1) # the default parameters # quality = 0.01 # min_distance = 30 # min distance between detected points # search the good points # features = cv.GoodFeaturesToTrack(h_plane, eig, temp, 20, quality, min_distance) # for (x,y) in features: # cv.Circle(dest_img, (x, y), 3, (0, 255, 0), -1, 8, 0) cv.Canny(h_plane, h_plane, CANNY_LOW, CANNY_HIGH) cv.ShowImage("thresh", h_plane) contours = cv.FindContours(h_plane, cv.CreateMemStorage(), cv.CV_RETR_EXTERNAL, cv.CV_CHAIN_APPROX_SIMPLE) while contours: rect = cv.MinAreaRect2(contours) if cv.ContourArea(contours) > 1000: print "FOUND RECT WITH AREA: %s" % cv.ContourArea(contours) box = cv.BoxPoints(rect) for i in range(4): cv.Line(dest_img, box[i], box[(i + 1) % 4], (0, 255, 0), 6, 8) contours = contours.h_next() # HoughLines2(image, storage, method, rho, theta, threshold, param1=0, param2=0) # lines = cv.HoughLines2(h_plane, cv.CreateMemStorage(), cv.CV_HOUGH_PROBABILISTIC, cv.CV_PI/180, 1, 50, 1) # for l in lines: # (p1, p2) = l # # Line(img, pt1, pt2, color, thickness=1, lineType=8, shift=0) # cv.Line(dest_img, p1, p2, cv.Scalar(0,0,255), 2, cv.CV_AA) cv.ShowImage("result", dest_img)
def cont(self, value): self._cont = value box = cv.MinAreaRect2(value) self.box_points = [(int(x), int(y)) for x, y in cv.BoxPoints(box)]
def detect_motion(self, sensitivity='medium'): #Finding Video Size from the first frame frame = cv.QueryFrame(self.video_handle) frame_size = cv.GetSize(frame) '''Initializing Image Variables(to be used in motion detection) with required types and sizes''' # Image containg instantaneous moving rectangles color_image = cv.CreateImage(frame_size, 8, 3) # Resizing to window size color_output = cv.CreateImage(self.window_size, 8, 3) # Grey Image used for contour detection grey_image = cv.CreateImage(frame_size, cv.IPL_DEPTH_8U, 1) # Image storing background (moving pixels are averaged over small time window) moving_average = cv.CreateImage(frame_size, cv.IPL_DEPTH_32F, 3) # Image for storing tracks resized to window size track_output = cv.CreateImage(self.window_size, cv.IPL_DEPTH_8U, 3) track_image, track_win = self.init_track_window(frame) def totuple(a): try: return tuple(totuple(i) for i in a) except TypeError: return a first = True # Infinite loop for continuous detection of motion while True: '''########## Pixelwise Detection of Motion in a frame ###########''' # Capturing Frame color_image = cv.QueryFrame(self.video_handle) ##### Sensitivity Control 1 ##### if (sensitivity == 'medium') or (sensitivity == 'low'): # Gaussian Smoothing cv.Smooth(color_image, color_image, cv.CV_GAUSSIAN, 3, 0) if first: difference = cv.CloneImage(color_image) temp = cv.CloneImage(color_image) cv.ConvertScale(color_image, moving_average, 1.0, 0.0) first = False else: cv.RunningAvg(color_image, moving_average, .020, None) # Convert the scale of the moving average. cv.ConvertScale(moving_average, temp, 1, 0.0) # Minus the current frame from the moving average. cv.AbsDiff(color_image, temp, difference) #cv.ShowImage("BG",difference) # Convert the image to grayscale. cv.CvtColor(difference, grey_image, cv.CV_RGB2GRAY) ##### Sensitivity Control 2 ##### sens_thres = 90 if (sensitivity == 'low') or (self.opt == 'cam') else 40 # Convert the image to black and white. cv.Threshold(grey_image, grey_image, sens_thres, 255, cv.CV_THRESH_BINARY) '''### Blobing moved adjacent pixels, finding closed contours and bounding rectangles ###''' ##### Sensitivity Control 3 ##### if (sensitivity == 'medium') or (sensitivity == 'low'): # Dilate and erode to get people blobs ker_size = 20 if self.opt == 'file' else 50 cv.Dilate(grey_image, grey_image, None, ker_size) cv.Erode(grey_image, grey_image, None, 3) storage = cv.CreateMemStorage(0) contour = cv.FindContours(grey_image, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE) points = [] while contour: bound_rect = cv.BoundingRect(list(contour)) polygon_points = cv.ApproxPoly(list(contour), storage, cv.CV_POLY_APPROX_DP) pt1 = (bound_rect[0], bound_rect[1]) pt2 = (bound_rect[0] + bound_rect[2], bound_rect[1] + bound_rect[3]) if (self.opt == 'file'): points.append(pt1) points.append(pt2) elif (bound_rect[0] - bound_rect[2] > 20) and (bound_rect[1] - bound_rect[3] > 20): points.append(pt1) points.append(pt2) box = cv.MinAreaRect2(polygon_points) box2 = cv.BoxPoints(box) box3 = np.int0(np.around(box2)) box4 = totuple(box3) box5 = box4 + (box4[0], ) # Filling the contours in the greyscale image (visual blobs instead of just contours) cv.FillPoly(grey_image, [ list(polygon_points), ], cv.CV_RGB(255, 255, 255), 0, 0) # Following line to draw detected contours as well #cv.PolyLine( color_image, [ polygon_points, ], 0, cv.CV_RGB(255,0,0), 1, 0, 0 ) # Drawing Rectangle around the detected contour cv.PolyLine(color_image, [list(box5)], 0, (0, 255, 255), 2) if len(points): # (self.opt == 'file') and center1 = (pt1[0] + pt2[0]) / 2 center2 = (pt1[1] + pt2[1]) / 2 cv.Circle(color_image, (center1, center2), 5, cv.CV_RGB(0, 255, 0), -1) rad = 3 if self.opt == 'file' else 5 cv.Circle(track_image, (center1, center2), rad, cv.CV_RGB(255, 128, 0), -1) contour = contour.h_next() # Uncomment to track centroid of all the moved boxes (only for WebCam) ''' if (self.opt == 'cam') and len(points): center_point = reduce(lambda a, b: ((a[0] + b[0]) / 2, (a[1] + b[1]) / 2), points) cv.Circle(track_image, center_point, 15, cv.CV_RGB(255, 128, 0), -1) ''' cv.Resize(color_image, color_output, cv.CV_INTER_AREA) cv.ShowImage("Original", color_output) cv.Resize(track_image, track_output, cv.CV_INTER_AREA) cv.ShowImage(track_win, track_output) # Listen for ESC key c = cv.WaitKey(7) % 0x100 if (0xFF & c == 27): cv.SaveImage('Tracks_img_042_' + sensitivity + '.jpeg', track_output) break
def aspect(c): ((x, y), (w, h), th) = cv.MinAreaRect2(c, cv.CreateMemStorage()) return max([w / h, h / w])
def seq_min_rects(seqs): min_rects = [] for seq in seqs: min_rect = cv.MinAreaRect2(seq) min_rects.append(min_rect) return min_rects