00001
00002
00003
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):
00040 blob_statistics(binary_image, max_area, max_dim)
00041 return binary_image
00042
00043
00044
00045
00046 def blob_statistics(binary_image, max_area=99999.0, max_dim=99999.0):
00047 statistics = []
00048 storage = cv.CreateMemStorage(0)
00049
00050 contours = cv.FindContours(binary_image, storage, cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE, (0,0))
00051
00052
00053
00054
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
00063
00064 area = bounding_rect.width * bounding_rect.height
00065 if False:
00066
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
00083
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
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)
00115 if r.width < patch_size or r.height < patch_size:
00116
00117
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
00131
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)