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):
00036 blob_statistics(binary_image, max_area, max_dim)
00037 return binary_image
00038
00039
00040
00041
00042 def blob_statistics(binary_image, max_area=99999.0, max_dim=99999.0):
00043 statistics = []
00044 storage = cv.CreateMemStorage(0)
00045
00046 contours = cv.FindContours(binary_image, storage, cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE, (0,0))
00047
00048
00049
00050
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
00059
00060 area = bounding_rect.width * bounding_rect.height
00061 if False:
00062
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
00079
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
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)
00111 if r.width < patch_size or r.height < patch_size:
00112
00113
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
00127
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)