阈值在OpenCV中没有检测到完整的对象,我想。我怎样才能解决这个问题?

问题描述 投票:0回答:1

我想检测从视频源的鸡蛋,当我尝试使用就可以了门槛,它没有得到完整的鸡蛋。

我试图从这个https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html适用不同的阈值的步骤

应用阈值,以不同的轮廓,下面是结果

ret, img = cap.read()
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

ret,th1 = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,11,2)
th3 = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,2)
ret2,th4 = cv2.threshold(gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

blur = cv2.GaussianBlur(gray,(5,5),0)
ret3,th5 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

dummy,cnts,hier = cv2.findContours(th1,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
for c in cnts:
    M = cv2.moments(c)
    if M["m00"] != 0:
        cX = int(M["m10"] / M["m00"])
        cY = int(M["m01"] / M["m00"])
    else:
        cX, cY = 0, 0
    cv2.drawContours(img, [c], -1, (0, 255, 0), 2)
    cv2.circle(img, (cX, cY), 2, (0, 0, 0), -1)
cv2.imshow("Global",th1)
cv2.imshow("Adaptive Mean",th2)
cv2.imshow("Adaptive Gaussian",th3)
cv2.imshow("Otsu's",th4)
cv2.imshow("Otsu's after Blur",th5)

https://imgur.com/a/qgLMkj6

更新:使用来自@马丁的回答后,我想出了这个

https://i.stack.imgur.com/2EQVM.jpg

通过越来越面积最大的轮廓。但也有其他的轮廓有一个大区也。接下来的问题是我能做些什么,以低于过滤掉其他的轮廓?我想确定哪些轮廓具有角或不是因为鸡蛋是椭圆形的。另一种方法是裁剪出来的图像,因为鸡蛋是仅在图像的上半部分,但我不知道怎么办。

码:

dummy,cnts,hier = cv2.findContours(close.astype(np.uint8),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#print (len(cnts))

for c in cnts:
    M = cv2.moments(c)
    area = cv2.contourArea(c)
    print (area)
    if area >46000:
        if M["m00"] != 0:
            cX = int(M["m10"] / M["m00"])
            cY = int(M["m01"] / M["m00"])
        else:
            cX, cY = 0, 0
        cv2.drawContours(img, [c], -1, (0, 255, 0), 2)
        cv2.circle(img, (cX, cY), 2, (0, 0, 0), -1)
cv2.imshow("th5",img)
python opencv
1个回答
1
投票

为什么你没有得到完整的蛋的原因是因为门槛太高。您需要降低一点点

喜欢:

limit = 100 # possible lower
ret,th1 = cv2.threshold(gray,limit,255,cv2.THRESH_BINARY)

你的问题是相当大的,但因为背景(物体上的蛋)有颜色的蛋一样。你可能想尝试的边缘检测,而不是阈值。

看一下这个:

enter image description here

在与你的形象打我能得到的边缘(仅一半):

enter image description here

码:

import cv2
import numpy as np
img = cv2.imread('eBxV8IA.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(15,15),0)
lap = cv2.Laplacian(blur,cv2.CV_64F)
blur = cv2.GaussianBlur(lap,(45,45),0)
cv2.imshow("Global",blur)

我能准确地检测出鸡蛋,但不幸的是也有很多的杂讯的enter image description here

码:

import cv2
import numpy as np
img = cv2.imread('eBxV8IA.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(15,15),0)
lap = cv2.Laplacian(blur,cv2.CV_64F)
blur = cv2.GaussianBlur(lap,(45,45),0)
blur[blur<0]=0
blur = 255.*blur/np.amax(blur)


dummy,cnts,hier = cv2.findContours(blur.astype(np.uint8),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
for c in cnts:
    M = cv2.moments(c)
    if M["m00"] != 0:
        cX = int(M["m10"] / M["m00"])
        cY = int(M["m01"] / M["m00"])
    else:
        cX, cY = 0, 0
    cv2.drawContours(img, [c], -1, (0, 255, 0), 2)
    cv2.circle(img, (cX, cY), 2, (0, 0, 0), -1)
cv2.imshow("Global",img)
© www.soinside.com 2019 - 2024. All rights reserved.