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


laser_interface
Author(s): Hai Nguyen and Travis Deyle. Advisor: Prof. Charlie Kemp, Lab: Healthcare Robotics Lab at Georgia Tech
autogenerated on Wed Nov 27 2013 11:45:51