How To Find Different Centers Of Various Arcs In A Almost Circular Hole Using Opencv?
Solution 1:
An idea is to threshold then find contours and filter using the largest contour area. From here we use cv2.minEnclosingCircle()
to find the center (x,y)
point and the radius. Here's the largest contour highlighted in green
Now we simply find the minimum enclosing circle around the contour to determine the center point. Here's the result
the (x,y)
coordinate
176.53846740722656 174.33653259277344
Code
import cv2
import numpy as np
image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.threshold(blur,0,255,cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV)[1]
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] iflen(cnts) == 2else cnts[1]
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
for c in cnts:
(x,y), radius = cv2.minEnclosingCircle(c)
cv2.circle(image,(int(x),int(y)),int(radius),(35,255,12),3)
cv2.circle(image,(int(x),int(y)),1,(35,255,12),2)
print(x,y)
break
cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()
Solution 2:
If you have a hole you might use a specific color of the background behind your "object". So it should not be a problem to segment the actual shape:
and walk through all the points to find the most distant pairs (so you can find the diameter). With that being said you can find, for example, the centre of the circle you a looking for. Just did a quick test:
Sorry, no code to show. I'm not using OpenCV here, but you say any help is helpful :)
Solution 3:
import cv2
import numpy as np
import math
import random
ConvexityDefectPoint = []
# load image as color to draw
img = cv2.imread('YourImagePath\\test.jpg' ,
cv2.IMREAD_COLOR )
#convert to gray
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#threshold
ret,thresh1= cv2.threshold(gray,29,255,cv2.THRESH_BINARY_INV)
contours, hierarchy = cv2.findContours(thresh1,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#find the biggest contour
contour_sizes = [(cv2.contourArea(contour), contour) for contour in contours]
biggest_contour = max(contour_sizes, key=lambda x: x[0])[1]
#draw the bigest contour
cv2.drawContours(img,biggest_contour,-1,(0,255,0),3)
# compute the center of the contour using moment
M = cv2.moments(biggest_contour)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
# draw the centroid
cv2.circle(img, (cX, cY), 7, (0, 255, 255), -1)
#Get convexity defect points
hull = cv2.convexHull(biggest_contour,returnPoints = False)
defects = cv2.convexityDefects(biggest_contour,hull)
for i inrange(defects.shape[0]):
s,e,f,d = defects[i,0]
start = tuple(biggest_contour[s][0])
end = tuple(biggest_contour[e][0])
far = tuple(biggest_contour[f][0])
ConvexityDefectPoint.append(far)
#cv2.line(img,start,end,[0,255,0],2)
cv2.circle(img,far,5,[0,0,255],-1)
# fit ellipse to the selected points.
(x, y), (MA, ma), angle = cv2.fitEllipse(np.array(ConvexityDefectPoint))
# draw the ellipse center
cv2.circle(img, (int(x), int(y)), 7, (0, 0, 255), -1)
# Draw the center using moment ( outliers eliminated)
M = cv2.moments(np.array(ConvexityDefectPoint))
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
cv2.circle(img, (cX, cY), 7, (0, 255, ), -1)
cv2.imshow('Display',img)
cv2.waitKey(0)
This is just one of many possible methods you can use to calculate the centroid
- 1 using the moment
- 2 eliminate outliers using convexity defect and fit ellipse
using moment with new data points (outliers eliminated)
Result
Farther improvement :
eliminate outliers by iterating through the contour and detect arcs & non arcs
Post a Comment for "How To Find Different Centers Of Various Arcs In A Almost Circular Hole Using Opencv?"