我想检测从视频源的鸡蛋,当我尝试使用就可以了门槛,它没有得到完整的鸡蛋。
我试图从这个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://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)
为什么你没有得到完整的蛋的原因是因为门槛太高。您需要降低一点点
喜欢:
limit = 100 # possible lower
ret,th1 = cv2.threshold(gray,limit,255,cv2.THRESH_BINARY)
你的问题是相当大的,但因为背景(物体上的蛋)有颜色的蛋一样。你可能想尝试的边缘检测,而不是阈值。
看一下这个:
在与你的形象打我能得到的边缘(仅一半):
码:
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)
码:
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)