dan-masek

Detect and fit 2 intersecting ellipses -- prototype 1

Aug 5th, 2021 (edited)
321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.96 KB | None | 0 0
  1. import cv2
  2. import numpy as np
  3.  
  4.  
  5. def process_blob(n, contour, input_img, output_img):
  6.     MAJOR_DEFECT_THRESHOLD = 2.0
  7.    
  8.     cv2.drawContours(output_img, [contour], 0, (191,0,0), 2)
  9.    
  10.     hull = cv2.convexHull(contour)
  11.     cv2.drawContours(output_img, [hull], 0, (0,191,0), 2)
  12.    
  13.     hull_idx = cv2.convexHull(contour, returnPoints=False)
  14.     defects = cv2.convexityDefects(contour, hull_idx)
  15.    
  16.     intersections = []
  17.     for i,defect in enumerate(np.squeeze(defects, 1)):
  18.         first_idx, last_idx, far_idx, far_dist = defect
  19.         real_far_dist = far_dist / 256.0
  20.         if real_far_dist >= MAJOR_DEFECT_THRESHOLD:
  21.             print(("DEFECT #%d " % i), first_idx, last_idx, far_idx, real_far_dist)
  22.             intersections.append(far_idx)
  23.  
  24.     if len(intersections) == 0:
  25.         print("One ellipse")
  26.         ellipse = cv2.fitEllipse(contour)
  27.         cv2.ellipse(output_img, ellipse, (0,0,255), 2)
  28.         return [ellipse]
  29.        
  30.     if len(intersections) == 4:
  31.         print("Two ellipses")
  32.         contour_segments = [
  33.             contour[intersections[0]:intersections[1]+1]
  34.             , contour[intersections[1]:intersections[2]+1]
  35.             , contour[intersections[2]:intersections[3]+1]
  36.             , np.vstack([contour[intersections[3]:],contour[:intersections[0]+1]])
  37.         ]
  38.         cv2.polylines(output_img, [contour_segments[0]], False, (0,255,0), 4)
  39.         cv2.polylines(output_img, [contour_segments[1]], False, (0,255,255), 4)
  40.         cv2.polylines(output_img, [contour_segments[2]], False, (255,255,0), 4)
  41.         cv2.polylines(output_img, [contour_segments[3]], False, (255,0,255), 4)
  42.        
  43.         split_contours = [
  44.             np.vstack([contour_segments[0], contour_segments[2]])
  45.             , np.vstack([contour_segments[1], contour_segments[3]])
  46.         ]
  47.         ellipses = [cv2.fitEllipse(c) for c in split_contours]
  48.         for ellipse in ellipses:
  49.             cv2.ellipse(output_img, ellipse, (0,0,255), 2)
  50.         return ellipses
  51.  
  52.     print("Invalid scenario")
  53.     return []
  54.  
  55.  
  56. image = cv2.imread('input.png', cv2.IMREAD_GRAYSCALE)
  57.  
  58. _,img_binary = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY_INV)
  59.  
  60. contours, _ = cv2.findContours(img_binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  61.  
  62. print("Found %d blob(s)." % len(contours))
  63.  
  64. PADDING = 20
  65.  
  66. for i,contour in enumerate(contours):
  67.     orig_x, orig_y, width, height = cv2.boundingRect(contour)
  68.     offset_x, offset_y = orig_x - PADDING, orig_y - PADDING
  69.     offset_contour = contour - (offset_x, offset_y)
  70.  
  71.     input_img = cv2.copyMakeBorder(image[orig_y:orig_y+height,orig_x:orig_x+width]
  72.         , PADDING, PADDING, PADDING, PADDING, cv2.BORDER_CONSTANT, None, 255)
  73.     #output_img = np.zeros((PADDING * 2 + height, PADDING * 2 + width, 3), np.uint8)
  74.     output_img = cv2.cvtColor(cv2.add(input_img, 127), cv2.COLOR_GRAY2BGR)
  75.    
  76.     process_blob(i, offset_contour, input_img, output_img)
  77.     cv2.imshow('', output_img)
  78.     cv2.waitKey()
  79.  
Add Comment
Please, Sign In to add comment