python - Python OpenCV - 自定义掩码
问题描述
我在这里有一个图像。黄线内的区域是我感兴趣的区域,如图所示,这也是我的目标之一。这是我的计划/步骤:
- 去噪、滤色、掩蔽和 Canny 边缘 (DONE)
- 边缘坐标(完成)
- 选择某些顶点的坐标,例如
- 用这些顶点的坐标绘制多边形
这是代码:
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),我被卡住了。我在这里尝试过编码,但收到错误消息“ValueError:要解压的值太多(预期为 2)”。
请帮助教我找到构建尽可能接近黄线的多边形的好顶点。
解决方案
我已将答案分为两部分
第 1 部分:找到构造多边形的好顶点
包含边缘的图像周围所需的顶点可以使用 OpenCV 的内置cv2.findContours()
函数来完成。它返回带有轮廓、轮廓顶点和轮廓层次结构的图像。
可以通过两种方式找到轮廓的顶点:
cv2.CHAIN_APPROX_NONE
绘制每个轮廓上的所有坐标(边界点)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)
您可以通过在创建蒙版时进行更多预处理来获得所需边缘的更好近似值