def GetIrisUsingThreshold(gray,pupil): tempResultImg = cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR) #used to draw temporary results props = RegionProps() val,binI =cv2.threshold(gray, 110, 255, cv2.THRESH_BINARY_INV) n=3 n2=3 ker=np.ones((n,n))/(n**2) ker2=np.ones((n2,n2))/(n2**2) temp1=cv2.dilate(binI, ker2) temp2=cv2.erode(binI, ker) temp3=cv2.add(temp1,temp2) temp4=cv2.add(temp2,temp1) temp5=cv2.add(temp3,temp4) temp6=cv2.add(temp4,temp3) binI=temp3 cv2.imshow("Threshold",binI) contours, hierarchy = cv2.findContours(binI, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) a=500.0 b=6000.0 c=0.30 glintElipseArray=[] for i in contours: vals = props.CalcContourProperties(i.astype('int'),['Area','Length','Centroid','Extend','ConvexHull']) if a<vals['Area'] and b>vals['Area']: if c<vals['Extend']: x,y=vals['Centroid'] cv2.circle(tempResultImg,(int(x),int(y)), 2, (0,255,0),4) #draw a circle if (len(i.astype(int))>=5): temp=cv2.fitEllipse(i.astype(int)) ax=int(temp[0][0]) bx=int(temp[0][1]) cx=int((temp[1][0]+temp[1][1])/4) glintElipseArray.append(cv2.fitEllipse(i.astype(int))) cv2.imshow("TempResults",tempResultImg) return glintElipseArray
def lipSegment(img): img = imutils.resize(img,width=300) img_copy = img.copy() landmarks = dlib_obj.get_landmarks(img) dlib_obj.get_face_mask(img_copy, landmarks) output_img = img-img_copy output_img = cv2.cvtColor(output_img,cv2.COLOR_BGR2GRAY) contours,hierarchy = cv2.findContours(output_img.copy(), cv2.cv.CV_RETR_EXTERNAL, cv2.cv.CV_CHAIN_APPROX_SIMPLE) #cv2.findContours(image, mode, method cv2.drawContours(img, contours, -1, (0,255,0), 2,maxLevel=0) cnt = contours[0] ellipse = cv2.fitEllipse(cnt) (x,y),(MA,ma),angle = cv2.fitEllipse(cnt) a = ma/2 b = MA/2 eccentricity = sqrt(pow(a,2)-pow(b,2)) eccentricity = round(eccentricity/a,2) font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText(img,'Eccentr= '+str(round(eccentricity,3)),(10,350), font, 1,(255,0,0),2,16) if(eccentricity < 0.9): cv2.putText(img,'Commands = O',(10,300), font, 1,(0,0,255),2,16) else: cv2.putText(img,'Commands = E',(10,300), font, 1,(0,0,255),2,16) return img
def trackRobot(self, imagePath): '''this function track the robot and return its coordinates''' img = cv2.imread(imagePath) img = cv2.flip(img, 1) img = cv2.flip(img, 0) # convert into hsv hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # Find mask that matches green_mask = cv2.inRange(hsv, np.array((50., 30., 0.)), np.array((100., 255., 255.))) green_mask = cv2.erode(green_mask, None, iterations=2) green_mask = cv2.dilate(green_mask, None, iterations=2) green_cnts = cv2.findContours(green_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] green_c = max(green_cnts, key=cv2.contourArea) # fit an ellipse and use its orientation to gain info about the robot green_ellipse = cv2.fitEllipse(green_c) # This is the position of the robot green_center = (int(green_ellipse[0][0]), int(green_ellipse[0][1])) red_mask = cv2.inRange(hsv, np.array((0., 100., 100.)), np.array((80., 255., 255.))) red_mask = cv2.erode(red_mask, None, iterations=2) red_mask = cv2.erode(red_mask, None, iterations=2) red_cnts = cv2.findContours(red_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] red_c = max(red_cnts, key=cv2.contourArea) red_ellipse = cv2.fitEllipse(red_c) red_center = (int(red_ellipse[0][0]), int(red_ellipse[0][1])) return green_center, red_center
def main(): print "\tSTARTING!!" # capture frames from the camera for frame in camera.capture_continuous(rawCapture, format="bgr",use_video_port=True): # grab the raw NumPy array representing the image, then initialize the timestamp # and occupied/unoccupied text img= frame.array img = imutils.resize(img, width = 200) img_copy = img.copy() cv2.imwrite('lip_reader2.jpg',img) landmarks = get_landmarks(img) get_face_mask(img_copy, landmarks) output_img = img-img_copy output_img = cv2.cvtColor(output_img,cv2.COLOR_BGR2GRAY) contours,hierarchy = cv2.findContours(output_img.copy(), cv2.cv.CV_RETR_EXTERNAL, cv2.cv.CV_CHAIN_APPROX_SIMPLE) #cv2.findContours(image, mode, method #cv2.drawContours(img, contours, -1, (0,255,0), 2,maxLevel=0) cnt = contours[0] ellipse = cv2.fitEllipse(cnt) (x,y),(MA,ma),angle = cv2.fitEllipse(cnt) cv2.ellipse(img,ellipse,(0,255,0),2) a = ma/2 b = MA/2 eccentricity = sqrt(pow(a,2)-pow(b,2)) eccentricity = round(eccentricity/a,2) font = cv2.FONT_HERSHEY_SIMPLEX #cv2.putText(img,'ma = '+str(round(ma,2)),(10,100), font, 1,(255,0,0),1,1) #cv2.putText(img,'MA = '+str(round(MA,2)),(10,150), font, 1,(255,0,0),1,1) cv2.putText(img,'Eccentricity = '+str(round(eccentricity,3)),(10,100), font, 1,(255,0,0),1,1) if(eccentricity < 0.84): print 'O' cv2.putText(img,'Commands = O',(10,150), font, 1,(0,0,255),1,1) else: print 'E' cv2.putText(img,'Commands = E',(10,150), font, 1,(0,0,255),1,1) #cv2.imwrite('output_e3.jpg',img) cv2.imshow('Mask',img_copy) cv2.imshow('Output', output_img) cv2.imshow('Img',img) # show the frame key = cv2.waitKey(1) & 0xFF # clear the stream in preparation for the next frame rawCapture.truncate(0) # if the `q` key was pressed, break from the loop if key == ord("q"): break# import the necessary packages
def find_single_bin(self, img, bin_type): """Find the bins and their orientations.""" assert bin_type in self.bins[bin_type], "Bins_2d does not know bin color: {}".format(bin_type) if img is not None: kernel = np.ones((2,2),np.float32)/4 img = cv2.filter2D(img,-1,kernel) debug_image = np.copy(img) img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) zeros = np.array([0]) ret,img = cv2.threshold(img,254,255,cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(np.copy(img), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) contours = contour_sort(contours) """This finds the bins and looks for the one that is orange or is not orange. Each bin is given an orangeness rating and either the most or least orange bin is selected. """ if len(contours) > 0: bins = 2 if (self.bin_type == 'orange'): orangeness = 0 else: orangeness = 100000 if len(contours) < bins: bins = len(contours) for i in range(0, bins+1): x, y, w, h = cv2.boundingRect(contours[i]) roi = debug_image[y: y + h, x: x + w] temp = evaluate_bin(roi) if ((orangeness > temp and self.bin_type == 'norange') or (orangeness < temp and self.bin_type == 'orange')): orangeness = temp M = cv2.moments(contours[i]) cx = int(M['m10'] / M['m00']) cy = int(M['m01'] / M['m00']) img_h, img_w, _ = np.shape(debug_image) point = (cx, cy) (_, _), (_, _), rad = cv2.fitEllipse(contours[i]) cv2.rectangle(debug_image, (x, y), (x + w, y + h), (127), 2) ellipse = cv2.fitEllipse(contours[i]) cv2.ellipse(debug_image, ellipse, (170), 2) if point != None: cv2.circle(debug_image, point, 5, (0, 0, 255), -1) pixels = np.copy(point) point = [cx - (img_w / 2), cy - (img_h / 2)] tuple_center = (point[0], point[1], 0) rad = ((rad) * np.pi) / 180.0 P = np.asarray(self.image_sub.camera_info.P).reshape(3,4) _P = np.linalg.pinv(P) pixels = np.asarray([pixels[0], pixels[1], 1]) ray = _P.dot(pixels) tuple_center = self.range*ray tuple_center[2] = -tuple_center[2]+0.45+1 #height of the bin and some buffer self.last_draw_image = debug_image print tuple_center return tuple_center, rad
def estimate_affine(src_mask, trg_mask, mode='rotation'): ''' Parameters: =========== mode: rotation, similarity, full ''' if int(cv2.__version__.split('.')[0]) == 3: _, src_cont, _ = cv2.findContours(src_mask.astype('uint8'), \ cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) _, trg_cont, _ = cv2.findContours(trg_mask.astype('uint8'), \ cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) else: src_cont, _ = cv2.findContours(src_mask.astype('uint8'), \ cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) trg_cont, _ = cv2.findContours(trg_mask.astype('uint8'), \ cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) src_ellipse = cv2.fitEllipse(src_cont[0]) trg_ellipse = cv2.fitEllipse(trg_cont[0]) rotation = (src_ellipse[2] - trg_ellipse[2]) / 180. * np.pi if mode == 'rotation': scale_x = scale_y = 1 elif mode == 'similarity': scale_x = scale_y = (trg_ellipse[1][0] / src_ellipse[1][0] \ + trg_ellipse[1][1] / src_ellipse[1][1]) / 2 elif mode == 'full': scale_x = trg_ellipse[1][0] / src_ellipse[1][0] scale_y = trg_ellipse[1][1] / src_ellipse[1][1] else: raise RuntimeError('mode %s not in ' \ '[\'rotation\', \'similarity\', \'full\']' % mode) shift_src = src_ellipse[0] shift_trg = trg_ellipse[0] # Compute transformation matrices alpha = np.cos(rotation) beta = np.sin(rotation) t0 = np.array([[+alpha, +beta, (1. - alpha) * shift_src[0] \ - beta * shift_src[1] \ + shift_trg[0] - shift_src[0]], \ [-beta, +alpha, beta * shift_src[0] \ + (1. - alpha) * shift_src[1] \ + shift_trg[1] - shift_src[1]]], 'float32') alpha = scale_x * np.cos(np.pi + rotation) beta = scale_y * np.sin(np.pi + rotation) t1 = np.array([[+alpha, +beta, (1. - alpha) * shift_src[0] \ - beta * shift_src[1] \ + shift_trg[0] - shift_src[0]], \ [-beta, +alpha, beta * shift_src[0] \ + (1. - alpha) * shift_src[1] \ + shift_trg[1] - shift_src[1]]], 'float32') return t0, t1
def color_contours(self, blob_img, contours): """ Return a colored image where the regions within certain the contours is colored in. :param blob_image: :return: """ labeled_img = np.zeros(blob_img.shape + (3, ), np.uint8) colors = ((0,0,255),(0,255,0),(255,0,0),(0,255,255),(255,0,255), (255, 255, 0)) pnts_list = [] mask_list = [] for ind, contour in enumerate(contours): mask = np.zeros(blob_img.shape, np.uint8) cv2.drawContours(mask, [contour], 0, 255, -1, 8) pixel_points = cv2.findNonZero(mask)#(x,y) labeled_img[mask == 255] = colors[ind] pnts_list.append(pixel_points) mask_list.append(mask) k = 0 angles = [] for cnt in contours: if len(cnt) < 10: #don't care about tiny contours # this should have already been protected for in the # large_contour code, but that is technically area angles.append(0) continue pixel_points = pnts_list[k] M = cv2.moments(cnt)#expects to get a contour - uses Green's theorem #center of blob cx = int(M['m10']/M['m00']) cy = int(M['m01']/M['m00']) #ellipsoid outline of blob ellipse = cv2.fitEllipse(cnt) (x, y), (MA, ma), angle = cv2.fitEllipse(pixel_points)#yet another way to get the angle angles.append(angle) #line fitting, THIS WAS SLOWING ME DOWN #DIST_L1 = 1: |x1-x2| + |y1-y2| */, DIST_L2 = 2: euclidean distance, DIST_C = : max(|x1-x2|,|y1-y2|) [vx, vy, x, y] = cv2.fitLine(pixel_points, 1, 0, 0.01, 0.01) pt1 = (np.array((x, y)) + 20*np.array((vx, vy))).astype('int32') pt2 = (np.array((x, y)) - 20*np.array((vx, vy))).astype('int32') cv2.line(labeled_img, tuple(pt1), tuple(pt2), (0, 128, 128), 2, 8) k += 1 return labeled_img, angles
def main(): while True: try: ret,img = cam.read() hand_track(img) if not ret: print "Error opening file" break img_copy = img.copy() landmarks = get_landmarks(img) get_face_mask(img_copy, landmarks) output_img = img-img_copy output_img = cv2.cvtColor(output_img,cv2.COLOR_BGR2GRAY) contours,hierarchy = cv2.findContours(output_img.copy(), cv2.cv.CV_RETR_EXTERNAL, cv2.cv.CV_CHAIN_APPROX_SIMPLE) #cv2.findContours(image, mode, method #cv2.drawContours(img, contours, -1, (0,255,0), 2,maxLevel=0) cnt = contours[0] ellipse = cv2.fitEllipse(cnt) (x,y),(MA,ma),angle = cv2.fitEllipse(cnt) cv2.ellipse(img,ellipse,(0,255,0),2) a = ma/2 b = MA/2 eccentricity = sqrt(pow(a,2)-pow(b,2)) eccentricity = round(eccentricity/a,2) font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText(img,'ma = '+str(round(ma,2)),(10,300), font, 1,(255,0,0),2,16) cv2.putText(img,'MA = '+str(round(MA,2)),(10,350), font, 1,(255,0,0),2,16) cv2.putText(img,'Eccentricity = '+str(round(eccentricity,3)),(10,400), font, 1,(255,0,0),2,16) if(eccentricity < 0.88): cv2.putText(img,'Commands = O',(10,450), font, 1,(0,0,255),2,16) else: cv2.putText(img,'Commands = E',(10,450), font, 1,(0,0,255),2,16) cv2.imshow('Mask',img_copy) cv2.imshow('Output', output_img) cv2.imshow('Img',img) if cv2.waitKey(20) & 0xFF == ord('q'): # To move frame by frame print "Pressed Q, quitting!!" break except ValueError as e: print e
def getLabelInfo(labels, label_find, k, map_M, r_wide, im, cen): posY = int(label_find[k][0].start) posX = int(label_find[k][1].start) cont = cv2.findContours(np.uint8(labels[0][label_find[k]]),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) # mom = cv2.moments(im) # hu = cv2.HuMoments(mom) blob = [] # Si obtuve un contorno válido if len(cont[1]) > 0 and len(cont[1][0]) > 4: peri = cv2.arcLength(cont[1][0],True) area = cv2.contourArea(cont[1][0]) eli = cv2.fitEllipse(cont[1][0]) eli_max = eli[1][1] eli_min = eli[1][0] posM = intT(transformPerspective(cen,map_M)) posYt = normalizeYt(r_wide, posM[1]) sqrtAr = np.sqrt(area) if sqrtAr > 0 and eli_max != 0: blob.append(sqrtAr / posYt) # sqrt(Area) / Y de centro transformado blob.append(sqrtAr / peri) # Perimetro / sqrt (Area) blob.append(eli_min / eli_max) # Dimension de elipse # for i in range(0,7): # blob.append(hu[i][0]) return blob
def GetPupil(gray,thr): tempResultImg = cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR) #used to draw temporary results props = RegionProps() val,binI = cv2.threshold(gray, thr, 255, cv2.THRESH_BINARY_INV) #Combining Closing and Opening to the thresholded image st7 = cv2.getStructuringElement(cv2.MORPH_CROSS,(7,7)) st9 = cv2.getStructuringElement(cv2.MORPH_CROSS,(9,9)) st15 = cv2.getStructuringElement(cv2.MORPH_CROSS,(15,15)) binI = cv2.morphologyEx(binI, cv2.MORPH_CLOSE, st9) #Close binI= cv2.morphologyEx(binI, cv2.MORPH_OPEN, st15) #Open binI = cv2.morphologyEx(binI, cv2.MORPH_DILATE, st7, iterations=2) #Dialite cv2.imshow("ThresholdPupil",binI) #Calculate blobs sliderVals = getSliderVals() #Getting slider values contours, hierarchy = cv2.findContours(binI, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) #Finding contours/candidates for pupil blob pupils = [] pupilEllipses = [] for cnt in contours: values = props.CalcContourProperties(cnt,['Area','Length','Centroid','Extend','ConvexHull']) #BUG - Add cnt.astype('int') in Windows if values['Area'] < sliderVals['maxSizePupil'] and values['Area'] > sliderVals['minSizePupil'] and values['Extend'] < 0.9: pupils.append(values) centroid = (int(values['Centroid'][0]),int(values['Centroid'][1])) cv2.circle(tempResultImg,centroid, 2, (0,0,255),4) pupilEllipses.append(cv2.fitEllipse(cnt)) cv2.imshow("TempResults",tempResultImg) return pupilEllipses
def process_image(args, path): global intersects, rotation, img, img_src, center img = cv2.imread(path) if img == None or img.size == 0: logging.info("Failed to read %s" % path) return logging.info("Processing %s..." % path) # Scale the image down if its perimeter exceeds the maximum (if set). img = common.scale_max_perimeter(img, args.max_size) img_src = img.copy() # Perform segmentation logging.info("- Segmenting...") mask = common.grabcut(img, args.iters, None, args.margin) bin_mask = np.where((mask == cv2.GC_FGD) + (mask == cv2.GC_PR_FGD), 255, 0).astype("uint8") # Obtain contours (all points) from the mask. contour = ft.get_largest_contour(bin_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) # Fit an ellipse on the contour to get the rotation angle. box = cv2.fitEllipse(contour) rotation = int(box[2]) # Get the shape360 feature. logging.info("- Obtaining shape...") intersects, center = ft.shape_360(contour, rotation) logging.info("- Done") draw_axis()
def getDarkEllipse(self,img): #if not self.isFid: # #cv2.imwrite(self.name + "_" + "%.2d" % imageNum + "_raw.png" , img) try: smoothedImg = cv2.GaussianBlur(img,(self.blurSize,self.blurSize),0) #if not self.isFid: # #cv2.imwrite(self.name + "_" + "%.2d" % imageNum + "_smoothed.png" , img) except: print 'cv2.GaussianBlur failed' # cv2.imwrite('temp.png',img) return None try: dataMin = scipy.ndimage.filters.minimum_filter(smoothedImg, self.filterSize) except: print 'scipy.ndimage.filters.minimum_filter failed' # cv2.imwrite('temp.png',img) return None if dataMin!=None: try: minLocs = numpy.where(dataMin<(numpy.min(dataMin)+numpy.std(dataMin))) except: print 'numpy.where failed' # cv2.imwrite('temp.png',img) return None if len(minLocs[0])>=5: try: ellipse = cv2.fitEllipse(numpy.reshape(numpy.column_stack((minLocs[1],minLocs[0])),(len(minLocs[0]),1,2))) except: print 'cv2.fitEllipse failed' # cv2.imwrite('temp.png',img) return None return ellipse
def GetGlints(gray,thr): tempResultImg = cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR) #used to draw temporary results props = RegionProps() val,binI = cv2.threshold(gray, thr, 255, cv2.THRESH_BINARY) #Using non inverted binary image #Combining opening and dialiting seems to be the best but is it ok that other glints are visible two?????!!!!! st7 = cv2.getStructuringElement(cv2.MORPH_CROSS,(7,7)) st9 = cv2.getStructuringElement(cv2.MORPH_CROSS,(7,7)) binI= cv2.morphologyEx(binI, cv2.MORPH_OPEN, st7) binI = cv2.morphologyEx(binI, cv2.MORPH_DILATE, st9, iterations=2) cv2.imshow("ThresholdGlints",binI) #Calculate blobs sliderVals = getSliderVals() #Getting slider values contours, hierarchy = cv2.findContours(binI, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) #Finding contours/candidates for pupil blob glints = [] glintEllipses = [] for cnt in contours: values = props.CalcContourProperties(cnt,['Area','Length','Centroid','Extend','ConvexHull']) #BUG - Add cnt.astype('int') in Windows if values['Area'] < sliderVals['maxSizeGlints'] and values['Area'] > sliderVals['minSizeGlints']: glints.append(values) centroid = (int(values['Centroid'][0]),int(values['Centroid'][1])) cv2.circle(tempResultImg,centroid, 2, (0,0,255),4) glintEllipses.append(cv2.fitEllipse(cnt)) cv2.imshow("TempResults",tempResultImg) return glintEllipses
def processEye(eyesubrect, vis_roi, gray_roi, vis, gray): """threshold get contours find largest fit ellipse """ # apply threshold thresh = gray_roi.copy() #cv2.adaptiveThreshold(leftthresh, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 25, 25, leftthresh) thresh = thresholdByPercentage(thresh, .075) # find contours from thresholded img contours, heirarchy = cv2.findContours(thresh.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) maxarea = 0 maxidx = 0 # find contour with largest area for idx in range(len(contours)): a = cv2.contourArea(contours[idx]) if maxarea < a: maxarea = a maxidx = idx cv2.drawContours(vis_roi, contours, maxidx, (0,0,255), -1) # fit ellipse to the detected contour ellipseBox = cv2.fitEllipse(contours[maxidx]) cv2.ellipse(vis_roi, ellipseBox, (50, 150, 255)) return thresh, ellipseBox
def getContours(img, fit_type='ellipse', AREA_EXCLUSION_LIMITS=(200, 2000), CELL_RADIUS_THRESHOLD = 4): contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) coord_list = [] for i in range(len(contours)): if fit_type == 'circle': radius_list = [] center_list = [] (x,y),radius = cv2.minEnclosingCircle(contours[i]) if radius > CELL_RADIUS_THRESHOLD: center = (int(x), int(y)) center_list.append(center) radius_list.append(radius) cv2.circle(img,center,int(radius),(0,255,0),-11) coord_list.append([center_list, radius_list]) elif fit_type == 'ellipse': if len(contours[i]) >= 5: ellipse = cv2.fitEllipse(contours[i]) area = np.pi*np.product(ellipse[1]) if area >= AREA_EXCLUSION_LIMITS[0] and area < AREA_EXCLUSION_LIMITS[1]: cv2.ellipse(img,ellipse,(0,255,0),-1) return img, contours, coord_list
def GetGlints(gray, thr, areaMin, areaMax): props = RegionProps() gray = cv2.GaussianBlur(gray, (11, 11), 0) val,binI = cv2.threshold(gray, thr, 255, cv2.THRESH_BINARY) cv2.imshow("Threshold Glint",binI) #cv2.imshow("Gray", gray) #Calculate blobs contours, hierarchy = cv2.findContours(binI, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) glints = []; for c in contours: tmp = props.CalcContourProperties(c, properties=["centroid", "area", "extend"]) area = tmp['Area'] extend = tmp['Extend'] #print tmp['Area'] if area > areaMin and area < areaMax and extend < 1: if len(c) >= 5: el = cv2.fitEllipse(c) glints.append(el) #canny = cv2.Canny(tempResultImg, 30, 150) #cv2.imshow("Canny", canny) #x, y = tmp['Centroid'] #cv2.circle(tempResultImg,(int(x), int(y)), 2, (0,0,255),4) #cv2.ellipse(tempResultImg,el,(0,255,0),1) #cv2.imshow("Glint detect", tempResultImg) return glints
def isEllipse(contour): rect = cv2.fitEllipse(contour) # Rotated rectangle representing the ellipse it tries to fit (x, y), (w, h), angle = rect # x offset, y offset, width, height, angle w, h = h, w # Switch them since our ellipses are usually rotated 90 degrees # Draw TEST_INSIDE points inside the ellipse and TEST_OUTSIDE points outside and see if they're in the hull TEST_INSIDE = 10 TEST_OUTSIDE = 10 # Equation of ellipse: (x/a)^2 + (y/b)^2 = 1 e = 0.1 tests = [] tests.append(cv2.pointPolygonTest(contour, (x, y), False)) tests.append(cv2.pointPolygonTest(contour, (x+w*(0.5-e), y), False)) tests.append(cv2.pointPolygonTest(contour, (x-w*(0.5-e), y), False)) tests.append(cv2.pointPolygonTest(contour, (x, y+h*(0.5-e)), False)) tests.append(cv2.pointPolygonTest(contour, (x, y-h*(0.5-e)), False)) tests.append(not cv2.pointPolygonTest(contour, (x+w*(0.5-e), y+h*(0.5-e)), False)) tests.append(not cv2.pointPolygonTest(contour, (x+w*(0.5-e), y-h*(0.5-e)), False)) tests.append(not cv2.pointPolygonTest(contour, (x-w*(0.5-e), y+h*(0.5-e)), False)) tests.append(not cv2.pointPolygonTest(contour, (x-w*(0.5-e), y-h*(0.5-e)), False)) for test in tests: if test == -1.0: return False return True
def find_ellipses(source_image, canny_image, min_points=5, \ axes_ratio=1.5, minor_axes_ratio=25, major_axes_ratio=15): # declaring variables i = 0 height, width, channels = source_image.shape ellipse_list = [] # find all the contours contours, hierarchy = cv2.findContours(canny_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) number_of_contours = len(contours) # finding and filtering ellipses while i < number_of_contours: if len(contours[i]) >= min_points: ellipse = cv2.fitEllipse(contours[i]) (x, y), (minor_axis, major_axis), angle = ellipse if minor_axis != 0 and major_axis != 0 and major_axis / minor_axis <= axes_ratio: ellipse_min_ratio = width / minor_axis ellipse_maj_ratio = height / major_axis if minor_axes_ratio >= ellipse_min_ratio >= 1.5 and major_axes_ratio >= ellipse_maj_ratio >= 1.5: ellipse_list.append(ellipse) i += 1 return ellipse_list
def _get_poly_8(self, contour): """ellipse format: ((x,y),(s,l),0)""" plots = [] epsilon = 100 def dynamic_approx_poly(epsilon): for i in range(20): poly_points = cv2.approxPolyDP(contour, epsilon=epsilon, closed=True) if len(poly_points) == self.poly_number: return poly_points elif len(poly_points) > self.poly_number: epsilon += 50 else: epsilon -= 50 return poly_points poly_points = dynamic_approx_poly(epsilon) if len(poly_points) < 5: raise PolyPointsError("poly point not enough") ellipse = cv2.fitEllipse(poly_points) for n, i in enumerate(poly_points): x, y = i[0] plot_arg = ((x, y), 20, (255, 255, 255)) plot_kwarg = {"lineType": 10} plot = ("circle", plot_arg, plot_kwarg) plots.append(plot) plot_arg = ((x, y), 5, (255, 255, 255), -1) plot_kwarg = {"lineType": 10} plot = ("circle", plot_arg, plot_kwarg) plots.append(plot) return ellipse, plots
def run(self, img, blurindex=False): u"""主要的执行函数: 1、滤波 2、提取轮廓 3、合并轮廓 4、椭圆拟合 5、计算结果 :param img: :param blurindex: :return: """ # blurindex = SETTING()["medianBlur"].get("corefilter", 3) # raise ValueError("abc") if blurindex: img = cv2.medianBlur(img, blurindex) # cv2.imshow("img", img[::4, ::4]) # cv2.waitKey() contours, hierarchys = cv2.findContours(img.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) # tempPlots = np.ones(img.shape) * 255 logger.info('get contours len %s' % len(contours)) if len(contours) == 0: raise NoneContoursError("contours = 0") elif len(contours) == 1: mergedpoints = contours[0] else: mergedpoints = np.concatenate(contours[1:]) ellipse = cv2.fitEllipse(mergedpoints) result = self._getResult(ellipse) result['ellipese'] = ellipse # cv2.ellipse(tempPlots, ellipse, (0,255,255)) # result['plot'] = tempPlots result['contour'] = mergedpoints return result
def ransac(self, ntrials, contour, small_gray, draw): # RANSAC implementation starts r2centerx = [] r2centery = [] r2majrad = [] r2minrad = [] r2angle = [] for i in range(ntrials): if len(contour) > 60: # embed() samples = contour[np.random.choice(len(contour), int(len(contour) / 10))] ellipse = cv2.fitEllipse(samples) if draw: cv2.ellipse(small_gray, ellipse, (0, 0, 255), 2) r2centerx.append(ellipse[0][0]) r2centery.append(ellipse[0][1]) r2majrad.append(ellipse[1][1]) r2minrad.append(ellipse[1][0]) r2angle.append(ellipse[2]) else: r2centerx.append(100 * (i % 2)) r2centery.append(100 * (i % 2)) r2majrad.append(100 * (i % 2)) r2minrad.append(100 * (i % 2)) r2angle.append(100 * (i % 2)) r2centerx = np.asarray(r2centerx) r2centery = np.asarray(r2centery) r2majrad = np.asarray(r2majrad) r2minrad = np.asarray(r2minrad) r2angle = np.asarray(r2angle) return r2centerx, r2centery, r2majrad, r2minrad, r2angle, small_gray
def detectCircles(): im = cv2.imread('oldImage.jpg') imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) imgray_Blur = cv2.GaussianBlur(imgray, (15,15), 0) thresh = cv2.adaptiveThreshold(imgray_Blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 1) kernel = np.ones((3,3), np.uint8) closing = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations = 4) cont_img = closing.copy() #ret, thresh = cv2.threshold(imgray, 127, 255, 0 contours, hierarcy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: area = cv2.contourArea(cnt) '''if area < 2000 or area > 4000: continue if len(cnt) < 5: continue ''' ellipse = cv2.fitEllipse(cnt) #returns array [(centerx, centery), (radiusx, radiusy), rotation] #cv2.ellipse(im, ellipse, (0,0,255), 2) centerx = ellipse[0][0] centery = ellipse[0][1] radiusx = ellipse[1][0] radiusy = ellipse[1][1] rotation = ellipse[2] print "Ellipse " print centerx, centery, radiusx, radiusy, rotation
def drawStuff(centerCordinates, image): # http://opencvpython.blogspot.no/2012/06/contours-2-brotherhood.html # http://docs.opencv.org/3.1.0/dd/d49/tutorial_py_contour_features.html#gsc.tab=0pyth ############## creating a minimum rectangle around the object ###################### rect = cv2.minAreaRect(points=centerCordinates) box = cv2.cv.BoxPoints(rect) box = np.int0(box) cv2.drawContours(image,[box],0,(255,255,255),2) ########### circle around object #######3 (x, y),radius = cv2.minEnclosingCircle(centerCordinates) center = (int(x),int(y)) radius = int(radius) cv2.circle(image, center, radius, (255,255,255),2) ########### finding a elipse ############## ellipse = cv2.fitEllipse(centerCordinates) cv2.ellipse(image,ellipse,(255,255,255),2) ##### fitting a line ########### rows,cols = image.shape[:2] [vx,vy,x,y] = cv2.fitLine(points=centerCordinates, distType=cv2.cv.CV_DIST_L2, param =0, reps=0.01, aeps=0.01) lefty = int((-x*vy/vx) + y) righty = int(((cols-x)*vy/vx)+y) cv2.line(image,(cols-1,righty),(0,lefty),(255,255,255),2) pixelSizeOfObject = radius # an okay estimate for testing return image, pixelSizeOfObject
def GetGlints(gray,thr,minS,maxS): ''' Given a gray level image, gray and threshold value return a list of glint locations''' # YOUR IMPLEMENTATION HERE !!!! tempResultImg = cv2.cvtColor(gray,cv2.COLOR_GRAY2BGR) #used to draw temporary results #cv2.circle(tempResultImg,(100,200), 2, (0,0,255),4) #draw a circle #cv2.imshow("TempResults",tempResultImg) props = RegionProps() val,binI =cv2.threshold(gray, thr, 255, cv2.THRESH_BINARY) cv2.imshow("ThresholdInverse",binI) #Calculate blobs _, contours, hierarchy= cv2.findContours(binI, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) glints = []; glintEllipses = []; Centroids = []; # YOUR IMPLEMENTATION HERE !!!! #CalcContourProperties for cnt in contours: vals = props.CalcContourProperties(cnt,['Area','Length','Centroid','Extend','ConvexHull']) if vals['Area']> minS and vals['Area']< maxS: if vals['Extend'] < 1: glints.append(cnt) #print vals['Centroid'] #cv2.circle(tempResultImg,(int(vals['Centroid'][0]),int(vals['Centroid'][1])), 2, (255,0,0),-1) #draw a circle Centroids.append(vals['Centroid']) glintEllipse = cv2.fitEllipse(cnt) glintEllipses.append(glintEllipse) #cv2.ellipse(tempResultImg,ellipse,(0,255,0),2) #cv2.imshow("TempResultsglint",tempResultImg) return (glints,glintEllipses,Centroids)
def main(): np_img = cv2.imread('8.bmp', 0) blur = cv2.GaussianBlur(np_img,(5,5),0) ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) kernel = np.ones((3, 3), np.uint8) closing = cv2.morphologyEx(th3, cv2.MORPH_CLOSE, kernel, iterations=4) cont_img = closing.copy() contours, hierarchy = cv2.findContours(cont_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: area = cv2.contourArea(cnt) if area < 200 or area > 8000: continue if len(cnt) < 5: continue ellipse = cv2.fitEllipse(cnt) cv2.ellipse(np_img, ellipse, (155,155,0), 2) while True: cv2.imshow('final result', np_img) if cv2.waitKey(1) & 0xFF == ord('q'): break
def find_blob(im): im[:30, :] = 0 im[-30:, :] = 0 im[:, :10] = 0 im[:, -10:] = 0 # thresh, im_bw = cv2.threshold(im, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) # print thresh thresh, im_bw = cv2.threshold(im, 100, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(im_bw.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) # moments = [cv2.moments(i).nu20 for i in contours] # all_bbox = [cv2.boundingRect(i) for i in contours] all_area = np.array([cv2.contourArea(c) for c in contours]) # all_aspect_ratio = np.array([float(b[2]) / b[3] for b in all_bbox]) print all_area big_indices = np.nonzero(all_area > config.AREA_THRESH)[0] print big_indices ellipses = [cv2.fitEllipse(contours[i]) for i in big_indices] color = [0, 255, 0] im_rgb = cv2.cvtColor(im_bw, cv2.COLOR_GRAY2RGB) for ell in ellipses: center, dimension, angle = ell h, w = dimension print h, w cv2.ellipse(im_rgb, ell, color, 2, 8) cv2.namedWindow('threshold') cv2.moveWindow('threshold', 800, 100) cv2.imshow('threshold', im_rgb) cv2.waitKey() cv2.destroyAllWindows()
def FitEllipse_LeastSquares(pnts, roi, cfg): """ Simple least-squares ellipse fit to boundary points Parameters ---- pnts : n x 2 array of integers Candidate pupil-iris boundary points from edge detection roi : 2D scalar array Grayscale image of pupil-iris region for display only cfg : configuration structure Configuration parameters Returns ---- best_ellipse : tuple of tuples Best fitted ellipse parameters ((x0, y0), (a,b), theta) """ # Tiny circle init best_ellipse = ((0, 0), (1e-6, 1e-6), 0) # Break if too few points to fit ellipse (RARE) if pnts.shape[0] < 5: return best_ellipse # Call OpenCV ellipse fitting best_ellipse = cv2.fitEllipse(pnts) return best_ellipse
def fit_ellipses(img): import cv2 img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) img = cv2.medianBlur(img, 5) #ret, thresh = cv2.threshold(img, 169, 255, 0) thresh = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) contours, hierarchy = cv2.findContours(thresh, 1, 2) #print contours cntLengths = [len(i) for i in contours] cntMax = cntLengths.index(max(cntLengths)) for i in range(len(contours)): if 10 < len(contours[i]) < 1500: cnt = contours[i] M = cv2.moments(cnt) #print M cx = int(M['m10']/M['m00']) cy = int(M['m01']/M['m00']) print "cx: ", cx print "cy: ", cy ellipse = cv2.fitEllipse(cnt) cv2.ellipse(img, ellipse, (0, 255, 0), 2) cv2.imshow('img', img) cv2.waitKey() cv2.destroyAllWindows()
def isEllipse(contour): ''' Detects if the given polygon is an ellipse. Returns the ellipse form of the polygon if it's an ellipse, None otherwise. ''' try: rect = cv2.fitEllipse(contour) # Rotated rectangle representing the ellipse it tries to fit except: return None (x, y), (w, h), angle = rect # x offset, y offset, width, height, angle w, h = h, w # Switch them since our ellipses are usually rotated 90 degrees TEST_POINTS = 16 E = 0.1 # Radius percentage increase/decrease for test points MIN_SUCC_RATE = 0.9 successes = 0 for a in np.arange(0, 2*math.pi, 2*math.pi/TEST_POINTS): ipoint = (x+0.5*w*math.cos(a)*(1-E), y+0.5*h*math.sin(a)*(1-E)) opoint = (x+0.5*w*math.cos(a)*(1+E), y+0.5*h*math.sin(a)*(1+E)) test = cv2.pointPolygonTest(contour, ipoint, False) if cv2.pointPolygonTest(contour, ipoint, False) > 0: # The inside point is inside successes += 1 if cv2.pointPolygonTest(contour, opoint, False) < 0: # The outside point is outside successes += 1 succ_rate = successes / (TEST_POINTS * 2) if succ_rate >= MIN_SUCC_RATE: return rect else: return None
def process(self, annotator, iohelper): img = cv2.imread(iohelper.thumbnail()) image = img.copy() # Preprocessing like gray-scaling, thresholding, closing gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray_blur = cv2.GaussianBlur(gray, (9, 9), 0) thresh = cv2.adaptiveThreshold(gray_blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 31, 11) kernel = np.ones((3, 3), np.uint8) closing = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2) # Contour detection cont_img = closing.copy() if int(cv2.__version__[0]) < 3: contours, _ = cv2.findContours(\ cont_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) else: _, contours, _ = cv2.findContours(\ cont_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Draw rectangles and add found bug to annotator. i = 0 for cnt in contours: area = cv2.contourArea(cnt) ellipse = cv2.fitEllipse(cnt) center, axes, angle = ellipse rect_area = axes[0] * axes[1] rect = np.round(np.float64(cv2.cv.BoxPoints(ellipse))).astype(np.int64) annotator.add_bug(*rect) color = (255,0,0) cv2.drawContours(image, [rect], 0, color, 1) i = (i + 30) % 255 return image
import sys import numpy as np import cv2 as cv hsv_min = np.array((0, 77, 17), np.uint8) hsv_max = np.array((208, 255, 255), np.uint8) if __name__ == '__main__': fn = 'donuts.jpg' img = cv.imread(fn) hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV) thresh = cv.inRange(hsv, hsv_min, hsv_max) contours0, hierarchy = cv.findContours(thresh.copy(), cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE) for cnt in contours0: if len(cnt) > 6: ellipse = cv.fitEllipse(cnt) cv.ellipse(img, ellipse, (0, 0, 255), 2) cv.imshow('contours', img) cv.waitKey() cv.destroyAllWindows()
def predictCentroids(frame, radius, model, nFlies=2, bkg=None, dumpDir=None): # pass frame through - network depends on the arena # do some bluring and return potential bounding boxes # use opencv to clear circle of frame, either before or after passing through network? # then blur # should we subtract a background? try: if dumpDir == '': dumpDir = None if bkg is None: bkg = np.zeros(frame.shape) # print('aha') # frame = frame[:,:,2::-1] # print(frame.shape) frame = (1 - np.expand_dims(frame[:, :, :, 1], axis=-1)) * 255 # print('aww') # print(frame.shape) # print(frame.shape) prediction = model.predict(frame) # print('?') if dumpDir is not None: cv2.imwrite(dumpDir + 'frame.png', frame[0, :, :, 0]) cv2.imwrite(dumpDir + 'pred.png', np.uint8((prediction[0, :, :, 0]) * 255 * 1)) cv2.imwrite(dumpDir + 'raw.png', np.uint8((prediction[0, :, :, 0] - bkg) * 255 * 1)) cv2.imwrite(dumpDir + 'pos.png', (prediction[0, :, :, 0] - bkg > 0.05) * 255) cv2.imwrite(dumpDir + 'neg.png', (prediction[0, :, :, 0] - bkg < 0) * 255) pred_orig = prediction[0, :, :, 0] prediction = prediction[0, :, :, 0] - bkg prediction[prediction < 0] = 0 # sio.savemat('pred.mat',{'pred':prediction,'pred0':pred_orig,'bkg':bkg,'frame':frame}) mask = np.zeros(prediction.shape, np.uint8) # print(prediction.shape) # print(radius) cv2.circle( mask, (int(prediction.shape[0] / 2), int(prediction.shape[1] / 2)), int(radius), 255, -1) prediction[mask != 255] = 0 prediction = cv2.GaussianBlur(np.uint8(prediction * 255 * 6), (11, 11), 5) # print(np.max(prediction)) prediction = (prediction > 30) * 255 # prediction = (prediction > 60)*255 # cv2.imwrite('pred_.jpg',np.uint8(prediction)) prediction = cv2.blur(prediction, (3, 3)) prediction = cv2.blur(prediction, (3, 3)) prediction = cv2.blur(prediction, (3, 3)) if dumpDir is not None: cv2.imwrite(dumpDir + 'pred_.jpg', np.uint8(prediction * 255 * 10)) # prediction = (prediction > 150)*255 # now do some denoising (k-means) contours = getFlyContours(np.uint8(prediction), nFlies) markers = np.zeros((prediction.shape[0], prediction.shape[1], 1), np.int32) for cntInd, cnt in enumerate(contours): cv2.drawContours(markers, contours, cntInd, cntInd + 1, -1) fgObjects = np.zeros(prediction.shape, np.uint8) fgObjects[np.logical_and(markers[:, :, 0] > 0, prediction > 0)] = prediction[np.logical_and( markers[:, :, 0] > 0, prediction > 0)] kernel2 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)) cv2.erode(fgObjects, kernel2, fgObjects) pts = np.vstack(np.nonzero(fgObjects)).astype(np.float32).T pts = pts[:, 0:2] numK = nFlies term_crit = (cv2.TERM_CRITERIA_EPS, 30, 0.1) bestLabelsKM = np.zeros(len(pts)) compactness, bestLabelsKM, centers = cv2.kmeans( pts, numK, bestLabelsKM, term_crit, 10, cv2.KMEANS_PP_CENTERS) bodyEllipses = np.zeros((2, 5), np.float16) allRedLines = np.zeros((2, 4), np.float16) ind = bestLabelsKM == 0 ptsBody = np.vstack((pts[ind[:, 0], 0], pts[ind[:, 0], 1])).T flyEllipse = cv2.fitEllipse(ptsBody[:, ::-1]) bodyEllipses[0] = ellipseListToArray(flyEllipse) thisLine = cv2.fitLine(ptsBody, cv2.DIST_L2, 0, 0.01, 0.01) allRedLines[0] = np.squeeze(thisLine) ind = bestLabelsKM == 1 ptsBody = np.vstack((pts[ind[:, 0], 0], pts[ind[:, 0], 1])).T flyEllipse = cv2.fitEllipse(ptsBody[:, ::-1]) bodyEllipses[1] = ellipseListToArray(flyEllipse) thisLine = cv2.fitLine(ptsBody, cv2.DIST_L2, 0, 0.01, 0.01) allRedLines[1] = np.squeeze(thisLine) if dumpDir is not None: tmp = np.zeros((prediction.shape[0], prediction.shape[1], 3)) ind = bestLabelsKM == 0 pts2 = np.vstack((pts[ind[:, 0], 0], pts[ind[:, 0], 1])).T for (x, y) in pts2: tmp[int(x), int(y), 0] = 255 ind = bestLabelsKM == 1 pts2 = np.vstack((pts[ind[:, 0], 0], pts[ind[:, 0], 1])).T for (x, y) in pts2: tmp[int(x), int(y), 1] = 255 ind = bestLabelsKM >= 2 pts2 = np.vstack((pts[ind[:, 0], 0], pts[ind[:, 0], 1])).T for (x, y) in pts2: tmp[int(x), int(y), 2] = 255 cv2.imwrite(dumpDir + 'kMeans_' + str(numK) + '.jpg', tmp) return prediction, centers, bodyEllipses, allRedLines except: return None, np.zeros((nFlies, 2)), np.zeros((nFlies, 5)), np.zeros( (nFlies, 4))
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) # Apply KMeans compactness, labels, centers = cv2.kmeans(hist, 2, None, criteria, 100, cv2.KMEANS_RANDOM_CENTERS) print(np.sqrt(compactness) / 10) print(centers) # center = pbcvt.findPupil(roi_gray, int(ex), int(ey), int(ew), int(eh)) ret, thresh = cv2.threshold(eye_roi_gray, centers[0] - 10, 255, 0) # thresh = cv2.adaptiveThreshold(eye_roi_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 0) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # cv2.drawContours(eye_roi_color, contours, -1, (0,0,255), 3) for cont in contours: if len(cont) > 5 and cv2.contourArea(cont) > 1000: ellipse = cv2.fitEllipse(cont) cv2.ellipse(eye_roi_color, ellipse, (0, 0, 255), 2) cv2.circle(eye_roi_color, (int(ellipse[0][0]), int(ellipse[0][1])), 2, (255, 0, 0), 3) # cv2.circle(eye_roi_color, center, 2, (0,255,0), 3) # else: # face = None cv2.imshow("preview", roi_gray) cv2.imshow("preview2", equalized) cv2.imshow("preview3", thresh) # if vout: # vout.write(frame) nf = nf + 1
def divide_shelter_once(self, im, filename, pred, pred_pro, gt_ellip, if_valid=False, is_save=True): ''' divide the shelter and not shelter ''' pts = [] ''' _, p, hierarchy = cv2.findContours(pred, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #tmp draw contours sz = im.shape c_im_show = np.zeros((sz[0], sz[1], 3)) cv2.drawContours(c_im_show, p, -1, (0, 255, 0), 1) for i in range(len(p)): for j in range(len(p[i])): pts.append(p[i][j]) ''' sz = im.shape im = cv2.cvtColor(im, cv2.COLOR_RGB2BGR) #tmp fn = filename.strip().decode('utf-8') fn_full = '%s%s%s.bmp' % ('s8', 'img', fn.split('img')[1]) fn_full_path = os.path.join(cfgs.full_im_path, fn_full) im_full = cv2.imread(fn_full_path) im = cv2.resize(im_full, (sz[1], sz[0]), interpolation=cv2.INTER_CUBIC) pred = remove_small_area(pred) for ii in range(sz[0]): for jj in range(sz[1]): #if pred[ii][jj] > 0: if pred[ii][jj] == 2: pts.append([jj, ii]) #im[ii][jj] = 255 pts_ = np.array(pts) if pts_.shape[0] > 5: ellipse_info = cv2.fitEllipse(pts_) ellipse_info_ = ellipse_info #pred_ellip = np.array([ellipse_info[0][0], ellipse_info[0][1], ellipse_info[1][0], ellipse_info[1][1]]) if ellipse_info[2] > 150 or ellipse_info[2] < 30: angle = 180 pred_ellip = np.array([ ellipse_info[0][0], ellipse_info[0][1], ellipse_info[1][0], ellipse_info[1][1] ]) else: angle = 90 pred_ellip = np.array([ ellipse_info[0][0], ellipse_info[0][1], ellipse_info[1][1], ellipse_info[1][0] ]) ellipse_info = (tuple( np.array([ ellipse_info[0][0], ellipse_info[0][1] ])), tuple(np.array([ellipse_info[1][0], ellipse_info[1][1]])), angle) loss = 1 else: pred_ellip = np.array([0, 0, 0, 0]) ellipse_info = (tuple(np.array([0, 0])), tuple(np.array([0, 0])), 0) loss = 1 if is_save: ''' fn = filename.strip().decode('utf-8') fn_full = '%s%s.bmp' % ('img', fn.split('img')[1]) im_full = cv2.imread(os.path.join(cfgs.full_im_path, fn_full)) im = cv2.resize(im_full, (sz[1], sz[0]), interpolation=cv2.INTER_CUBIC) ''' #save worse result error_path = cfgs.error_path #im = cv2.cvtColor(im, cv2.COLOR_RGB2BGR) cv2.ellipse(im, ellipse_info, (0, 255, 0), 1) new_line = '%s %d %d %d %d %d\n' % ( fn_full_path, ellipse_info[0][0], ellipse_info[0][1], ellipse_info[1][0], ellipse_info[1][1], 0) with open(cfgs.list_save_path, 'a') as correct_txt: correct_txt.write(new_line) ''' part_label=ellipse_my(ellipse_info) c_x=ellipse_info[0][0] c_y=ellipse_info[0][1] for i in range(len(part_label)): x=int(part_label[i][1]) y=int(part_label[i][0]) if y<len(im) and x<len(im[0]): im[y][x][0]=0 im[y][x][1]=255 im[y][x][2]=0 p_i_x,p_i_y,p_o_x,p_o_y=get_nine_half(c_x,c_y,x,y) #p_i_y,p_i_x,p_o_y,p_o_x=get_nine_half(c_x,c_y,x,y) cv2.line(im,(p_i_x,p_i_y),(p_o_x,p_o_y),(0,255,0),1) ''' if loss > cfgs.loss_thresh: if loss > 500: loss = 500 path_ = os.path.join( error_path, filename.strip().decode('utf-8') + '_' + str(int(loss)) + '.bmp') cv2.imwrite(path_, im) else: path_ = os.path.join( error_path + '_better', filename.strip().decode('utf-8') + '_' + str(int(loss)) + '.bmp') cv2.imwrite(path_, im) return loss
def detect(self, frame, user_roi, visualize=False): u_r = user_roi if self.window_should_open: self.open_window((frame.img.shape[1], frame.img.shape[0])) if self.window_should_close: self.close_window() if self._window: debug_img = np.zeros(frame.img.shape, frame.img.dtype) #get the user_roi img = frame.img r_img = img[u_r.view] gray_img = cv2.cvtColor(r_img, cv2.COLOR_BGR2GRAY) # coarse pupil detection integral = cv2.integral(gray_img) integral = np.array(integral, dtype=c_float) x, y, w, response = eye_filter(integral, self.coarse_filter_min, self.coarse_filter_max) p_r = Roi(gray_img.shape) if w > 0: p_r.set((y, x, y + w, x + w)) else: p_r.set((0, 0, -1, -1)) coarse_pupil_center = x + w / 2., y + w / 2. coarse_pupil_width = w / 2. padding = coarse_pupil_width / 4. pupil_img = gray_img[p_r.view] # binary thresholding of pupil dark areas hist = cv2.calcHist([pupil_img], [0], None, [256], [ 0, 256 ]) #(images, channels, mask, histSize, ranges[, hist[, accumulate]]) bins = np.arange(hist.shape[0]) spikes = bins[hist[:, 0] > 40] # every intensity seen in more than 40 pixels if spikes.shape[0] > 0: lowest_spike = spikes.min() highest_spike = spikes.max() else: lowest_spike = 200 highest_spike = 255 offset = self.intensity_range.value spectral_offset = 5 if visualize: # display the histogram sx, sy = 100, 1 colors = ((0, 0, 255), (255, 0, 0), (255, 255, 0), (255, 255, 255)) h, w, chan = img.shape hist *= 1. / hist.max() # normalize for display for i, h in zip(bins, hist[:, 0]): c = colors[1] cv2.line(img, (w, int(i * sy)), (w - int(h * sx), int(i * sy)), c) cv2.line(img, (w, int(lowest_spike * sy)), (int(w - .5 * sx), int(lowest_spike * sy)), colors[0]) cv2.line(img, (w, int((lowest_spike + offset) * sy)), (int(w - .5 * sx), int( (lowest_spike + offset) * sy)), colors[2]) cv2.line(img, (w, int((highest_spike) * sy)), (int(w - .5 * sx), int((highest_spike) * sy)), colors[0]) cv2.line( img, (w, int((highest_spike - spectral_offset) * sy)), (int(w - .5 * sx), int( (highest_spike - spectral_offset) * sy)), colors[3]) # create dark and spectral glint masks self.bin_thresh.value = lowest_spike binary_img = bin_thresholding(pupil_img, image_upper=lowest_spike + offset) kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7)) cv2.dilate(binary_img, kernel, binary_img, iterations=2) spec_mask = bin_thresholding(pupil_img, image_upper=highest_spike - spectral_offset) cv2.erode(spec_mask, kernel, spec_mask, iterations=1) kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9)) #open operation to remove eye lashes pupil_img = cv2.morphologyEx(pupil_img, cv2.MORPH_OPEN, kernel) if self.blur > 1: pupil_img = cv2.medianBlur(pupil_img, self.blur.value) edges = cv2.Canny(pupil_img, self.canny_thresh, self.canny_thresh * self.canny_ratio, apertureSize=self.canny_aperture) # remove edges in areas not dark enough and where the glint is (spectral refelction from IR leds) edges = cv2.min(edges, spec_mask) edges = cv2.min(edges, binary_img) overlay = img[u_r.view][p_r.view] if visualize: b, g, r = overlay[:, :, 0], overlay[:, :, 1], overlay[:, :, 2] g[:] = cv2.max(g, edges) b[:] = cv2.max(b, binary_img) b[:] = cv2.min(b, spec_mask) # draw a frame around the automatic pupil ROI in overlay. overlay[::2, 0] = 255 #yeay numpy broadcasting overlay[::2, -1] = 255 overlay[0, ::2] = 255 overlay[-1, ::2] = 255 # draw a frame around the area we require the pupil center to be. overlay[padding:-padding:4, padding] = 255 overlay[padding:-padding:4, -padding] = 255 overlay[padding, padding:-padding:4] = 255 overlay[-padding, padding:-padding:4] = 255 if visualize: c = (100., frame.img.shape[0] - 100.) e_max = ((c), (self.pupil_max.value, self.pupil_max.value), 0) e_recent = ((c), (self.target_size.value, self.target_size.value), 0) e_min = ((c), (self.pupil_min.value, self.pupil_min.value), 0) cv2.ellipse(frame.img, e_min, (0, 0, 255), 1) cv2.ellipse(frame.img, e_recent, (0, 255, 0), 1) cv2.ellipse(frame.img, e_max, (0, 0, 255), 1) #get raw edge pix for later raw_edges = cv2.findNonZero(edges) def ellipse_true_support(e, raw_edges): a, b = e[1][0] / 2., e[1][ 1] / 2. # major minor radii of candidate ellipse ellipse_circumference = np.pi * abs(3 * (a + b) - np.sqrt(10 * a * b + 3 * (a**2 + b**2))) distances = dist_pts_ellipse(e, raw_edges) support_pixels = raw_edges[distances <= 1.3] # support_ratio = support_pixel.shape[0]/ellipse_circumference return support_pixels, ellipse_circumference # if we had a good ellipse before ,let see if it is still a good first guess: if self.strong_prior: e = p_r.sub_vector(u_r.sub_vector(self.strong_prior[0]) ), self.strong_prior[1], self.strong_prior[2] self.strong_prior = None if raw_edges is not None: support_pixels, ellipse_circumference = ellipse_true_support( e, raw_edges) support_ratio = support_pixels.shape[0] / ellipse_circumference if support_ratio >= self.strong_perimeter_ratio_range[0]: refit_e = cv2.fitEllipse(support_pixels) if self._window: cv2.ellipse(debug_img, e, (255, 100, 100), thickness=4) cv2.ellipse(debug_img, refit_e, (0, 0, 255), thickness=1) e = refit_e self.strong_prior = u_r.add_vector(p_r.add_vector( e[0])), e[1], e[2] goodness = support_ratio pupil_ellipse = {} pupil_ellipse['confidence'] = goodness pupil_ellipse['ellipse'] = e pupil_ellipse['roi_center'] = e[0] pupil_ellipse['major'] = max(e[1]) pupil_ellipse['minor'] = min(e[1]) pupil_ellipse['axes'] = e[1] pupil_ellipse['angle'] = e[2] e_img_center = u_r.add_vector(p_r.add_vector(e[0])) norm_center = normalize( e_img_center, (frame.img.shape[1], frame.img.shape[0]), flip_y=True) pupil_ellipse['norm_pupil'] = norm_center pupil_ellipse['center'] = e_img_center pupil_ellipse['timestamp'] = frame.timestamp self.target_size.value = max(e[1]) self.confidence.value = goodness self.confidence_hist.append(goodness) self.confidence_hist[:-200] = [] if self._window: #draw a little animation of confidence cv2.putText(debug_img, 'good', (410, debug_img.shape[0] - 100), cv2.FONT_HERSHEY_SIMPLEX, 0.3, (255, 100, 100)) cv2.putText( debug_img, 'threshold', (410, debug_img.shape[0] - int(self.final_perimeter_ratio_range[0] * 100)), cv2.FONT_HERSHEY_SIMPLEX, 0.3, (255, 100, 100)) cv2.putText(debug_img, 'no detection', (410, debug_img.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.3, (255, 100, 100)) lines = np.array( [[[2 * x, debug_img.shape[0] - int(100 * y)], [2 * x, debug_img.shape[0]]] for x, y in enumerate(self.confidence_hist)]) cv2.polylines(debug_img, lines, isClosed=False, color=(255, 100, 100)) self.gl_display_in_window(debug_img) return pupil_ellipse # from edges to contours contours, hierarchy = cv2.findContours(edges, mode=cv2.RETR_LIST, method=cv2.CHAIN_APPROX_NONE, offset=(0, 0)) #TC89_KCOS # contours is a list containing array([[[108, 290]],[[111, 290]]], dtype=int32) shape=(number of points,1,dimension(2) ) ### first we want to filter out the bad stuff # to short good_contours = [ c for c in contours if c.shape[0] > self.min_contour_size.value ] # now we learn things about each contour through looking at the curvature. # For this we need to simplyfy the contour so that pt to pt angles become more meaningfull aprox_contours = [ cv2.approxPolyDP(c, epsilon=1.5, closed=False) for c in good_contours ] if self._window: x_shift = coarse_pupil_width * 2 color = zip(range(0, 250, 15), range(0, 255, 15)[::-1], range(230, 250)) split_contours = [] for c in aprox_contours: curvature = GetAnglesPolyline(c) # we split whenever there is a real kink (abs(curvature)<right angle) or a change in the genreal direction kink_idx = find_kink_and_dir_change(curvature, 80) segs = split_at_corner_index(c, kink_idx) #TODO: split at shart inward turns for s in segs: if s.shape[0] > 2: split_contours.append(s) if self._window: c = color.pop(0) color.append(c) s = s.copy() s[:, :, 0] += debug_img.shape[1] - coarse_pupil_width * 2 # s[:,:,0] += x_shift # x_shift += 5 cv2.polylines(debug_img, [s], isClosed=False, color=map(lambda x: x, c), thickness=1, lineType=4) #cv2.CV_AA split_contours.sort(key=lambda x: -x.shape[0]) # print [x.shape[0]for x in split_contours] if len(split_contours) == 0: # not a single usefull segment found -> no pupil found self.confidence.value = 0 self.confidence_hist.append(0) if self._window: self.gl_display_in_window(debug_img) return {'timestamp': frame.timestamp, 'norm_pupil': None} # removing stubs makes combinatorial search feasable split_contours = [c for c in split_contours if c.shape[0] > 3] def ellipse_filter(e): in_center = padding < e[0][ 1] < pupil_img.shape[0] - padding and padding < e[0][ 0] < pupil_img.shape[1] - padding if in_center: is_round = min(e[1]) / max(e[1]) >= self.min_ratio if is_round: right_size = self.pupil_min.value <= max( e[1]) <= self.pupil_max.value if right_size: return True return False def ellipse_on_blue(e): center_on_dark = binary_img[e[0][1], e[0][0]] return bool(center_on_dark) def ellipse_support_ratio(e, contours): a, b = e[1][0] / 2., e[1][ 1] / 2. # major minor radii of candidate ellipse ellipse_area = np.pi * a * b ellipse_circumference = np.pi * abs(3 * (a + b) - np.sqrt(10 * a * b + 3 * (a**2 + b**2))) actual_area = cv2.contourArea( cv2.convexHull(np.concatenate(contours))) actual_contour_length = sum( [cv2.arcLength(c, closed=False) for c in contours]) area_ratio = actual_area / ellipse_area perimeter_ratio = actual_contour_length / ellipse_circumference #we assume here that the contour lies close to the ellipse boundary return perimeter_ratio, area_ratio def final_fitting(c, edges): #use the real edge pixels to fit, not the aproximated contours support_mask = np.zeros(edges.shape, edges.dtype) cv2.polylines(support_mask, c, isClosed=False, color=(255, 255, 255), thickness=2) # #draw into the suport mast with thickness 2 new_edges = cv2.min(edges, support_mask) new_contours = cv2.findNonZero(new_edges) if self._window: new_edges[new_edges != 0] = 255 overlay[:, :, 1] = cv2.max(overlay[:, :, 1], new_edges) overlay[:, :, 2] = cv2.max(overlay[:, :, 2], new_edges) overlay[:, :, 2] = cv2.max(overlay[:, :, 2], new_edges) new_e = cv2.fitEllipse(new_contours) return new_e, new_contours # finding poential candidates for ellipse seeds that describe the pupil. strong_seed_contours = [] weak_seed_contours = [] for idx, c in enumerate(split_contours): if c.shape[0] >= 5: e = cv2.fitEllipse(c) # is this ellipse a plausible canditate for a pupil? if ellipse_filter(e): distances = dist_pts_ellipse(e, c) fit_variance = np.sum(distances**2) / float( distances.shape[0]) if fit_variance <= self.inital_ellipse_fit_threshhold: # how much ellipse is supported by this contour? perimeter_ratio, area_ratio = ellipse_support_ratio( e, [c]) # logger.debug('Ellipse no %s with perimeter_ratio: %s , area_ratio: %s'%(idx,perimeter_ratio,area_ratio)) if self.strong_perimeter_ratio_range[ 0] <= perimeter_ratio <= self.strong_perimeter_ratio_range[ 1] and self.strong_area_ratio_range[ 0] <= area_ratio <= self.strong_area_ratio_range[ 1]: strong_seed_contours.append(idx) if self._window: cv2.polylines(debug_img, [c], isClosed=False, color=(255, 100, 100), thickness=4) e = (e[0][0] + debug_img.shape[1] - coarse_pupil_width * 4, e[0][1]), e[1], e[2] cv2.ellipse(debug_img, e, color=(255, 100, 100), thickness=3) else: weak_seed_contours.append(idx) if self._window: cv2.polylines(debug_img, [c], isClosed=False, color=(255, 0, 0), thickness=2) e = (e[0][0] + debug_img.shape[1] - coarse_pupil_width * 4, e[0][1]), e[1], e[2] cv2.ellipse(debug_img, e, color=(255, 0, 0)) sc = np.array(split_contours) if strong_seed_contours: seed_idx = strong_seed_contours elif weak_seed_contours: seed_idx = weak_seed_contours if not (strong_seed_contours or weak_seed_contours): if self._window: self.gl_display_in_window(debug_img) self.confidence.value = 0 self.confidence_hist.append(0) return {'timestamp': frame.timestamp, 'norm_pupil': None} # if self._window: # cv2.polylines(debug_img,[split_contours[i] for i in seed_idx],isClosed=False,color=(255,255,100),thickness=3) def ellipse_eval(contours): c = np.concatenate(contours) e = cv2.fitEllipse(c) d = dist_pts_ellipse(e, c) fit_variance = np.sum(d**2) / float(d.shape[0]) return fit_variance <= self.inital_ellipse_fit_threshhold solutions = pruning_quick_combine(split_contours, ellipse_eval, seed_idx, max_evals=1000, max_depth=5) solutions = filter_subsets(solutions) ratings = [] for s in solutions: try: e = cv2.fitEllipse(np.concatenate(sc[s])) if self._window: cv2.ellipse(debug_img, e, (0, 150, 100)) support_pixels, ellipse_circumference = ellipse_true_support( e, raw_edges) support_ratio = support_pixels.shape[0] / ellipse_circumference # TODO: refine the selection of final canditate if support_ratio >= self.final_perimeter_ratio_range[ 0] and ellipse_filter(e): ratings.append(support_pixels.shape[0]) if support_ratio >= self.strong_perimeter_ratio_range[0]: self.strong_prior = u_r.add_vector(p_r.add_vector( e[0])), e[1], e[2] if self._window: cv2.ellipse(debug_img, e, (0, 255, 255), thickness=2) else: #not a valid solution, bad rating ratings.append(-1) except: logger.warning( '0-d arrays cant be concatenated. ignoring this result') #not a valid solution, bad rating ratings.append(-1) # selected ellipse if max(ratings) == -1: #no good final ellipse found if self._window: self.gl_display_in_window(debug_img) self.confidence.value = 0 self.confidence_hist.append(0) return {'timestamp': frame.timestamp, 'norm_pupil': None} best = solutions[ratings.index(max(ratings))] e = cv2.fitEllipse(np.concatenate(sc[best])) #final calculation of goodness of fit support_pixels, ellipse_circumference = ellipse_true_support( e, raw_edges) support_ratio = support_pixels.shape[0] / ellipse_circumference goodness = min(1., support_ratio) #final fitting and return of result new_e, final_edges = final_fitting(sc[best], edges) size_dif = abs(1 - max(e[1]) / max(new_e[1])) if ellipse_filter(new_e) and size_dif < .3: if self._window: cv2.ellipse(debug_img, new_e, (0, 255, 0)) e = new_e pupil_ellipse = {} pupil_ellipse['confidence'] = goodness pupil_ellipse['ellipse'] = e pupil_ellipse['pos_in_roi'] = e[0] pupil_ellipse['major'] = max(e[1]) pupil_ellipse['apparent_pupil_size'] = max(e[1]) pupil_ellipse['minor'] = min(e[1]) pupil_ellipse['axes'] = e[1] pupil_ellipse['angle'] = e[2] e_img_center = u_r.add_vector(p_r.add_vector(e[0])) norm_center = normalize(e_img_center, (frame.img.shape[1], frame.img.shape[0]), flip_y=True) pupil_ellipse['norm_pupil'] = norm_center pupil_ellipse['center'] = e_img_center pupil_ellipse['timestamp'] = frame.timestamp self.target_size.value = max(e[1]) self.confidence.value = goodness self.confidence_hist.append(goodness) self.confidence_hist[:-200] = [] if self._window: #draw a little animation of confidence cv2.putText(debug_img, 'good', (410, debug_img.shape[0] - 100), cv2.FONT_HERSHEY_SIMPLEX, 0.3, (255, 100, 100)) cv2.putText(debug_img, 'threshold', (410, debug_img.shape[0] - int(self.final_perimeter_ratio_range[0] * 100)), cv2.FONT_HERSHEY_SIMPLEX, 0.3, (255, 100, 100)) cv2.putText(debug_img, 'no detection', (410, debug_img.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.3, (255, 100, 100)) lines = np.array([[[2 * x, debug_img.shape[0] - int(100 * y)], [2 * x, debug_img.shape[0]]] for x, y in enumerate(self.confidence_hist)]) cv2.polylines(debug_img, lines, isClosed=False, color=(255, 100, 100)) self.gl_display_in_window(debug_img) return pupil_ellipse
def FitVia_RANSAC2(pnts, input_pts=5, max_itts=5, max_refines=3, max_perc_inliers=80.0): ''' Robust ellipse fitting to segmented boundary points Parameters ---- pnts : n x 2 array of integers Candidate pupil-iris boundary points from edge detection roi : 2D scalar array Grayscale image of pupil-iris region for display only max_itts : integer Maximum RANSAC ellipse candidate iterations max_refines : integer Maximum RANSAC ellipse inlier refinements max_perc_inliers : float Maximum inlier percentage of total points for convergence Returns ---- best_ellipse : tuple of tuples Best fitted ellipse parameters ((x0, y0), (a,b), theta) ''' # Debug flag DEBUG = False # Output flags #graphics = cfg.getboolean('OUTPUT', 'graphics') # Suppress invalid values np.seterr(invalid='ignore') # Maximum normalize # d error squared for inliers max_norm_err_sq = 3 norm_err_score = np.inf # Tiny circle init best_ellipse = cv2.fitEllipse(pnts) ((x, y), (MA_, ma), angle) = best_ellipse bestInliers = np.zeros((5, 2)) inlier_count = 0 inliers = [] bestInliers = pnts #print(bestInliers) #print(pnts) # Create display window and init overlay image #if graphics: # cv2.namedWindow('RANSAC', cv2.WINDOW_AUTOSIZE) # Count pnts (n x 2) n_pnts = pnts.shape[0] #print('npnts: ',n_pnts) # Break if too few points to fit ellipse (RARE) if n_pnts < input_pts: return best_ellipse # random.seed() # Ransac iterations for itt in range(0, max_itts): # Select 5 points at random sample_pnts = np.asarray(random.sample(list(pnts), input_pts)) #print(sample_pnts) # Fit ellipse to points ellipse = cv2.fitEllipse(sample_pnts) ((x, y), (MA, ma), angle) = ellipse if (MA == 0): continue if (np.abs(MA - MA_) > 50): continue # Calculate normalized errors for all points norm_err = EllipseNormError(pnts, ellipse) #print(norm_err) # Identify inliers inliers = np.nonzero(np.abs(norm_err) <= max_norm_err_sq)[0] # Update inliers set inlier_pnts = pnts[inliers] #print('inpnts: ',inlier_pnts.shape[0]) # Protect ellipse fitting from too few points # End refinement # Count inliers (n x 2) n_inliers = inliers.size perc_inliers = (n_inliers * 100.0) / n_pnts # Update overlay image and display #if graphics: # overlay = cv2.cvtColor(roi/2,cv2.COLOR_GRAY2RGB) # OverlayRANSACFit(overlay, pnts, inlier_pnts, ellipse) # cv2.imshow('RANSAC', overlay) # cv2.waitKey(5) # Update best ellipse if n_inliers > inlier_count: best_ellipse = ellipse bestInliers = inlier_pnts inlier_count = n_inliers norm_err_score = np.average(np.abs(norm_err)) elif n_inliers == inlier_count: if np.average(np.abs(norm_err)) < norm_err_score: best_ellipse = ellipse bestInliers = inlier_pnts inlier_count = n_inliers norm_err_score = np.average(np.abs(norm_err)) #print(perc_inliers) #if perc_inliers > max_perc_inliers: # if DEBUG: print('Break Max Perc Inliers') # break return [best_ellipse, bestInliers]
def FitEllipse_RANSAC_Support(pnts, roi, cfg, max_itts=5, max_refines=3, max_perc_inliers=95.0): ''' Robust ellipse fitting to segmented boundary with image support Parameters ---- pnts : n x 2 array of integers Candidate pupil-iris boundary points from edge detection roi : 2D scalar array Grayscale image of pupil-iris region for support calculation. max_itts : integer Maximum RANSAC ellipse candidate iterations max_refines : integer Maximum RANSAC ellipse inlier refinements max_perc_inliers : float Maximum inlier percentage of total points for convergence Returns ---- best_ellipse : tuple of tuples Best fitted ellipse parameters ((x0, y0), (a,b), theta) ''' # Debug flag DEBUG = False # Output flags graphics = cfg.getboolean('OUTPUT', 'graphics') # Suppress invalid values np.seterr(invalid='ignore') # Maximum normalized error squared for inliers max_norm_err_sq = 2.0 # Tiny circle init best_ellipse = ((0, 0), (1e-6, 1e-6), 0) # High support is better, so init with -Infinity best_support = -np.inf # Create display window and init overlay image if graphics: cv2.namedWindow('RANSAC', cv2.WINDOW_AUTOSIZE) # Count pnts (n x 2) n_pnts = pnts.shape[0] # Break if too few points to fit ellipse (RARE) if n_pnts < 5: return best_ellipse # Precalculate roi intensity gradients dIdx = cv2.Sobel(roi, cv2.CV_32F, 1, 0) dIdy = cv2.Sobel(roi, cv2.CV_32F, 0, 1) # Ransac iterations for itt in range(0, max_itts): # Select 5 points at random sample_pnts = np.asarray(random.sample(list(pnts), 5)) # Fit ellipse to points ellipse = cv2.fitEllipse(sample_pnts) # Dot product of ellipse and image gradients for support calculation grad_dot = EllipseImageGradDot(sample_pnts, ellipse, dIdx, dIdy) # Skip this iteration if one or more dot products are <= 0 # implying that the ellipse is unlikely to bound the pupil if all(grad_dot > 0): # Refine inliers iteratively for refine in range(0, max_refines): # Calculate normalized errors for all points norm_err = EllipseNormError(pnts, ellipse) # Identify inliers inliers = np.nonzero(norm_err**2 < max_norm_err_sq)[0] # Update inliers set inlier_pnts = pnts[inliers] # Protect ellipse fitting from too few points if inliers.size < 5: if DEBUG: print('Break < 5 Inliers (During Refine)') break # Fit ellipse to refined inlier set ellipse = cv2.fitEllipse(inlier_pnts) # End refinement # Count inliers (n x 2) n_inliers = inliers.size perc_inliers = (n_inliers * 100.0) / n_pnts # Calculate support for the refined inliers support = EllipseSupport(inlier_pnts, ellipse, dIdx, dIdy) # Report on RANSAC progress if DEBUG: print('RANSAC %d,%d : %0.3f (%0.1f)' % (itt, refine, support, best_support)) # Update overlay image and display if graphics: overlay = cv2.cvtColor(roi / 2, cv2.COLOR_GRAY2RGB) OverlayRANSACFit(overlay, pnts, inlier_pnts, ellipse) cv2.imshow('RANSAC', overlay) cv2.waitKey(5) # Update best ellipse if support > best_support: best_support = support best_ellipse = ellipse else: # Ellipse gradients did not match image gradients support = 0.0 perc_inliers = 0.0 if perc_inliers > max_perc_inliers: if DEBUG: print('Break Max Perc Inliers') break return best_ellipse, inlier_pnts
def caculate_ellip_accu_once(im, filename, pred, pred_pro, gt_ellip, if_valid=False): #gt_ellipse [(x,y), w, h] pts = [] _, p, hierarchy = cv2.findContours(pred, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #tmp sz = im.shape c_im_show = np.zeros((sz[0], sz[1], 3)) cv2.drawContours(c_im_show, p, -1, (0, 255, 0), 1) #contours_path_ = os.path.join(error_path, filename.strip().decode('utf-8')+'_'+str(int(loss))+'_contour.bmp') #cv2.imwrite(contours_path_, c_im_show) for i in range(len(p)): for j in range(len(p[i])): pts.append(p[i][j]) pts_ = np.array(pts) if pts_.shape[0] > 5: ellipse_info = cv2.fitEllipse(pts_) pred_ellip = np.array([ ellipse_info[0][0], ellipse_info[0][1], ellipse_info[1][0], ellipse_info[1][1] ]) ellipse_info = (tuple( np.array([ellipse_info[0][0], ellipse_info[0][1]])), tuple( np.array([ellipse_info[1][0], ellipse_info[1][1]])), 0) else: pred_ellip = np.array([0, 0, 0, 0]) ellipse_info = (tuple(np.array([0, 0])), tuple(np.array([0, 0])), 0) sz_ = im.shape loss = np.sum(np.power( (np.array(gt_ellip) - pred_ellip), 2)) / (sz_[0] * sz_[1]) #save worse result if if_valid: error_path = cfgs.error_path + '_valid' else: error_path = cfgs.error_path #tmp contours_path_ = os.path.join( error_path, filename.strip().decode('utf-8') + '_' + str(int(loss)) + '_contour.bmp') cv2.imwrite(contours_path_, c_im_show) if loss > cfgs.loss_thresh: im = cv2.cvtColor(im, cv2.COLOR_RGB2BGR) cv2.ellipse(im, ellipse_info, (0, 255, 0), 1) gt_ellip_info = (tuple(np.array([gt_ellip[0], gt_ellip[1]])), tuple(np.array([gt_ellip[2], gt_ellip[3]])), 0) cv2.ellipse(im, gt_ellip_info, (0, 0, 255), 1) path_ = os.path.join( error_path, filename.strip().decode('utf-8') + '_' + str(int(loss)) + '.bmp') cv2.imwrite(path_, im) #heatmap heat_map = density_heatmap(pred_pro[:, :, 1]) cv2.imwrite( os.path.join(error_path, filename.strip().decode('utf-8') + '_heatseq_.bmp'), heat_map) contours_path_ = os.path.join( error_path, filename.strip().decode('utf-8') + '_' + str(int(loss)) + '_contour.bmp') cv2.imwrite(contours_path_, c_im_show) return loss
def divide_shelter_once(self, im, filename, pred, pred_pro, gt_ellip, if_valid=False, is_save=True): ''' divide the shelter and not shelter ''' pts = [] ''' _, p, hierarchy = cv2.findContours(pred, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #tmp draw contours sz = im.shape c_im_show = np.zeros((sz[0], sz[1], 3)) cv2.drawContours(c_im_show, p, -1, (0, 255, 0), 1) for i in range(len(p)): for j in range(len(p[i])): pts.append(p[i][j]) ''' sz = im.shape im = cv2.cvtColor(im, cv2.COLOR_RGB2BGR) #tmp fn = filename.strip().decode('utf-8') fn_full = '%s%s.bmp' % ('img', fn.split('img')[1]) im_full = cv2.imread(os.path.join(cfgs.full_im_path, fn_full)) im = cv2.resize(im_full, (sz[1], sz[0]), interpolation=cv2.INTER_CUBIC) for ii in range(sz[0]): for jj in range(sz[1]): if pred[ii][jj] > 0: pts.append([jj, ii]) im[ii][jj] = 255 pts_ = np.array(pts) if pts_.shape[0] > 5: ellipse_info = cv2.fitEllipse(pts_) ellipse_info_ = ellipse_info #pred_ellip = np.array([ellipse_info[0][0], ellipse_info[0][1], ellipse_info[1][0], ellipse_info[1][1]]) if ellipse_info[2] > 150 or ellipse_info[2] < 30: angle = 180 pred_ellip = np.array([ ellipse_info[0][0], ellipse_info[0][1], ellipse_info[1][0], ellipse_info[1][1] ]) else: angle = 90 pred_ellip = np.array([ ellipse_info[0][0], ellipse_info[0][1], ellipse_info[1][1], ellipse_info[1][0] ]) ellipse_info = (tuple( np.array([ ellipse_info[0][0], ellipse_info[0][1] ])), tuple(np.array([ellipse_info[1][0], ellipse_info[1][1]])), angle) loss = self.haus_loss(pred_ellip, gt_ellip) else: pred_ellip = np.array([0, 0, 0, 0]) ellipse_info = (tuple(np.array([0, 0])), tuple(np.array([0, 0])), 0) loss = self.ellip_loss(pred_ellip, gt_ellip) #loss = np.sum(np.power((np.array(gt_ellip)-pred_ellip), 2)) / (gt_ellip[2]*gt_ellip[3]) * 1000 if is_save: ''' fn = filename.strip().decode('utf-8') fn_full = '%s%s.bmp' % ('img', fn.split('img')[1]) im_full = cv2.imread(os.path.join(cfgs.full_im_path, fn_full)) im = cv2.resize(im_full, (sz[1], sz[0]), interpolation=cv2.INTER_CUBIC) ''' #save worse result error_path = cfgs.error_path #im = cv2.cvtColor(im, cv2.COLOR_RGB2BGR) cv2.ellipse(im, ellipse_info, (0, 255, 0), 1) gt_ellip_info = (tuple(np.array([gt_ellip[0], gt_ellip[1]])), tuple(np.array([gt_ellip[2], gt_ellip[3]])), 0) cv2.ellipse(im, gt_ellip_info, (0, 0, 255), 1) ''' print('filename: ', fn, ' loss: ', loss) print('gt_ellipse_info: ', gt_ellip) print('pred_ellipse_info: ', pred_ellip) print('gt_ellipse_info: ', gt_ellip_info) print('pred_ellipse_info: ', ellipse_info_) print('gt_ellipse_info: ', gt_ellip_info) print('pred_ellipse_info: ', ellipse_info) ''' if loss > cfgs.loss_thresh: if loss > 500: loss = 500 path_ = os.path.join( error_path, filename.strip().decode('utf-8') + '_' + str(int(loss)) + '.bmp') cv2.imwrite(path_, im) else: path_ = os.path.join( error_path + '_better', filename.strip().decode('utf-8') + '_' + str(int(loss)) + '.bmp') cv2.imwrite(path_, im) return loss
def divide_shelter_once(im, filename, pred, pred_pro, gt_ellip, if_valid=False): ''' divide the shelter and not shelter ''' pts = [] _, p, hierarchy = cv2.findContours(pred, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #tmp sz = im.shape c_im_show = np.zeros((sz[0], sz[1], 3)) cv2.drawContours(c_im_show, p, -1, (0, 255, 0), 1) for i in range(len(p)): for j in range(len(p[i])): pts.append(p[i][j]) pts_ = np.array(pts) if pts_.shape[0] > 5: ellipse_info = cv2.fitEllipse(pts_) pred_ellip = np.array([ ellipse_info[0][0], ellipse_info[0][1], ellipse_info[1][0], ellipse_info[1][1] ]) ellipse_info = (tuple( np.array([ellipse_info[0][0], ellipse_info[0][1]])), tuple( np.array([ellipse_info[1][0], ellipse_info[1][1]])), 0) else: pred_ellip = np.array([0, 0, 0, 0]) ellipse_info = (tuple(np.array([0, 0])), tuple(np.array([0, 0])), 0) loss = np.sum(np.power((np.array(gt_ellip) - pred_ellip), 2)) / (gt_ellip[2] * gt_ellip[3]) * 1000 #save worse result error_path = cfgs.error_path im = cv2.cvtColor(im, cv2.COLOR_RGB2BGR) cv2.ellipse(im, ellipse_info, (0, 255, 0), 1) gt_ellip_info = (tuple(np.array([gt_ellip[0], gt_ellip[1]])), tuple(np.array([gt_ellip[2], gt_ellip[3]])), 0) cv2.ellipse(im, gt_ellip_info, (0, 0, 255), 1) if loss > cfgs.loss_thresh: path_ = os.path.join( error_path, filename.strip().decode('utf-8') + '_' + str(int(loss)) + '.bmp') cv2.imwrite(path_, im) #tmp contours_path_ = os.path.join( error_path, filename.strip().decode('utf-8') + '_' + str(int(loss)) + '_contour.bmp') cv2.imwrite(contours_path_, c_im_show) else: path_ = os.path.join( error_path + '_better', filename.strip().decode('utf-8') + '_' + str(int(loss)) + '.bmp') cv2.imwrite(path_, im) #tmp contours_path_ = os.path.join( error_path + '_better', filename.strip().decode('utf-8') + '_' + str(int(loss)) + '_contour.bmp') cv2.imwrite(contours_path_, c_im_show) return loss
def FitEllipse_RobustLSQ(pnts, roi, cfg, max_refines=5, max_perc_inliers=95.0): ''' Iterate ellipse fit on inliers Parameters ---- pnts : n x 2 array of integers Candidate pupil-iris boundary points from edge detection roi : 2D scalar array Grayscale image of pupil-iris region for display only cfg : configuration structure Configuration parameters max_refines : integer Maximum number of inlier refinements max_perc_inliers : float Maximum inlier percentage of total points for convergence Returns ---- best_ellipse : tuple of tuples Best fitted ellipse parameters ((x0, y0), (a,b), theta) ''' # Debug flag DEBUG = False # Suppress invalid values np.seterr(invalid='ignore') # Maximum normalized error squared for inliers max_norm_err_sq = 4.0 # Tiny circle init best_ellipse = ((0, 0), (1e-6, 1e-6), 0) # Count edge points n_pnts = pnts.shape[0] # Break if too few points to fit ellipse (RARE) if n_pnts < 5: return best_ellipse # Fit ellipse to points ellipse = cv2.fitEllipse(pnts) # Refine inliers iteratively for refine in range(0, max_refines): # Calculate normalized errors for all points norm_err = EllipseNormError(pnts, ellipse) # Identify inliers inliers = np.nonzero(norm_err**2 < max_norm_err_sq)[0] # Update inliers set inlier_pnts = pnts[inliers] # Protect ellipse fitting from too few points if inliers.size < 5: if DEBUG: print('Break < 5 Inliers (During Refine)') break # Fit ellipse to refined inlier set ellipse = cv2.fitEllipse(inlier_pnts) # Count inliers (n x 2) n_inliers = inliers.size perc_inliers = (n_inliers * 100.0) / n_pnts # Update best ellipse best_ellipse = ellipse if perc_inliers > max_perc_inliers: if DEBUG: print('Break > maximum inlier percentage') break return best_ellipse, inlier_pnts
def callback(self, data): if not self.is_moving: try: frame = self.bridge.imgmsg_to_cv2(data, "bgr8") except CvBridgeError as e: print("==[CAMERA MANAGER]==", e) global counter if counter > 4: counter = 0 scale = 0.75 frame = (frame * scale).astype(np.uint8) # Split frame into left and right halves left_frame = frame[0:frame.shape[0], 0:frame.shape[1] / 3] middle_frame = frame[0:frame.shape[0], frame.shape[1] / 3:2 * frame.shape[1] / 3] right_frame = frame[0:frame.shape[0], 2 * frame.shape[1] / 3:frame.shape[1]] # Create list of left and right images frames = [left_frame, middle_frame, right_frame] for i, f in enumerate(frames): kps, des = sift.detectAndCompute(f, None) # frames[i] = cv2.drawKeypoints(f, kps, None, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) # draw SIFT points # Convert current index to one_hot list representation for color assignment later one_hot = [0, 0, 0] one_hot[i] = 1 # Basic threshold example gray = cv2.cvtColor(f, cv2.COLOR_RGBA2GRAY) # CHANGE THESE VALUES TO CALIBRATE BOUNDING BOXES # th, dst = cv2.threshold(gray, 77, 147, cv2.THRESH_BINARY) dst = cv2.adaptiveThreshold(gray, 200, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 17, 5) # UNCOMMENT IF YOU WANT TO SEE OUTPUT OF OPENCV THRESHOLDING PROCESS # cv2.imshow('test' + str(i), dst) # Find contours of each partial frame and put bounding box around contour _, contours, hierarchy = cv2.findContours( dst, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) if len(contours) <= 0: # print ("Waiting for something to grasp...") rospy.logwarn_throttle( 1, "Waiting for something to grasp...") else: contours = sorted(contours, key=cv2.contourArea, reverse=True)[:20] cnt = contours[0] # M = cv2.moments(cnt) # self.object_info.x[i] = int(M["m10"]/M["m00"]) # self.object_info.y[i] = int(M["m01"]/M["m00"]) # cv2.circle(frames[i],(int(M["m10"]/M["m00"]),int(M["m01"]/M["m00"])), 5, (255*one_hot[0],255*one_hot[1],255*one_hot[2]), -1) rect = cv2.minAreaRect(cnt) box = cv2.boxPoints(rect) cv2.drawContours( frames[i], [np.int0(box)], 0, (255 * one_hot[0], 255 * one_hot[1], 255 * one_hot[2]), 2) # Calculate angle and center of each bounding box if len(cnt) > 5: (x, y), (MA, mA), angle = cv2.fitEllipse(cnt) if x >= 0 and y >= 0: self.object_info.x[i] = int( x) + frame.shape[1] / 3 * i self.object_info.y[i] = int(y) self.object_info.theta[i] = np.deg2rad(angle) # Check to make sure des has elements and there are at least 15 keypoints if des is not None and len(kps) > 30: test_features = np.zeros((1, k), "float32") words, distance = vq(whiten(des), vocabulary) for w in words: if w >= 0 and w < 100: test_features[0][w] += 1 # Scale the features test_features = std_slr.transform(test_features) # predictions based on classifier (more than 2) predictions[i][counter] = [ class_names[j] for j in classifier.predict(test_features) ][0] prediction = max(set(predictions[i]), key=predictions[i].count) self.object_info.names[i] = prediction # Find the point at the top of each bounding box to put label labelY = int( min(box[0][1], box[1][1], box[2][1], box[3][1])) labelX = [ int(pt[0]) for pt in box if int(pt[1]) == labelY ][0] # Add label to partial frame font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText( frames[i], prediction, (labelX, labelY - 5), font, 0.5, (255 * one_hot[0], 255 * one_hot[1], 255 * one_hot[2]), 1) # Combine smaller frames into one frame[0:frame.shape[0], 0:frame.shape[1] / 3] = frames[0] frame[0:frame.shape[0], frame.shape[1] / 3:2 * frame.shape[1] / 3] = frames[1] frame[0:frame.shape[0], 2 * frame.shape[1] / 3:frame.shape[1]] = frames[2] # Add a dividing line down the middle of the frame cv2.line(frame, (frame.shape[1] / 3, 0), (frame.shape[1] / 3, frame.shape[0]), (255, 255, 255), 1) cv2.line(frame, (2 * frame.shape[1] / 3, 0), (2 * frame.shape[1] / 3, frame.shape[0]), (255, 255, 255), 1) # Resize image to fit monitor (if monitor is attached) if needResizing: frame = cv2.resize(frame, (1920, 1080), interpolation=cv2.INTER_CUBIC) counter += 1 # Display the resulting frame cv2.imshow('Object recognition', frame) self.object_location_pub.publish(self.object_info) cv2.waitKey(1) if self.is_moving == True: # Debug terminal # print("---- IT'S MOVING -----") self._done = True # Debug terminal # print(self._done) # Calling shutdown rospy.signal_shutdown("ismoving") return
#cv2.imshow ("gray", gray) #set the threshold for contouring ret2, thresh = cv2.threshold(gray, 127, 255, 0) #show those thresholds bby #cv2.imshow ("thresh", thresh) #heres where we find the coutours #contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) contours, hierarchy = cv2.findContours(thresh, 1, 2) img = cv2.drawContours(frame, contours, -1, (0, 255, 0), 3) #this will display the contrours on the video cv2.imshow('contrours on video', frame) cnts = sorted(contours, key=cv2.contourArea, reverse=True) for i in range(0, len(cnts)): sel_cnts = sorted(contours, key=cv2.contourArea, reverse=True)[i] area = cv2.contourArea(sel_cnts) center, axis, angle = cv2.fitEllipse(sel_cnts) hyp = 100 # length of the orientation line # Find out coordinates of 2nd point if given length of line and center coord linex = int(center[0]) + int(math.sin(math.radians(angle)) * hyp) liney = int(center[1]) - int(math.cos(math.radians(angle)) * hyp) # Draw orienation cv2.line(frame, (int(center[0]), int(center[1])), (linex, liney), (0, 0, 255), 5) cv2.circle(frame, (int(center[0]), int(center[1])), 10, (255, 0, 0), -1) cv2.imshow('kill me', frame) # Press Q on keyboard to exit
# Contor Detection # Convert to grayscale gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY) # Create a binary thresholded image retval, binary = cv2.threshold(gray, 225, 255, cv2.THRESH_BINARY_INV) # Find contours from thresholded, binary image retval, contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # Draw all contours on a copy of the original image contours_image = np.copy(image) contours_image = cv2.drawContours(contours_image, contours, -1, (0,255,0), 3) # Fit an ellipse to a contour and extract the angle from that ellipse (x,y), (MA,ma), angle = cv2.fitEllipse(selected_contour) # Bounding Box # Find the bounding rectangle of a selected contour x,y,w,h = cv2.boundingRect(selected_contour) # Draw the bounding rectangle as a purple box box_image = cv2.rectangle(contours_image, (x,y), (x+w,y+h), (200,0,200),2) # Crop using the dimensions of the bounding rectangle (x, y, w, h) cropped_image = image[y: y + h, x: x + w] # K-Means Clustering # Reshape image into a 2D array of pixels and 3 color values (RGB) pixel_vals = image.reshape((-1,3))
image_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(pupil_roi_gray, contours, -1, (0, 0, 255), 1) area = [] for i in range(0, len(contours)): area.append(cv2.contourArea(contours[i])) x, y, w, h = cv2.boundingRect(contours[i]) cv2.rectangle(pupil_roi_gray, (x, y), (x + w, y + h), (255, 255, 0), 1) if (len(contours) > 0): max_contour_id = np.argmax(area) ellipse = [] key = cv2.waitKey(1) key = key - 48 if (len(contours[max_contour_id]) > 5): ellipse = cv2.fitEllipse( contours[max_contour_id]) #return (center,axis,angle) cv2.ellipse(pupil_roi_gray, ellipse, (255, 255, 255), 2) cv2.circle(pupil_roi_gray, (int(ellipse[0][0]), int(ellipse[0][1])), 1, (255, 255, 255), 1) #get calibration data pupil_center = ellipse[0] if (key == 1): calibration_data.append(pupil_center) elif (key == 2): calibration_data.append(pupil_center) elif (key == 3): calibration_data.append(pupil_center) elif (key == 4): calibration_data.append(pupil_center) elif (key == 5):
area = cv2.contourArea(cnt) #perimeter perimeter = cv2.arcLength(cnt, True) #contour approximation epsilon = .1 * cv2.arcLength(cnt, True) approx = cv2.approxPolyDP(cnt, epsilon, True) #convex hull hull = cv2.convexHull(cnt) #Checking convexity k = cv2.isContourConvex(cnt) k #Bounding rectangle #Straight x, y, w, h = cv2.boundingRect(cnt) #Rotated rect = cv2.minAreaRect(cnt) box = cv2.boxPoints(rect) box = np.int0(box) #min enclosing circle (x, y), radius = cv2.minEnclosingCircle(cnt) #Fitting an ellipse ellipse = cv2.fitEllipse(cnt)
cv2.drawContours(im, contours, -1, (0, 255, 0), 3) cv2.imshow('cont', im) cv2.waitKey() cv2.destroyAllWindows() im_patBGR = cv2.imread('bbox/cucumber_belt_509_bbox.jpg') im_pat = cv2.cvtColor(im_patBGR, cv2.COLOR_BGR2GRAY) thr, im_pattern = cv2.threshold(im_pat, 230, 255, cv2.THRESH_BINARY_INV) cv2.imshow('binary', im_pattern) cv2.waitKey() im_pattern, pattern_contours, hierarchy = cv2.findContours( im_pattern, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(im_pat, pattern_contours, -1, (0, 255, 0), 3) cv2.imshow('cont', im_pat) cv2.waitKey() #contour attribs ellipse = cv2.fitEllipse(contours[0]) cv2.ellipse(imBGR, ellipse, (0, 255, 0), 2) cv2.imshow('cont', imBGR) cv2.waitKey() #sketeize, quitar ramas y luego dilate a tope skeletonize(im_thr) ret = cv2.matchShapes(contours[0], pattern_contours[0], 1, 0.0) print(ret) cv2.destroyAllWindows()
def PoseEstimationfrmMask(self, mask, frame, frameH, frameW, arSet): # Contours detection contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) oldArea = 300 for cnt in contours: area = cv2.contourArea(cnt) approx = cv2.approxPolyDP(cnt, 0.012 * cv2.arcLength(cnt, True), True) #to change 0.012 param IMP x = approx.ravel()[0] y = approx.ravel()[1] if area > 300: #param #to change # if len(approx) == 3: # cv2.putText(frame, "Triangle", (x, y), font, 1, (0, 0, 0)) if len(approx) == 4: if 0: (cx, cy), (MA, ma), angle = cv2.fitEllipse(cnt) ar = MA / ma else: ar = (np.linalg.norm(approx[0] - approx[1]) + np.linalg.norm(approx[2] - approx[3])) / ( np.linalg.norm(approx[2] - approx[1]) + np.linalg.norm(approx[0] - approx[3])) if ar > 1: ar = 1 / ar hull = cv2.convexHull(cnt) hull_area = cv2.contourArea(hull) solidity = float(area) / hull_area # print "Angle",angle # print "solidity",solidity # print "ar",ar condition = ar < 1 and ar > arSet if solidity > 0.90 and condition: #to change self.ar = ar # print "ar",self.ar self.ARqueue = np.roll(self.ARqueue, 1, axis=0) self.ARqueue[0, :] = [ar] self.ARvar = np.var(self.ARqueue, axis=0) self.ARmean = np.mean(self.ARqueue, axis=0) if area > oldArea: cv2.drawContours(frame, [approx], 0, (0, 0, 0), 5) #cv2.circle(frame,(int(cx),int(cy)), 3, (0,0,255), -1) cv2.putText(frame, "Rectangle", (x, y), font, 1, (0, 0, 0)) cntMain = approx rect = self.order_points(cntMain) # print "rect",rect Pose = self.PoseEstimation(rect, frameH, frameW) if self.PoseFlag == 1: # print "PoseFlag",self.PoseFlag self.telloPose = np.transpose(Pose) self.poseQueue = np.roll(self.poseQueue, 1, axis=0) self.poseQueue[0, :] = [ Pose[0, 0], Pose[0, 1], Pose[0, 2] ] self.telloPoseVariance = np.var(self.poseQueue, axis=0) self.telloPoseMean = np.mean(self.poseQueue, axis=0) # print "PoseQueue",self.poseQueue # print "PoseMean",self.telloPoseMean # print "telloPoseVariance" , self.telloPoseVariance else: pass varN = np.linalg.norm(self.telloPoseVariance) # print "varN",varN oldArea = area
masky = cv2.inRange(image, lowery, uppery) imageb, contoursb, hierarchyb = cv2.findContours(maskb, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) imagey, contoursy, hierarchyy = cv2.findContours(masky, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) sortedContoursb = sorted(contoursb, key=cv2.contourArea, reverse=True) sortedContoursy = sorted(contoursy, key=cv2.contourArea, reverse=True) ## Create Ellipse ellipseb, ellipsey = 0, 0 xb, yb, xy, yy, = 0, 0, 0, 0 if len(sortedContoursb) > 0: if len(sortedContoursb[0]) > 5: ellipseb = cv2.fitEllipse(sortedContoursb[0]) (xb, yb), (MA, ma), angle = ellipseb cv2.ellipse(image, ellipseb, (0, 255, 255), 1) if len(sortedContoursy) > 0: if len(sortedContoursy[0]) > 5: ellipsey = cv2.fitEllipse(sortedContoursy[0]) (xy, yy), (MA, ma), angle = ellipsey cv2.ellipse(image, ellipsey, (0, 255, 255), 1) if (xb - xy != 0): m = abs((yy - yb) / (xb - xy)) else: m = 100 if (xb != 0) and (xy != 0) and m < .2: pixel = abs(int(round(xb - xy))) if pixel == 0:
def scale(self): # scale parameter determination ecc = 0.7 diameter_min = 25 diameter_max = 1000 distance_max = 10 img = self.image # resize image for processing sc = 2000 / float(img.shape[1]) imgres = cv2.resize(img, (int(img.shape[1] * sc), int(img.shape[0] * sc))) # convert to grayscale image gray = cv2.cvtColor(imgres, cv2.COLOR_BGR2GRAY) # adaptive thresholding th = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 201, 10.0) # closing operator kernel = np.ones((5, 5), np.uint8) closing = cv2.morphologyEx(th, cv2.MORPH_CLOSE, kernel) # extract contours im2, contours, hierarchy = cv2.findContours(closing, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) # filter contours by bounding box and eccentricity Contdist = np.array([[0, 0]]) contlist = list() bboxlist = list() for cnt in contours: x, y, w, h = cv2.boundingRect(cnt) # filter contours by bounding if (w > diameter_min and w < diameter_max and h > diameter_min and h < diameter_max): # compute eccentricity (center, axes, orientation) = cv2.fitEllipse(cnt) majoraxis_length = max(axes) minoraxis_length = min(axes) eccent = np.sqrt(1 - (minoraxis_length / majoraxis_length)**2) # filter contours by eccentricity if eccent < ecc: ar = np.array([[int(x + (w / 2)), int(y + (h / 2))]]) Contdist = np.concatenate((Contdist, ar)) contlist.append(cnt) bboxlist.append([x, y, w, h]) Contdist = Contdist[1:] # compute pairwise distance dist_matrix = scipy.spatial.distance.pdist(Contdist) distsquare = scipy.spatial.distance.squareform(dist_matrix) np.fill_diagonal(distsquare, np.inf) # compute minimum distance min_positions = np.where(distsquare == distsquare.min()) # find circles of scale symbol x, y, w, h = cv2.boundingRect(contlist[min_positions[0][0]]) cent = [int(x + w / 2), int(y + h / 2)] contlistend = list() dialist = list() for cnt, b in zip(contlist, bboxlist): if (b[0] < cent[0] and b[1] < cent[1] and b[0] + b[2] > cent[0] and b[1] + b[3] > cent[1]): contlistend.append(cnt) d = (b[2] + b[3]) / 2 dialist.append(d) # find circle with maximum diameter dmax = max(dialist) cnt = contlistend[dialist.index(dmax)] # compute scale resolution if distance_max > dmax: scale_factor = False else: d = dmax / sc scale_factor = 25.86 * (d / 198) if scale_factor < 10 or scale_factor > 150: scale_factor = False #cv2.drawContours(closing,cnt,-1,(0,255,0),cv2.cv.CV_FILLED) #cv2.namedWindow('win1',cv2.cv.CV_NORMAL) #cv2.imshow('win1',closing*255) #cv2.waitKey() #print('scale_factor: ' + str(scale_factor)) return scale_factor
def find(self, image): """ Finds elliptical markers in an image. Sample markers can be found in 'img/circle.jpg' :param image: The image to find markers in :return: Tuple: Whether any markers were found, Numpy array containing detected Marker objects """ self.img_size = (image.shape[0] + image.shape[1]) / 2.0 assert self.img_size > 0, "image size is <= 0" self.image = image self.gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) processed = self.process_image(self.gray) _, self.contours, self.hierarchy = self.find_contours(processed) self.markers = np.array([]) # type: list[CalibrationMarker] found = False if len(self.contours) > 1: # region Area pre-calculation areas = np.float32([]) for i in xrange(len(self.contours)): area = cv2.contourArea(self.contours[i]) areas = np.append(areas, area) # endregion # region Contour filtering for i in xrange(len(self.contours)): contour = self.contours[i] approx = cv2.approxPolyDP(contour, 0.01 * cv2.arcLength(contour, True), True) area = areas[i] children = self.get_contour_children(i) num_children = len(children) children_areas = areas[children] # num of contours must be greater than 5 for fitEllipse to work if len(contour) > 5 and (len(approx) > 4) and \ (math.pow(self.img_size / 2.0, 2) > area > config.cmarker.CONTOUR_MIN_AREA) and \ num_children >= 2 and np.all(area > children_areas): # Check ratio to children ratio_correct = False for child in children: if areas[child] <= 0: continue child_area_ratio = area / areas[child] if config.cmarker.CONTOUR_MAX_CHILD_AREA_RATIO > child_area_ratio > config.cmarker.CONTOUR_MIN_CHILD_AREA_RATIO: ratio_correct = True break # If ratio to children matches model if ratio_correct: ellipse = cv2.fitEllipse(contour) # Major and minor ellipse axes respectively major, minor = ellipse[1] aspect_ratio = float(major) / minor if aspect_ratio < config.cmarker.CONTOUR_MAX_ASPECT_RATIO: ellipse_center = np.array( [ellipse[0][0], ellipse[0][1]]) circle_center, radius = cv2.minEnclosingCircle( contour) circle_center = np.array( [circle_center[0], circle_center[1]]) # Distance between approx circle center and approx ellipse center center_dist = np.linalg.norm(ellipse_center - circle_center) # Make sure approx ellipse is not bigger than approx circle if center_dist < (major + minor) / config.cmarker.CONTOUR_MAX_CENTER_DIST_RATIO and \ major <= radius * config.cmarker.CONTOUR_MAJOR2RADIUS_RATIO and \ minor <= radius * config.cmarker.CONTOUR_MINOR2RADIUS_RATIO: # Determine if contour is ellipse using difference between ellipse and actual contour x, y, w, h = cv2.boundingRect(contour) # Draw estimated ellipse mask ellipse_mask = np.zeros((h, w, 1), np.uint8) ellipse_translated = ((ellipse[0][0] - x, ellipse[0][1] - y), ellipse[1], ellipse[2]) cv2.ellipse(ellipse_mask, ellipse_translated, (255, 255, 255), -1) # Draw actual contour mask contour_mask = np.zeros((h, w, 1), np.uint8) contour_translated = np.array( contour) - np.array([x, y]) cv2.drawContours(contour_mask, [contour_translated], 0, (255, 255, 255), -1) # Find absolute difference between contour and ellipse mask abs_diff = cv2.absdiff(contour_mask, ellipse_mask) # Count and normalize difference shape_diff = cv2.countNonZero( abs_diff) / float(area) if shape_diff < config.cmarker.CONTOUR_ELLIPSE_CONTOUR_DIFF: m = CalibrationMarker( ellipse, area, num_children) # region Check if there is a better marker nearby and delete worse ones found_duplicate = False markers_to_remove = [] for j in xrange(len(self.markers)): m2 = self.markers[j] if m.dist_to( m2.center ) < config.cmarker.MAX_MARKER_DIST: # If found a better one forget about me if m2.area > m.area and m2.num_children > m.num_children: found_duplicate = True # If existing ones are worse delete them else: markers_to_remove.append(j) for idx in markers_to_remove: np.delete(self.markers, idx) # endregion # If this is the best marker in the vicinity use this one if not found_duplicate: self.markers = np.append( self.markers, m) # endregion # Sort markers from top-left to bottom-right found, self.markers = self.sort_markers(self.markers) # region Draw found markers, debug only contour_mat = image.copy() prev_center = None r = 10 colors = [(0, 0, 255), (0, 128, 255), (0, 200, 200), (0, 255, 0), (200, 200, 0), (255, 0, 0), (255, 0, 255)] for i in xrange(len(self.markers)): marker = self.markers[i] center = tuple(np.int0(marker.center)) if prev_center is not None and found: cv2.line(contour_mat, center, prev_center, (0, 0, 0), 1) if found: color = colors[int(i / grid_size[1]) % len(colors)] cv2.line(contour_mat, (center[0] - r, center[1] - r), (center[0] + r, center[1] + r), color, 1) cv2.line(contour_mat, (center[0] - r, center[1] + r), (center[0] + r, center[1] - r), color, 1) cv2.circle(contour_mat, center, r + 2, color, 1) else: color = (0, 0, 255) cv2.line(contour_mat, (center[0] - r, center[1] - r), (center[0] + r, center[1] + r), color, 1) cv2.line(contour_mat, (center[0] - r, center[1] + r), (center[0] + r, center[1] - r), color, 1) cv2.circle(contour_mat, center, r + 2, color, 1) # cv2.ellipse(contour_mat, marker.ellipse, color, -1) """if found: cv2.putText(contour_mat, str(i), (center[0] - 5, center[1] - int(r*1.7)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)""" prev_center = center # cv2.imshow('Objects Detected', contour_mat) # endregion if not found: self.markers = np.array([]) if self.markers.shape[0] == 0: found = False return found, self.markers
def processimage1(self, imgdrone1): #this method finds the distance and angle of the hoop and the angle of the drone relative to the hoop #print "image recieved" yellow = [ np.array(x, np.uint8) for x in [[25, 100, 100], [35, 255, 255]] ] #the hsv filter used to detect yellow color by cv2.inRange #ranges: 0-180,0-255,0-255 erosion = (5, 5) #values used for erosion by cv2.erode imgrgb = self.bridge.imgmsg_to_cv2( imgdrone1, "bgr8") #converts drone's raw_image to bgr8 used by opencv imghsv = cv2.cvtColor(imgrgb, cv2.COLOR_BGR2HSV) #converts hsv to rgb color imgyellow = cv2.inRange( imghsv, yellow[0], yellow[1]) #filter the image for yellow, returns 8UC1 binary image erosion = (5, 5) imgyellow = cv2.erode(imgyellow, erosion, iterations=3) dilation = (5, 5) imgyellow = cv2.dilate( imgyellow, dilation, iterations=5 ) #erodes, then dilates the image to remove noise points #self.pub_image2.publish(self.bridge.cv2_to_imgmsg(imgyellow, "8UC1")) #publish filtered binary image filtered_contours = [] #creates array to store contours contours, hierarchy = cv2.findContours(\ imgyellow,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE) #finds image contours contour_area = [(cv2.contourArea(c), (c)) for c in contours] #pairs contours with size data contour_area = sorted(contour_area, reverse=True, key=lambda x: x[0]) #sorts contours by size imgcont = imgrgb #saves rgb image without drawn elements if (len(contour_area) > 1): stacked = np.vstack( (contour_area[0][1], contour_area[1][1] )) #combines the two largest contours to find hoop if len( stacked ) > 100: # and len(contour_area[0][1])>40 and len(contour_area[1][1])>40: ellipse = cv2.fitEllipse( stacked) #fits the ellipse to the combined contour #ellipse data: 0=center, 1=size, 2=angle #cv2.circle(imgcont, (int(round(ellipse[0][0])), int(round(ellipse[0][1]))) , 30, (200,100,0)) #draws circle at ellipse center cv2.drawContours(imgcont, contours, -1, (0, 255, 0), 3) #draws all contours cv2.rectangle( imgcont, (int(round(ellipse[0][0] + ellipse[1][0] * .3)), int(round(ellipse[0][1] + ellipse[1][1] * .3))), (int(round(ellipse[0][0] - ellipse[1][0] * .3)), int(round(ellipse[0][1] - ellipse[1][1] * .3))), (200, 100, 0) ) #draws a rectangle at ellipse center with dimensions proportional to those of ellipse cv2.ellipse(imgcont, ellipse, (255, 0, 0), 2) #draws ellipse #the hoop is ~40" in diameter, reads h= 512 at x = 36 inches .5071 = atan((40/2)/36), .5 = radius of hoop in meters hoop_angle = math.acos(ellipse[1][0] / ellipse[1][1]) #computes and hoop angle hoop_distance = .5 * math.cos( .5071 * ellipse[1][1] / 512) / math.sin( .5071 * ellipse[1][1] / 512) #computes distance to the hoop drone_angle = .5071 * (ellipse[0][0] - 300) / 512 #computes drone angle print hoop_angle print hoop_distance print drone_angle print "--------------------" imgdrone2 = self.bridge.cv2_to_imgmsg( imgcont, "8UC3" ) #converts opencv's bgr8 back to the drone's raw_image for rviz use, converts both hsv and rgb to self.pub_image.publish(imgdrone2) return [drone_angle, hoop_distance, hoop_angle] imgdrone2 = self.bridge.cv2_to_imgmsg( imgcont, "8UC3" ) #converts opencv's bgr8 back to the drone's raw_image for rviz use, converts both hsv and rgb to rviz-readable form self.pub_image.publish(imgdrone2) return [-1, -1, -1] #tells navigator method no hoop is detected
def process_image(self, frame): #rospy.loginfo("%s %s %s %s"%(str(self.is_positioning), str(self.is_grasping), str(self.is_done), str(self.is_failed))) #rospy.loginfo("processing image ...") #cv2.imshow("camera", frame) # gray frame_gray = cv2.cvtColor(frame, cv.CV_RGB2GRAY) #frame_gray = cv2.blur(frame_gray, (3,3)) frame_gray = cv2.GaussianBlur(frame_gray, (9, 9), 0) #cv2.imshow("camera_gray", frame_gray) # adaptive filter frame_filter = cv2.adaptiveThreshold( frame_gray, 255.0, cv.CV_THRESH_BINARY, #cv.CV_ADAPTIVE_THRESH_GAUSSIAN_C, cv.CV_ADAPTIVE_THRESH_MEAN_C, 9, # neighbourhood 9) #cv2.imshow("camera_filter", frame_filter) size = frame.shape size = (size[1] - 1, size[0] - 1) # rectangle cv2.rectangle( frame_filter, (0, 0), size, 255, # color 20, # thickness 8, # line-type ??? 0) # random shit # rectangle cv2.rectangle( frame_filter, (0, 0), (640, 180), 255, # color cv2.cv.CV_FILLED, # thickness 8, # line-type ??? 0) # random shit cv2.bitwise_not(frame_filter, frame_filter) kernel = np.ones((3, 3), 'uint8') frame_dilate = cv2.dilate(frame_filter, np.array((3, 3))) cv2.imshow("camera_dilate", frame_dilate) # contours contours, hierarchy = cv2.findContours(frame_dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cross_w = size[0] / 2 + CROSS_OFF_X cross_h = size[1] / 2 + CROSS_OFF_Y #crosshair cv2.line(frame, (cross_w, 0), (cross_w, size[1]), (255, 255, 0)) cv2.line(frame, (0, cross_h), (size[0], cross_h), (255, 255, 0)) largest = None max_area = 0 smallest_x_dist = size[0] snd_smallest_x_dist = size[0] cen1 = None cen2 = None for c in contours: if len(c) <= 4: continue area = cv2.contourArea(c) if area > 100: ellipse = cv2.fitEllipse(c) axis = tuple(np.int32(ellipse[1])) if (max(axis) < 300): cv2.drawContours(frame, [c], -1, (255, 0, 0), 1) cv2.ellipse(frame, ellipse, (0, 255, 0), 2) center = tuple(np.int32(ellipse[0])) cv2.circle(frame, center, 3, (0, 0, 255), 2) xdist = abs(center[0] - cross_w) #print ydist #center = tuple(np.int32(ellipse[0])) #axis = tuple(np.int32(ellipse[1])) if xdist < smallest_x_dist: snd_smallest_x_dist = smallest_x_dist smallest_x_dist = xdist cen2 = cen1 cen1 = center elif xdist < snd_smallest_x_dist: snd_smallest_x_dist = xdist cen2 = center #if max_area < area: # max_area = area # largest = c print np.linalg.norm((np.array(cen2) - np.array(cen1))) print(np.array(cen2) + np.array(cen1)) / 2. self.angle = None if largest is not None and len(largest) >= 5: ellipse = cv2.fitEllipse(largest) center = tuple(np.int32(ellipse[0])) axis = tuple(np.int32(ellipse[1])) self.angle = ellipse[-1] / 180.0 * pi r = 30.0 cv2.line( frame, tuple( np.int32(center) + np.int32([r * cos(self.angle), r * sin(self.angle)])), tuple( np.int32(center) - np.int32([r * cos(self.angle), r * sin(self.angle)])), (0, 0, 255), 2) #xdist = center[0] - cross_w #ydist = center[1] - cross_h #print xdist, ydist # show camera image with annotations cv2.imshow("camera contours", frame)
def process_image(img): CORRECTION_NEEDED = False # Define lower and upper bounds of skin areas in YCrCb colour space. lower = np.array([0, 139, 60], np.uint8) upper = np.array([255, 180, 127], np.uint8) # convert img into 300*x large r = 300.0 / img.shape[1] print(r) dim = (300, int(img.shape[0] * r)) #img = cv2.resize(img, dim, interpolation=cv2.INTER_AREA) original = img.copy() # Extract skin areas from the image and apply thresholding ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB) mask = cv2.inRange(ycrcb, lower, upper) skin = cv2.bitwise_and(ycrcb, ycrcb, mask=mask) _, black_and_white = cv2.threshold(mask, 127, 255, 0) # Find contours from the thresholded image _, contours, _ = cv2.findContours(black_and_white, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # Get the maximum contour. It is usually the hand. length = len(contours) maxArea = -1 final_Contour = np.zeros(img.shape, np.uint8) # print(final_Contour) if length > 0: for i in range(length): temp = contours[i] area = cv2.contourArea(temp) if area > maxArea: maxArea = area ci = i largest_contour = contours[ci] # print(largest_contour) # Draw it on the image, in case you need to see the ellipse. cv2.drawContours(final_Contour, [largest_contour], 0, (0, 255, 0), 2) # Get the angle of inclination ellipse = _, _, angle = cv2.fitEllipse(largest_contour) # original = cv2.bitwise_and(original, original, mask=black_and_white) # Vertical adjustment correction ''' This variable is used when the result of hand segmentation is upside down. Will change it to 0 or 180 to correct the actual angle. The issue arises because the angle is returned only between 0 and 180, rather than 360. ''' vertical_adjustment_correction = 0 if CORRECTION_NEEDED: vertical_adjustment_correction = 180 # Rotate the image to get hand upright if angle >= 90: black_and_white = im.rotate_bound( black_and_white, vertical_adjustment_correction + 180 - angle) original = im.rotate_bound( original, vertical_adjustment_correction + 180 - angle) final_Contour = im.rotate_bound( original, vertical_adjustment_correction + 180 - angle) else: black_and_white = im.rotate_bound( black_and_white, vertical_adjustment_correction - angle) original = im.rotate_bound(original, vertical_adjustment_correction - angle) final_Contour = im.rotate_bound(final_Contour, vertical_adjustment_correction - angle) original = cv2.bitwise_and(original, original, mask=black_and_white) cv2.imshow('Extracted Hand', final_Contour) cv2.imwrite('contour.jpg', final_Contour) #cv2.imshow('Original image', original) # 求手掌中心 # 参考至http://answers.opencv.org/question/180668/how-to-find-the-center-of-one-palm-in-the-picture/ # 因为已经是黑白的,所以省略这一句 # cv2.threshold(black_and_white, black_and_white, 200, 255, cv2.THRESH_BINARY) distance = cv2.distanceTransform(black_and_white, cv2.DIST_L2, 5, cv2.CV_32F) # Calculates the distance to the closest zero pixel for each pixel of the source image. maxdist = 0 # rows,cols = img.shape for i in range(distance.shape[0]): for j in range(distance.shape[1]): # 先扩展一下访问像素的 .at 的用法: # cv::mat的成员函数: .at(int y, int x) # 可以用来存取图像中对应坐标为(x,y)的元素坐标。 # 但是在使用它时要注意,在编译期必须要已知图像的数据类型. # 这是因为cv::mat可以存放任意数据类型的元素。因此at方法的实现是用模板函数来实现的。 dist = distance[i][j] if maxdist < dist: x = j y = i maxdist = dist # 得到手掌中心并画出最大内切圆 final_img = original.copy() #cv2.circle(original, (x, y), maxdist, (255, 100, 255), 1, 8, 0) half_slide = maxdist * math.cos(math.pi / 4) (left, right, top, bottom) = ((x - half_slide), (x + half_slide), (y - half_slide), (y + half_slide)) p1 = (int(left), int(top)) p2 = (int(right), int(bottom)) #cv2.rectangle(original, p1, p2, (77, 255, 9), 1, 1) final_img = final_img[int(top):int(bottom), int(left):int(right)] # cv2.imshow('palm image', original) cv2.imwrite('cutout.jpg', original) return final_img
"""
def getPupil(self, image, threshold=0, pupilMinimum=10, pupilMaximum=50): """ Given an image, return the coordinates of the pupil candidates. """ # Create the output variable. bestPupil = -1 bestProps = {} ellipses = [] centers = [] # Create variables to plot the regression data. # TIPS: You must select two blob properties and add their values in # the following lists. Then, call the private method # __plotData() in the end of your implementation. x = [] y = [] # Grayscale image. grayscale = image.copy() if len(grayscale.shape) == 3: grayscale = cv2.cvtColor(grayscale, cv2.COLOR_BGR2GRAY) # Define the minimum and maximum size of the detected blob. pupilMinimum = int(round(math.pi * math.pow(pupilMinimum, 2))) pupilMaximum = int(round(math.pi * math.pow(pupilMaximum, 2))) # Preprocessing #kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7)) #grayscale = cv2.morphologyEx(grayscale, cv2.MORPH_OPEN, kernel) #kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(15,15)) #grayscale = cv2.morphologyEx(grayscale, cv2.MORPH_CLOSE, kernel) # Create a binary image. _, thres = cv2.threshold(grayscale, threshold, 255, cv2.THRESH_BINARY_INV) #thres = self.__GetAutoThresholdPupil(grayscale) #print thres # Find blobs in the input image. _, contours, hierarchy = cv2.findContours(thres, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) #<!---------------------------------------------------------------------------> #<!-- YOUR CODE HERE --> #<!---------------------------------------------------------------------------> for blob in contours: props = self.Props.calcContourProperties(blob, [ "centroid", "area", "extend", "circularity", "compactness", "epr" ]) # Is candidate if 500.0 < props["Area"] and props[ "Area"] < 8000.0 and 0.65 < props["Extend"] and props[ "Extend"] < 0.9: centers.append(props["Centroid"]) if len(blob) > 4: ellipses.append(cv2.fitEllipse(blob)) x.append(props["Area"]) y.append(props["Extend"]) else: ellipses.append(cv2.minAreaRect(blob)) x.append(props["Area"]) y.append(props["Extend"]) compactnessRatio = props["Compactness"] epr = props["Epr"] print props["Circularity"] if props[ "Circularity"] > 0.5 and compactnessRatio > 0.5 and epr > 0.5: # Update best props if bestPupil == -1: bestProps = props bestPupil = len(ellipses) - 1 else: if props["Circularity"] > bestProps["Circularity"]: bestProps = props bestPupil = len(ellipses) - 1 # Return the final result. return ellipses, centers, bestPupil
def ellipse_eval(contours): c = np.concatenate(contours) e = cv2.fitEllipse(c) d = dist_pts_ellipse(e, c) fit_variance = np.sum(d**2) / float(d.shape[0]) return fit_variance <= self.inital_ellipse_fit_threshhold
def get_pupil_from_contours(self, contours, small_gray, show_matching=5): ratio_thres = self._params['ratio_threshold'] area_threshold = self._params['relative_area_threshold'] error_threshold = self._params['error_threshold'] min_contour = self._params['min_contour_len'] margin = self._params['margin'] speed_thres = self._params['speed_threshold'] dr_thres = self._params['dr_threshold'] err = np.inf best_ellipse = None best_contour = None results, cond = defaultdict(list), defaultdict(list) for j, cnt in enumerate(contours): if len(contours[j] ) < min_contour: # otherwise fitEllipse won't work continue ellipse = cv2.fitEllipse(contours[j]) ((x, y), axes, angle) = ellipse if min(axes) == 0: # otherwise ratio won't work continue ratio = max(axes) / min(axes) area = np.prod(ellipse[1]) / np.prod(small_gray.shape) curr_err = self.goodness_of_fit(cnt, ellipse) results['ratio'].append(ratio) results['area'].append(area) results['rmse'].append(curr_err) results['x coord'].append(x / small_gray.shape[1]) results['y coord'].append(y / small_gray.shape[0]) center = np.array( [x / small_gray.shape[1], y / small_gray.shape[0]]) r = max(axes) dr = 0 if self._radius is None else np.abs( r - self._radius) / self._radius dx = 0 if self._center is None else np.sqrt( np.sum((center - self._center)**2)) results['dx'].append(dx) results['dr/r'].append(dr) matching_conditions = 1 * (ratio <= ratio_thres) + 1 * (area >= area_threshold) \ + 1 * (curr_err < error_threshold) \ + 1 * (margin < center[0] < 1 - margin) \ + 1 * (margin < center[1] < 1 - margin) \ + 1 * (dx < speed_thres * self._last_detection) \ + 1 * (dr < dr_thres * self._last_detection) cond['ratio'].append(ratio <= ratio_thres) cond['area'].append(area >= area_threshold) cond['rmse'].append(curr_err < error_threshold) cond['x coord'].append(margin < center[0] < 1 - margin) cond['y coord'].append(margin < center[1] < 1 - margin) cond['dx'].append(dx < speed_thres * self._last_detection) cond['dr/r'].append(dr < dr_thres * self._last_detection) results['conditions'] = matching_conditions cond['conditions'].append(True) if curr_err < err and matching_conditions == 7: best_ellipse = ellipse best_contour = cnt err = curr_err cv2.ellipse(small_gray, ellipse, (0, 0, 255), 2) elif matching_conditions >= show_matching: cv2.ellipse(small_gray, ellipse, (255, 0, 0), 2) if best_ellipse is None: df = pd.DataFrame(results) df2 = pd.DataFrame(cond) print('-', end="", flush=True) if np.any(df['conditions'] >= show_matching): idx = df['conditions'] >= show_matching df = df[idx] df2 = df2[idx] df[df2] = np.nan print("\n", df, flush=True) self._last_detection += 1 else: self._last_detection = 1 return best_contour, best_ellipse
def FitEllipse_RANSAC(pnts, roi, cfg, max_itts=5, max_refines=3, max_perc_inliers=95.0): ''' Robust ellipse fitting to segmented boundary points Parameters ---- pnts : n x 2 array of integers Candidate pupil-iris boundary points from edge detection roi : 2D scalar array Grayscale image of pupil-iris region for display only max_itts : integer Maximum RANSAC ellipse candidate iterations max_refines : integer Maximum RANSAC ellipse inlier refinements max_perc_inliers : float Maximum inlier percentage of total points for convergence Returns ---- best_ellipse : tuple of tuples Best fitted ellipse parameters ((x0, y0), (a,b), theta) ''' # Debug flag DEBUG = False # Output flags graphics = cfg.getboolean('OUTPUT', 'graphics') # Suppress invalid values np.seterr(invalid='ignore') # Maximum normalized error squared for inliers max_norm_err_sq = 2.0 # Tiny circle init best_ellipse = ((0, 0), (1e-6, 1e-6), 0) # Create display window and init overlay image if graphics: cv2.namedWindow('RANSAC', cv2.WINDOW_AUTOSIZE) # Count pnts (n x 2) n_pnts = pnts.shape[0] # Break if too few points to fit ellipse (RARE) if n_pnts < 5: return best_ellipse random.seed() # Ransac iterations for itt in range(0, max_itts): # Select 5 points at random sample_pnts = np.asarray(random.sample(list(pnts), 5)) # Fit ellipse to points ellipse = cv2.fitEllipse(sample_pnts) # Refine inliers iteratively for refine in range(0, max_refines): # Calculate normalized errors for all points norm_err = EllipseNormError(pnts, ellipse) # Identify inliers inliers = np.nonzero(norm_err**2 < max_norm_err_sq)[0] # Update inliers set inlier_pnts = pnts[inliers] # Protect ellipse fitting from too few points if inliers.size < 5: if DEBUG: print('Break < 5 Inliers (During Refine)') break # Fit ellipse to refined inlier set ellipse = cv2.fitEllipse(inlier_pnts) # End refinement # Count inliers (n x 2) n_inliers = inliers.size perc_inliers = (n_inliers * 100.0) / n_pnts # Update overlay image and display if graphics: overlay = cv2.cvtColor(roi / 2, cv2.COLOR_GRAY2RGB) OverlayRANSACFit(overlay, pnts, inlier_pnts, ellipse) cv2.imshow('RANSAC', overlay) cv2.waitKey(5) # Update best ellipse best_ellipse = ellipse if perc_inliers > max_perc_inliers: if DEBUG: print('Break Max Perc Inliers') break return [best_ellipse, inlier_pnts]
def getGlints(self, image, threshold=0, glintsMinimum=1, glintsMaximum=10, numOfGlints=1, pupilCenter=(0, 0)): """ Given an image, return the coordinates of the glints candidates. """ # Correct the number of glints. if numOfGlints < 1: numOfGlints = 1 # Create the output variable. bestGlints = [-1] * numOfGlints bestGlintsProps = [{}] * numOfGlints ellipses = [] centers = [] grayscale = image.copy() if len(grayscale.shape) == 3: grayscale = cv2.cvtColor(grayscale, cv2.COLOR_BGR2GRAY) glintProps = [] _, thres = cv2.threshold(grayscale, threshold, 255, cv2.THRESH_BINARY_INV) #thres = self.__GetAutoThresholdGlints(grayscale) # Find blobs in the input image. _, contours, hierarchy = cv2.findContours(thres, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) pupilCenterAsNumpyArray = np.array(pupilCenter) for blob in contours: props = self.Props.calcContourProperties( blob, ["centroid", "area", "extend", "circularity"]) distance = np.linalg.norm( np.array(props["Centroid"]) - pupilCenterAsNumpyArray) if props["Area"] < 1000.0 and props["Area"] > 15.0 and props[ "Circularity"] > 0.2 and distance < 50: centers.append(props["Centroid"]) glintProps.append(props) if len(blob) > 4: ellipses.append(cv2.fitEllipse(blob)) else: ellipses.append(cv2.minAreaRect(blob)) i = 0 if len(ellipses) <= numOfGlints: for ell in ellipses: bestGlints[i] = i i += 1 else: bestGlints = self.__GetBestGlints(glintProps, pupilCenterAsNumpyArray, numOfGlints) print i #<!---------------------------------------------------------------------------> #<!-- --> #<!---------------------------------------------------------------------------> # Return the final result. return ellipses, centers, bestGlints