我正在使用 Python 学习 OpenCV,我想学习如何对图像中的对象/元素进行计数。
我写了一个计数代码,但是我得到了错误的结果。图像中有12个元素,我得到了40个,但还有一些元素没有被计算在内。
我不知道我做错了什么。
这是我的代码:
import cv2
img = cv2.imread('slika.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
print('There are 12 elements on this image')
#cv2.imshow('img', gray)
#cv2.waitKey(0)
ret,thresh = cv2.threshold(gray,127,255,1)
contours,h = cv2.findContours(thresh,1,1)
print('Number of elements found:', len(contours))
for cnt in contours:
cv2.drawContours(img,[cnt],0,(0,0,255),2)
cv2.imshow('img', img)
cv2.waitKey(0)
这是默认图片,有 12 个元素:
这是结果:
你看到粉色和两个黄色元素没有被识别,但这是绿色元素的问题。
我做错了什么,如何解决?
最佳答案
有几点可以改进您当前的代码。
如果您实际查看您的
灰度
图像,您会发现您的127
阈值太低了。黄色和粉色结构的灰度值高于127
,然后被您的cv2.threshold
忽略。出于同样的原因,绿色结构是支离 splinter 的。而且,一般来说,最好使用实际的枚举值,如cv2.THRESH_BINARY_INV
而不是它们的数值。为了轮廓检测更好地使用
cv2.RETR_EXTERNAL
检索模式,所以你只考虑最外层的轮廓。同样,使用枚举值。
通过这些更改,您的代码可以正常工作:
import cv2
# Read image
img = cv2.imread('DIVmd.jpg')
# Convert image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Show grayscale image
cv2.imshow('gray', gray)
print('There are 12 elements on this image')
# Inverse binary threshold image with threshold at 224,
# i.e. every pixel with value above 224 is set to 0,
# and every pixel with value below 224 is set to 1
_, thresh = cv2.threshold(gray, 224, 255, cv2.THRESH_BINARY_INV)
# Show thresholded image
cv2.imshow('thresh', thresh)
# Find contours
# cv2.RETR_EXTERNAL: retrieves only the extreme outer contours
# cv2.CHAIN_APPROX_NONE: stores absolutely all the contour points
contours, h = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
print('Number of elements found:', len(contours))
# Iterate all found contours
for cnt in contours:
# Draw contour in original/final image
cv2.drawContours(img, [cnt], 0, (0, 0, 255), 2)
# Show final image
cv2.imshow('img', img)
cv2.waitKey(0)
出于可视化目的,这是您的灰色
图像:
这是实际的阈值图像thresh
:
最后输出img
:
当然,打印输出现在也是正确的:
There are 12 elements on this image
Number of elements found: 12
希望对您有所帮助!
关于python - 计算更多的元素,那么它应该是,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58500358/