从列表中检索轮廓时,轮廓显示的是点而不是曲线,否则显示曲线 [英] Contour shows dots rather than a curve when retrieving it from the list, but shows the curve otherwise
问题描述
我正在找到一个阈值图像的轮廓并将其绘制为:
I'm finding the contour of a thresholded image and drawing it like so:
self.disc_contour = cv2.findContours(self.thresh.copy(), cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE)[1]
cv2.drawContours(self.original_image, self.disc_contour, -1, (0,255,0), 2)
然后我得到所需的轮廓:
and I get the contour as desired:
(忽略内圆.外部是上下文中的轮廓)
(ignore the inner circle. The outer part is the contour in context)
但是,如果我将drawContour函数中的self.disc_contour
更改为self.disc_contour[0]
,则会得到以下结果:
But if I change self.disc_contour
in the drawContour function to self.disc_contour[0]
I get the following result:
可能是什么原因?
推荐答案
NB:特定于OpenCV 3.x
cv2.findContours
的第二个结果是轮廓列表.
cv.drawContours
的第二个参数应该是轮廓列表.
The second result from cv2.findContours
is a list of contours.
The second parameter of cv.drawContours
should be a list of contours.
轮廓表示为点的列表(或数组).每个点都是一个坐标列表.
A contour is represented as a list (or array) of points. Each point is a list of coordinates.
有多种方法可以仅绘制单个轮廓:
There are multiple ways how to draw only a single contour:
import cv2
src_img = cv2.imread("blob.png")
gray_img = cv2.cvtColor(src_img, cv2.COLOR_BGR2GRAY)
contours = cv2.findContours(gray_img, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)[1]
print(contours)
# Choose one:
# Draw only first contour from the list
cv2.drawContours(src_img, contours, 0, (0,255,0), 2)
# Pass only the first contour (v1)
cv2.drawContours(src_img, [contours[0]], -1, (0,255,0), 2)
# Pass only the first contour (v2)
cv2.drawContours(src_img, contours[0:1], -1, (0,255,0), 2)
cv2.imshow("Contour", src_img)
cv2.waitKey()
示例输入图像:
当我们检查cv2.findContours
的结果时,看到点的原因就很明显了-共有4级嵌套.
When we inspect the result of cv2.findContours
, the reason why you were seeing dots becomes apparent -- there are 4 levels of nesting.
[
array([
[[ 95, 61]], # Point 0
[[ 94, 62]], # Point 1
[[ 93, 62]],
... <snip> ...
[[ 98, 61]],
[[ 97, 61]],
[[ 96, 61]]
]) # Contour 0
]
根据此答案开头的定义,我们可以看到在这种情况下,这些点被包装在其他列表中,例如[[ 98, 61]]
. OpenCV显然可以正确处理此问题-我想这是作为一项功能来实现的.
According to the definitions at the beginning of this answer, we can see that the points in this case are wrapped in an additional list, e.g. [[ 98, 61]]
. OpenCV apparently deals with this correctly - I suppose this was intended as a feature.
如果仅通过使用contours
的第一个元素来删除外部列表,则可以有效地将每个点转换为包含单个点的单独轮廓.
If we remove the outer list by using only the first element of contours
, we effectively turn each point into a separate contour containing a single point.
array([
[
[ 95, 61] # Point 0
], # Contour 0
[
[ 94, 62] # Point 0
], # Contour 1
... and so on
])
这篇关于从列表中检索轮廓时,轮廓显示的是点而不是曲线,否则显示曲线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!