Red dot coordinates detection

…衆ロ難τιáo~ 提交于 2020-05-17 07:46:07

问题


I'm trying to follow movement of a part using red dots. I tried with white dots and thresholding before, but there is too much reflection from the smartphone I'm using. The plan is to recognize a dot as a contour, find the center and fill the array with the coordinates of all contour centers for further calculation.

The code is posted bellow, it recognizes the correct number of dots, but I get the division by zero error. Does anyone know what I'm doing wrong?

Image:https://imgur.com/a/GLXGCPP

import cv2
import numpy as np
from matplotlib import pyplot as plt
import imutils

#load image
img = cv2.imread('dot4_red.jpg')

#apply median blur, 15 means it's smoothing image 15x15 pixels
blur = cv2.medianBlur(img,15)

#convert to hsv
hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)

#color definition
red_lower = np.array([0,0,240])
red_upper = np.array([10,10,255])

#red color mask (sort of thresholding, actually segmentation)
mask = cv2.inRange(hsv, red_lower, red_upper)

#copy image for, .findContours distorts the source image
mask_copy = mask.copy()

#find contours
cnts = cv2.findContours(mask_copy,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

#extract contours from the list??
cnts = imutils.grab_contours(cnts)

#count number of conoturs of specific size
s1 = 500
s2 = 10000
xcnts = []
for cnt in cnts:
    if s1<cv2.contourArea(cnt)<s2:
        xcnts.append(cnt)

n = len(xcnts)

#pre-allocate array for extraction of centers of contours
s = (n,2)
array = np.zeros(s)

#fill array of center coordinates 
for i in range(0,n):
    cnt = cnts[i]
    moment = cv2.moments(cnt)
    c_x = int(moment["m10"]/moment["m00"])
    c_y = int(moment["m01"]/moment["m00"])

    array[i,:] = [c_x, c_y]

#display image
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.imshow('image', mask)
cv2.waitKey(0) & 0xFF
cv2.destroyAllWindows()

#print results
print ('number of dots, should be 4:',n)
print ('array of dot center coordinates:',array)

回答1:


moments00 (area) can be 0 for some shapes according to cv documentation. This is probably what is happening here:

Note Since the contour moments are computed using Green formula, you may get seemingly odd results for contours with self-intersections, e.g. a zero area (m00) for butterfly-shaped contours.

From: https://docs.opencv.org/3.4/d8/d23/classcv_1_1Moments.html#a8b1b4917d1123abc3a3c16b007a7319b

You need to ensure the area (m00) is not 0 before using it for division.




回答2:


The problem was the wrong color range. Because of this, there were holes in the mask of the circles. Due to division by zero. M00. You can choose the correct color range or pre-fill the holes in the mask. Or use this code:

import cv2
import numpy as np
#load image
img = cv2.imread('ZayrMep.jpg')

#apply median blur, 15 means it's smoothing image 15x15 pixels
blur = cv2.medianBlur(img,15)

#convert to hsv
hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)

#color definition
red_lower = np.array([160,210,230])
red_upper = np.array([180,255,255])

#red color mask (sort of thresholding, actually segmentation)
mask = cv2.inRange(hsv, red_lower, red_upper)

connectivity = 4  
# Perform the operation
output = cv2.connectedComponentsWithStats(mask, connectivity, cv2.CV_32S)
# Get the results

num_labels = output[0]-1

centroids = output[3][1:]
#print results
print ('number of dots, should be 4:',num_labels )
print ('array of dot center coordinates:',centroids)


来源:https://stackoverflow.com/questions/61769416/red-dot-coordinates-detection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!