C++ Opencv c++;图像中白色区域的检测与裁剪

C++ Opencv c++;图像中白色区域的检测与裁剪,c++,opencv,crop,detection,C++,Opencv,Crop,Detection,我已经在网上搜索过了,我已经找到了一些方法来做我想做的事情,但是与我需要的相比,这些方法在效率上失败了 我有一个kinect(使用Microsoft SDK),它当前正在获取一个删除背景的人,将结果保存在一个3通道的垫子中,并将该人从背景中删除。现在我需要裁剪图像以只适合那个人,忽略黑色区域 这里是棘手的部分:我没有太多的时间浪费在每一个操作上(我还需要做其他一些操作,这是支持实时工作的。我目前实现的是一个轮廓查找器,它只提供这个区域,但实时速度非常慢。因为我只有一个白色区域要检测,而且这个区域

我已经在网上搜索过了,我已经找到了一些方法来做我想做的事情,但是与我需要的相比,这些方法在效率上失败了

我有一个kinect(使用Microsoft SDK),它当前正在获取一个删除背景的人,将结果保存在一个3通道的垫子中,并将该人从背景中删除。现在我需要裁剪图像以只适合那个人,忽略黑色区域

这里是棘手的部分:我没有太多的时间浪费在每一个操作上(我还需要做其他一些操作,这是支持实时工作的。我目前实现的是一个轮廓查找器,它只提供这个区域,但实时速度非常慢。因为我只有一个白色区域要检测,而且这个区域非常大(图像面积的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;
cv::Mat thresh\u canny;
向量轮廓;
向量层次;
cv::阈值(src,thresh_canny,0,255,0);
cv::Canny(thresh_Canny,thresh_Canny,20,80,3);
cv::findContours(阈值、轮廓、层次、cv_-RETR_树、cv_-CHAIN_-Abrox_-SIMPLE、cv::Point(0,0));
如果(等高线.size()!=1)
返回false;
cv::Rect r=cv::boundingRect(等高线位于(0));
src(r).copyTo(dst);
返回true;
非常感谢

编辑:输入图像


如果您的图像没有非黑色异常值(如噪声),您可以忽略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;
}
intmain()
{
cv::Mat in=cv::imread(“CropWhite.jpg”);
//具有所有非黑点位置的向量
std::向量非黑名单;
非黑名单保留(行*列);
//将所有非黑色点添加到向量
//TODO:有更有效的方法来遍历图像

对于(int j=0;jc)可以发布一个示例输入图像和一个示例所需结果(两个不同的图像)?如果你的人是唯一的白色区域,你根本不需要canny和findcontours。只需从所有白色像素计算boundingrect?!用输入图像编辑。我如何计算boundingrect?你能给我一些代码或链接看看吗?谢谢!代码中已经有了(最后第三行)只需输入一个包含所有非黑色像素位置的向量,而不是轮廓,它不起作用(或者我误解了)。以下是我所做的:cv::Mat gray;cv::threshold(src,gray,0,255,0);cv:cvtColor(gray,gray,cv_bgr2; gray);if(cv::countNonZero(gray)==0)返回false;cv::Rect r=cv::boundingRect(gray);src(r).copyTo(dst);谢谢!确实有效!我增强了循环,并将Kinect深度字节数组转换为OpenCV Mat,结果几乎与任何操作一样快。