Opencv检测边界和ROI掩码
Posted
技术标签:
【中文标题】Opencv检测边界和ROI掩码【英文标题】:Opencv Detect boundary and ROI mask 【发布时间】:2015-10-12 09:38:34 【问题描述】:您好,我在下面的图片中附加了一个黄色边框。 Opencv 中是否有任何算法或(算法序列)可以检测黄色像素并创建一个 ROI 蒙版(这将阻止它之外的所有像素)。
【问题讨论】:
如果总是那种黄色调,您可以轻松使用 inRange 方法。然后使用 findContours 获取外轮廓。之后,您可以从该轮廓绘制填充蒙版并将蒙版应用于图像以仅将蒙版区域复制到新的黑色图像。 您的轮廓颜色是否始终相同?保证在图片中是唯一的(没有其他黄色背景点)?每张图片只有一个黄色轮廓,还是可以有多个? @Miki :背景中可能有黄色像素。如果我们发现这种情况,我们将来可以使用不同的颜色。是的,每张图片只有一个黄色轮廓 【参考方案1】:你可以这样做:
-
找到黄色多边形
填充多边形内部
仅将多边形内部复制到黑色初始化图像
找到黄色多边形
很遗憾,您使用抗锯齿来绘制黄线,因此黄色不是纯黄色,而是由于插值而具有更广泛的范围。这也会影响最终结果,因为结果图像中将包含一些 非黄色 像素。您可以通过不使用抗锯齿功能轻松纠正此问题。
因此,最好的选择是在 HSV 空间(更容易分割单一颜色)中转换图像,并仅保留纯黄色附近范围内的值。
如果不使用抗锯齿,甚至不需要转换为 HSV,只需保留值为纯黄色的点即可。
填充多边形内部
您可以使用floodFill
填充多边形。你需要一个起点。由于我们不知道一个点是否在多边形内(并且由于多边形不是凸的,所以取质心可能不安全),我们可以安全地假设点 (0,0),即左上角图像在多边形之外。然后我们可以填充多边形的外部,然后反转结果。
仅将多边形内部复制到黑色初始化图像
获得遮罩后,只需将copyTo
与该遮罩一起使用,即可将遮罩中非零像素下的内容复制到黑色图像上。
这里是完整的代码:
#include <opencv2\opencv.hpp>
using namespace cv;
int main()
Mat3b img = imread("path_to_image");
// Convert to HSV color space
Mat3b hsv;
cvtColor(img, hsv, COLOR_BGR2HSV);
// Get yellow pixels
Mat1b polyMask;
inRange(hsv, Scalar(29, 220, 220), Scalar(31, 255, 255), polyMask);
// Fill outside of polygon
floodFill(polyMask, Point(0, 0), Scalar(255));
// Invert (inside of polygon filled)
polyMask = ~polyMask;
// Create a black image
Mat3b res(img.size(), Vec3b(0,0,0));
// Copy only masked part
img.copyTo(res, polyMask);
imshow("Result", res);
waitKey();
return 0;
结果:
注意事项
请注意,结果图像中几乎有黄色像素。这是由于抗锯齿,如上所述。
【讨论】:
您是如何找到 HSV 范围内的黄色值范围的?我正在使用这个网站,colorspire.com/rgb-color-wheel。我的直觉是保持色调恒定在 42(或 60 度)并调整饱和度,值会给出范围。但我错了 详情请见here。黄色是 HSV 60°,100%,100%,在 OpenCV 中编码为 30,255,255。 H 通道值减半并在 [0,180] 范围内,S 和 V 在 [0,255] 范围内以上是关于Opencv检测边界和ROI掩码的主要内容,如果未能解决你的问题,请参考以下文章
python基于图像的掩码mask信息获取病灶区域ROI最小外接矩形坐标位置opencv基于掩码最小外接矩形坐标剪裁原图(crop image by mask rectangle)