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
Example #2
0
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
Example #3
0
    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   
Example #4
0
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
Example #5
0
    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
Example #7
0
    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
Example #8
0
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
Example #9
0
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 
Example #11
0
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()
Example #12
0
		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
Example #15
0
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
Example #18
0
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
Example #19
0
    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
Example #20
0
    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
Example #21
0
 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
Example #22
0
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)
Example #25
0
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
Example #26
0
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()
Example #27
0
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
Example #30
0
    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
Example #31
0
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))
Example #33
0
        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
Example #34
0
    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
Example #35
0
    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
Example #38
0
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
Example #39
0
    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
Example #40
0
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
Example #42
0
    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
Example #44
0
# 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):
Example #46
0
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()
Example #48
0
    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
Example #49
0
    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:
Example #50
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
Example #51
0
    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
Example #52
0
    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
Example #53
0
    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)
Example #54
0
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
"""
Example #56
0
    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
Example #57
0
 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
Example #58
0
    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]
Example #60
0
    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