The Netger
The Netger

Reputation: 61

Tracking an array of IR LEDs to find their coordinates

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.

Input image

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

Answers (1)

nathancy
nathancy

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

enter image description here

Result with the centroid drawn in blue

enter image description here

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

Related Questions