我有一个 image这里。黄线内的区域是我感兴趣的区域,如图 image 所示。在这里,这也是我的目标之一。这是我的计划/步骤:
- 降噪、滤色、遮蔽和 Canny 边缘处理(完成)
- 边缘坐标(完成)
- 选择某些顶点的坐标,对于example
- 用这些顶点的坐标绘制多边形
代码如下:
import cv2
import numpy as np
from matplotlib import pyplot as plt
frame = cv2.imread('realtest.jpg')
denoisedFrame = cv2.fastNlMeansDenoisingColored(frame, None, 10, 10, 7, 21)
HSVframe = cv2.cvtColor(denoisedFrame, cv2.COLOR_BGR2HSV)
lower_yellowColor = np.array([15,105,105])
upper_yellowColor = np.array([25,255,255])
whiteMask = cv2.inRange(HSVframe, lower_yellowColor, upper_yellowColor)
maskedFrame = cv2.bitwise_and(denoisedFrame, denoisedFrame, mask=whiteMask)
grayFrame = cv2.cvtColor(maskedFrame, cv2.COLOR_BGR2GRAY)
gaussBlurFrame = cv2.GaussianBlur(grayFrame, (5,5), 0)
edgedFrame = cv2.Canny(grayFrame, 100, 200)
#Coordinates of each white pixels that make up the edges
ans = []
for y in range(0, edgedFrame.shape[0]):
for x in range(0, edgedFrame.shape[1]):
if edgedFrame[y, x] != 0:
ans = ans + [[x, y]]
ans = np.array(ans)
#print(ans.shape)
#print(ans[0:100, :])
cv2.imshow("edged", edgedFrame)
cv2.waitKey(0)
cv2.destroyAllWindows()
如您所见,我已成功完成第 (2) 步,获取构成边缘的每个白色像素的坐标。而对于下一步,第 (3) 步,我卡住了。我试过编码 here ,但收到错误提示“ValueError:要解压的值太多(预期为 2)”。
请教我如何找到合适的顶点来构建尽可能靠近黄线的多边形。
最佳答案
我把答案分成两部分
第 1 部分:寻找构建多边形的好顶点
包含边缘的图像周围所需的顶点可以使用 OpenCV 的内置 cv2.findContours()
完成功能。它返回具有轮廓、轮廓顶点和轮廓层次的图像。
可以通过两种方式找到等高线的顶点:
cv2.CHAIN_APPROX_NONE
在每个轮廓上绘制ALL坐标(边界点)cv2.CHAIN_APPROX_SIMPLE
在每个等高线上仅绘制最必要的坐标。它不存储所有点。仅存储最能代表轮廓的最需要的坐标。
在您的情况下,可以选择选项 2。找到边缘后,您可以执行以下操作:
image, contours, hier = cv2.findContours(edgedFrame, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
contours
包含图像中每个轮廓的顶点 edgedFrame
第 2 部分:构建多边形
Opencv 对此也有一个内置函数 cv2.convexHull()
找到这些点后,您可以使用 cv2.drawContours()
绘制它们.
for cnt in contours:
hull = cv2.convexHull(cnt)
cv2.drawContours(frame, [hull], -1, (0, 255, 0), 2)
cv2.imshow("Polygon", frame)
您可以通过在创建掩码时进行更多预处理来获得所需边缘的更好近似值
关于Python OpenCV - 自定义掩码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50406883/