Reputation: 61
I have 2 arrays of points, I also know their location in our world. I need to calculate the total middle of each array and the 2d(x y) coordinate of this middle. As a result, the image with these arrays of points should be input, and the output should be 2 list: return [x1, y1], [x2, y2]. Python 3.x language, OpenCV library.
I found some useful code (Python):
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
X = np.random.randint(25,50,(5,2))
Y = np.random.randint(60,85,(4,2))
Z = np.vstack((X,Y))
# convert to np.float32
Z = np.float32(Z)
# define criteria and apply kmeans()
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 10, 1.0)
ret,label,center=cv.kmeans(Z,2,None,criteria,10,cv.KMEANS_RANDOM_CENTERS)
# Now separate the data, Note the flatten()
A = Z[label.ravel()==0]
B = Z[label.ravel()==1]
# Plot the data
plt.scatter(A[:,0],A[:,1])
plt.scatter(B[:,0],B[:,1],c = 'r')
plt.scatter(center[:,0],center[:,1],s = 80,c = 'y', marker = 's')
plt.xlabel('Height'),plt.ylabel('Weight')
plt.show()
This code finds the midpoint among the array of points. But the problem is understanding which point belongs to which array.
Upvotes: 2
Views: 1586
Reputation: 46580
An idea is to threshold, perform morph operations, find contours, then find the centroid. This should give you the two points.
Morph close to connect points
Result with the centroid drawn in blue
Coordinates
(416, 234)
(231, 244)
Code
import cv2
# Load image, convert to grayscale, Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# Morphological transformations
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11,11))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=5)
# Find contours, obtain bounding rect, and find centroid
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
# Get bounding rect
x,y,w,h = cv2.boundingRect(c)
# Find centroid
M = cv2.moments(c)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
# Draw the contour and center of the shape on the image
cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2)
cv2.circle(image, (cX, cY), 1, (320, 159, 22), 8)
cv2.putText(image, '({}, {})'.format(cX, cY), (x,y - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (100,255,100), 2)
print('({}, {})'.format(cX, cY))
cv2.imshow('image', image)
cv2.imshow('close', close)
cv2.imshow('thresh', thresh)
cv2.waitKey()
Upvotes: 1