blob.py
Go to the documentation of this file.
00001 ##################################################################
00002 # Functions and classes for dealing with OpenCV enclosed contours
00003 # (a blob is an enclosed contour).
00004 ##################################################################
00005 import roslib; roslib.load_manifest('hrl_opencv')
00006 import cv
00007 import numpy as np
00008 import hrl_opencv.adaptors as ad
00009 
00010 def bound(value, min_val, max_val):
00011     return min(max(value, min_val), max_val)
00012 
00013 class Rect:
00014     def __init__(self, x, y, width, height):
00015         self.x = x
00016         self.y = y
00017         self.width = width
00018         self.height = height
00019 
00020     def as_cv_rect(self):
00021         return (int(round(self.x)), int(round(self.y)), int(round(self.width)), int(round(self.height)))
00022 
00023     def top_left(self):
00024         return (int(round(self.x)), int(round(self.y)))
00025 
00026     def bottom_right(self):
00027         return (int(round(self.x+self.width)), int(round(self.y+self.height)))
00028 
00029     def keep_inside(self, minx, maxx, miny, maxy):
00030         nx = bound(self.x, minx, maxx)
00031         ny = bound(self.y, miny, maxy)
00032         mx = bound(self.x + self.width, minx,  maxx)
00033         my = bound(self.y + self.height, miny, maxy)
00034         return Rect(nx, ny, mx-nx, my-ny)
00035 
00036     def __repr__(self):
00037         return 'Rect: ' + str(self.x) + ' ' + str(self.y)+ ' ' + str(self.width)+ ' ' + str(self.height)
00038 
00039 def remove_large_blobs(binary_image, max_area, max_dim=30):#, show=False):
00040     blob_statistics(binary_image, max_area, max_dim)#, show=True)
00041     return binary_image
00042 
00043 ##
00044 #    WARNING: this function destructively modifies binary_image if max_area is set
00045 #
00046 def blob_statistics(binary_image, max_area=99999.0, max_dim=99999.0):#, show=False):
00047     statistics                = []
00048     storage                   = cv.CreateMemStorage(0)
00049     #FindContours(image,        storage, mode=CV_RETR_LIST, method=CV_CHAIN_APPROX_SIMPLE, offset=(0, 0))
00050     contours = cv.FindContours(binary_image, storage, cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE, (0,0))
00051     #number_contours, contours = cv.FindContours(binary_image, storage, cv.sizeof_CvContour, cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE, (0,0))
00052     #TODO: FIGURE OUT WHAT THE EQUIV OF SIZEOF IS IN OPENCV2
00053     #import pdb
00054     #pdb.set_trace()
00055 
00056     original_ptr = contours
00057     while contours != None:
00058         try:
00059             bx, by, bwidth, bheight = cv.BoundingRect(contours, 0)
00060             bounding_rect = Rect(bx, by, bwidth, bheight)
00061             moments = cv.Moments(contours, 0)
00062             #area = moments.m00
00063             #approximation to area since cvMoments' area seem broken
00064             area = bounding_rect.width * bounding_rect.height
00065             if False:
00066                 #TODO NOT WORKING!!
00067                 if moments.m00 == 0.0:
00068                     centroid = (bounding_rect.x, bounding_rect.y)
00069                 else:
00070                     centroid = (moments.m10/moments.m00, moments.m01/moments.m00)
00071             else:
00072                 if bwidth > 0:
00073                     cx = bx + bwidth/2.
00074                 else:
00075                     cx = bx
00076     
00077                 if bheight > 0:
00078                     cy = by + bheight/2.
00079                 else:
00080                     cy = by
00081                 centroid = (cx, cy)
00082                 #if show: 
00083                 #    print 'areas is', area, bounding_rect.width, bounding_rect.height
00084                 if area > max_area or bounding_rect.width > max_dim or bounding_rect.height > max_dim:
00085                     cv.DrawContours(binary_image, contours, cv.Scalar(0), cv.Scalar(0), 0, cv.CV_FILLED) 
00086                 else:
00087                     stats = {'area': area, 'centroid': centroid, 'rect': bounding_rect}
00088                     statistics.append(stats)
00089                 contours = contours.h_next()
00090         except Exception, e:
00091             pass
00092             #This is due to OPENCV BUG and not being able to see inside contour object'
00093             break
00094     return statistics
00095 
00096 def draw_blobs(frame, blobs, classification_window_width):
00097     if frame.nChannels == 1:
00098         color = cv.Scalar(200)
00099     else:
00100         color = cv.Scalar(255, 0, 0)
00101 
00102     for b in blobs:
00103         rect = blob_to_rect(b, classification_window_width)
00104         if rect != None:
00105             cv.Rectangle(frame, rect.top_left(), rect.bottom_right(), color, 1)
00106 
00107 def blob_to_rect(blob, classification_window_width):
00108     x_center, y_center = blob['centroid']
00109     x_center           = int(x_center)
00110     y_center           = int(y_center)
00111     x_start            = x_center - classification_window_width
00112     y_start            = y_center - classification_window_width
00113     patch_size         = classification_window_width*2+1
00114     r                  = Rect(x_start, y_start, patch_size, patch_size).keep_inside(0, 639, 0,479) #TODO: remove this magic number
00115     if r.width < patch_size or r.height < patch_size:
00116         #print "classified_stream_to_classifier_matrix: not using connected comp", 
00117         #print blob['centroid'], 'w', r.width, 'h', r.height, 'preferred', patch_size
00118         return None
00119     else:
00120         return r
00121 
00122 def blob_to_input_instance(image, blob, classification_window_width):
00123     patch_size = classification_window_width*2+1
00124     small_r    = blob_to_rect(blob, classification_window_width=classification_window_width)
00125     big_r      = blob_to_rect(blob, classification_window_width=classification_window_width*2)
00126     if big_r == None or small_r == None:
00127         return None
00128     small_patch        = cv.CloneMat(cv.GetSubRect(image, small_r.as_cv_rect()))
00129     big_patch          = cv.CloneMat(cv.GetSubRect(image, big_r.as_cv_rect()))
00130     #cv.ShowImage('patch', small_patch)
00131     #cv.ShowImage('big_patch', big_patch)
00132     big_patch_rescaled = cv.CreateImage((int(classification_window_width/2), int(classification_window_width/2)), 8, 3)
00133     cv.Resize(big_patch, big_patch_rescaled, cv.CV_INTER_LINEAR );
00134 
00135     np_patch_small   = np.asarray(small_patch)
00136     np_patch_big     = ad.cv2array(big_patch_rescaled)
00137     np_resized_small = np.matrix(np_patch_small.reshape(patch_size*patch_size*3, 1))
00138     np_resized_big   = np.matrix(np_patch_big.reshape(np_patch_big.shape[0] * np_patch_big.shape[1] * 3, 1))
00139     return np.concatenate((np_resized_small, np_resized_big), axis=0)


hrl_opencv
Author(s): Hai Nguyen, Advait Jain (Healthcare Robotics Lab, Georgia Tech)
autogenerated on Wed Nov 27 2013 11:36:49