简体   繁体   English

在 opencv numpy 中找到轮廓的边界点

[英]Finding the boundary points of a contour in opencv numpy

在此处输入图像描述 complete noob at open cv and numpy here.在此处完成 open cv 和 numpy 的菜鸟。 here is the image: here is my code:这是图像:这是我的代码:

import numpy as np
import cv2

im = cv2.imread('test.jpg')
imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
imgray = cv2.medianBlur(imgray, ksize=7)

ret, thresh = cv2.threshold(imgray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
_, contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

print ("number of countours detected before filtering %d -> "%len(contours))
new = np.zeros(imgray.shape)

new = cv2.drawContours(im,contours,len(contours)-1,(0,0,255),18)

cv2.namedWindow('Display',cv2.WINDOW_NORMAL)
cv2.imshow('Display',new)
cv2.waitKey()

mask = np.zeros(imgray.shape,np.uint8)
cv2.drawContours(mask,[contours[len(contours)-1]],0,255,-1)
pixelpoints = cv2.findNonZero(mask)
cv2.imwrite("masked_image.jpg",mask)

print(len(pixelpoints))
print("type of pixelpoints is %s" %type(pixelpoints))

the length of pixelpoints is nearly 2 million since it contains all the point covered by the contours.像素点的长度接近 200 万,因为它包含了轮廓覆盖的所有点。 But i only require the bordering point of that contour.但我只需要该轮廓的边界点。 How do I do it?我该怎么做? I have tried several methods from opencv documentation but always errors with tuples and sorting operations.我尝试了 opencv 文档中的几种方法,但元组和排序操作总是出错。 please...help?请帮忙?

I only require the border points of the contour:(我只需要轮廓的边界点:(

Is this what you mean by border points of a contour?这就是轮廓的边界点的意思吗?
(我用你上面的图片试试)

The white lines you see are points that I have marked out in white against the blue drawn contours.您看到的白线是我在蓝色绘制轮廓上用白色标记的点。 There's a little spot at the bottom right because I think its most likely that your black background isn't really black and so when I did thresholding and a floodfill to get this,右下角有一个小点,因为我认为你的黑色背景很可能不是真正的黑色,所以当我进行阈值处理和填充来得到这个时,
在此处输入图像描述

there was a tiny white speck at the same spot.同一个地方有一个小小的白色斑点。 But if you play around with the parameters and do a more proper thresholding and floodfill it shouldn't be an issue.但是,如果您使用参数并进行更适当的阈值处理和填充,则应该不是问题。 In openCV's drawContours function, the cnts would contain lists of contours and each contour will contain an array of points.在 openCV 的 drawContours function 中,cnts 将包含轮廓列表,每个轮廓将包含一个点数组。 Each point is also of type numpy.ndarray.每个点的类型也是 numpy.ndarray。 If you want to place all points of each contour in one place so it returns you a set of points of boundary points (like the white dots outline in the image above), you might want to append them all into a list.如果要将每个轮廓的所有点放在一个位置,以便返回一组边界点(如上图中的白点轮廓),您可能希望将它们全部放入一个列表中。 You can try this:你可以试试这个:

#rgb is brg instead
contoured=cv2.drawContours(black, cnts, -1, (255,0,0), 3)

#list of ALL points of ALL contours
all_pixels=[]

for i in range(0, len(cnts)):
    for j in range(0,len(cnts[i])):
        all_pixels.append(cnts[i][j])

When I tried to当我试图

print(len(all_pixels))

it returned me 2139 points.它给了我 2139 分。

Do this if you want to mark out the points for visualization purposes (eg like my white points):如果您想为可视化目的标记点(例如我的白点),请执行此操作:

#contouredC is a copy of the contoured image above
contouredC[x_val, y_val]=[255,255,255]

If you want less points, just use a step function when iterating through to draw the white points out.如果你想要更少的点,只需在迭代时使用一步 function 来绘制白点。 Something like this:像这样的东西:
在此处输入图像描述

In python, for loops are slow so I think there's better ways of replacing the nested for loops with a np.where() function or something instead.在 python 中,for 循环很慢,所以我认为有更好的方法可以用 np.where() function 或其他东西替换嵌套的 for 循环。 Will update this if/when I figure it out.如果/当我弄清楚时会更新这个。 Also, this needs better thresholding and binarization techniques.此外,这需要更好的阈值处理和二值化技术。 Floodfill technique referenced from: Python 2.7: Area opening and closing binary image in Python not so accurate . Floodfill 技术参考自: Python 2.7:Python 中的区域打开和关闭二进制图像不太准确

Hope it helps.希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM