Opencv c ++检测并裁剪图像上的白色区域
Posted
技术标签:
【中文标题】Opencv c ++检测并裁剪图像上的白色区域【英文标题】:Opencv c++ detect and crop white region on image 【发布时间】:2014-04-28 14:56:31 【问题描述】:我已经在网上搜索过,我已经找到了一些方法来做我想做的事,但是与我需要的相比,这些方法效率不高。
我有一个 kinect(使用 Microsoft SDK),它当前正在获取一个移除背景的人,将结果保存在一个 3 通道 Mat 中,并且该人从背景中移除。现在我需要裁剪图像以仅适合该人,忽略黑色区域。
这是棘手的部分:我没有太多时间可以浪费在每个操作上(我还需要做其他几个操作,这应该可以实时工作。我目前实现的是一个轮廓查找器,它提供只有这个区域,但它的实时速度真的很慢。因为我只有一个白色区域可以检测并且那个区域真的很大(50%的图像区域)我认为有一些更快的方法可以做到这一点,因为我只想要裁剪这个白色区域的 x 和 y 的最小值和最大值。
这是我目前的裁剪功能:
cv::Mat thresh_canny;
cv::vector<cv::vector<cv::Point> > contours;
cv::vector<cv::Vec4i> hierarchy;
cv::threshold(src, thresh_canny, 0, 255, 0);
cv::Canny(thresh_canny, thresh_canny, 20, 80, 3);
cv::findContours(thresh_canny, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
if (contours.size() != 1)
return false;
cv::Rect r = cv::boundingRect(contours.at(0));
src(r).copyTo(dst);
return true;
非常感谢!!
编辑:输入图片
【问题讨论】:
你能发布一个示例输入图像和一个示例期望结果(2 个不同的图像)吗? 如果你的人是唯一的白人区域,你根本不需要 canny 和 findcontours。只计算所有白色像素的boundingrect?!? 使用输入图像编辑。如何计算边界矩形?你能给我一些代码或链接看看吗?谢谢! 它已经在代码中(倒数第三行)只需输入一个包含所有非黑色像素位置的向量而不是轮廓 它没有用(或者我误解了)。这是我所做的: cv::Mat gray; cv::threshold(src, gray, 0, 255, 0);简历:cvtColor(灰色,灰色,CV_BGR2GRAY);如果 (cv::countNonZero(gray) == 0) 返回 false; cv::Rect r = cv::boundingRect(gray); src(r).copyTo(dst); 【参考方案1】:如果您的图像没有非黑色异常值(如噪声),您可以忽略 canny 和 findContours,而只需从所有非黑色像素位置创建边界矩形:
int main()
cv::Mat in = cv::imread("CropWhite.jpg");
// vector with all non-black point positions
std::vector<cv::Point> nonBlackList;
nonBlackList.reserve(in.rows*in.cols);
// add all non-black points to the vector
//TODO: there are more efficient ways to iterate through the image
for(int j=0; j<in.rows; ++j)
for(int i=0; i<in.cols; ++i)
// if not black: add to the list
if(in.at<cv::Vec3b>(j,i) != cv::Vec3b(0,0,0))
nonBlackList.push_back(cv::Point(i,j));
// create bounding rect around those points
cv::Rect bb = cv::boundingRect(nonBlackList);
// display result and save it
cv::imshow("found rect", in(bb));
cv::imwrite("CropWhiteResult.png", in(bb));
cv::waitKey(-1);
return 0;
不知道是否有更有效的方法来创建向量,在 openCV 中给出,但这仍然应该比 canny 和 findContours 快得多。
使用此输入:
我得到这个结果:
轮廓周围有一些区域,因为您提供了一个 jpg 图像,我猜轮廓的边界不是真正的黑色,因为压缩。
【讨论】:
谢谢!那确实奏效了!我增强了循环并混合了 Kinect Depth 字节数组到 OpenCV Mat 的转换,结果几乎和做任何事情一样快。以上是关于Opencv c ++检测并裁剪图像上的白色区域的主要内容,如果未能解决你的问题,请参考以下文章