首页 > 解决方案 > 红点坐标检测

问题描述

我正在尝试使用红点跟踪零件的运动。我之前尝试过使用白点和阈值,但我正在使用的智能手机反射太多。计划是将点识别为轮廓,找到中心并用所有轮廓中心的坐标填充数组以进行进一步计算。

代码发布在下面,它可以识别正确的点数,但我得到了除以零的错误。有谁知道我做错了什么?

图片: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)

标签: pythonopencvimage-processing

解决方案


根据 cv 文档,对于某些形状,moments00(面积)可以为 0。这可能是这里发生的事情:

注意 由于等高线矩是使用格林公式计算的,对于具有自相交的等高线,您可能会得到看似奇怪的结果,例如,蝴蝶形等高线的面积为零 (m00)。

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

您需要确保区域(m00)不为0,然后才能使用它进行划分。


推荐阅读