Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用c+搜索非白色背景的图像+;?_C++_Image_Opencv - Fatal编程技术网

C++ 如何使用c+搜索非白色背景的图像+;?

C++ 如何使用c+搜索非白色背景的图像+;?,c++,image,opencv,C++,Image,Opencv,我编写了一个使用openCV和boost::filesystem库的程序,该程序裁剪图像以适应图像中的对象。(Photoshop已经被用于用白色替换大部分背景)。然而,我有成千上万的图片需要整理。我已经知道如何使用文件系统库,并且在遍历系统目录时没有问题。但是,如何检测非白色背景的图像(在photoshop过程中丢失)?它的格式为有边距,宽高比为1:1,但仍有奇怪的灰色背景。图像最终应该是这样的。那么,如何确定图像的背景是否像错误的裁剪一样?I您可以计算图像的ROI梯度(例如第10列到第15列中

我编写了一个使用openCV和boost::filesystem库的程序,该程序裁剪图像以适应图像中的对象。(Photoshop已经被用于用白色替换大部分背景)。然而,我有成千上万的图片需要整理。我已经知道如何使用文件系统库,并且在遍历系统目录时没有问题。但是,如何检测非白色背景的图像(在photoshop过程中丢失)?它的格式为有边距,宽高比为1:1,但仍有奇怪的灰色背景。图像最终应该是这样的。那么,如何确定图像的背景是否像错误的裁剪一样?

I您可以计算图像的ROI梯度(例如第10列到第15列中的所有行)。 然后计算梯度的能量(梯度图像所有像素的总和)

如果能量很低,你就有了一个均匀的背景(你不能用这个算法知道背景颜色)。否则你会有一个纹理背景

这是第一种方法。您可以在OpenCV中找到执行此操作所需的所有函数

第二种方法:
如果你确信你的背景是白色的,你可以得到第一种方法的ROI,然后迭代所有的像素,检查它的颜色。如果有超过“n”个像素的颜色与“255255”不同,您可以将图像标记为“非白色背景”。

您可以尝试下面的代码吗

(要测试代码,您应该创建一个目录c:/croping和一些子目录,并在创建的目录中放置一些图像。)

希望这会有帮助

#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;

vector<Rect> divideHW(Mat src, int dim, double threshold1, double threshold2)
{
    Mat gray, reduced, canny;

    if (src.channels() == 1)
    {
        gray = src;
    }

    if (src.channels() == 3)
    {
        Laplacian(src, gray, CV_8UC1);
        cvtColor(gray, gray, COLOR_BGR2GRAY);
        imshow("sobel", gray);
    }

    reduce(gray, reduced, dim, REDUCE_AVG);

    Canny(reduced, canny, threshold1, threshold2);

    vector<Point> pts;
    findNonZero(canny, pts);

    vector<Rect> rects;

    Rect rect(0, 0, gray.cols, gray.rows);
    if (!pts.size())
    {
        rects.push_back(rect);
    }
    int ref_x = 0;
    int ref_y = 0;

    for (size_t i = 0; i< pts.size(); i++)
    {
        if (dim)
        {
            rect.height = pts[i].y - ref_y;
            rects.push_back(rect);
            rect.y = pts[i].y;
            ref_y = rect.y;
            if (i == pts.size() - 1)
            {
                rect.height = gray.rows - pts[i].y;
                rects.push_back(rect);
            }
        }

        else
        {
            rect.width = pts[i].x - ref_x;
            rects.push_back(rect);
            rect.x = pts[i].x;
            ref_x = rect.x;
            if (i == pts.size() - 1)
            {
                rect.width = gray.cols - pts[i].x;
                rects.push_back(rect);
            }
        }

    }
    return rects;
}

int main( int argc, char** argv )
{
    int wait_time = 0; // set this value > 0 for not waiting 
    vector<String> filenames;
    String folder = "c:/cropping/*.*"; // you can change this value or set it by argv[1]

    glob(folder, filenames, true);

    for (size_t i = 0; i < filenames.size(); ++i)
    {

        Mat src = imread(filenames[i]);

        if (src.data)
        {
            vector<Rect> rects = divideHW(src, 0, 0, 0);
            if (rects.size() < 3) continue;
            Rect border;
            border.x = rects[0].width;
            border.width = src.cols - rects[rects.size() - 1].width - border.x;

            rects = divideHW(src, 1, 0, 20);
            if (rects.size() < 3) continue;
            border.y = rects[0].height;
            border.height = src.rows - rects[rects.size() - 1].height - border.y;

            Mat cropped = src(border).clone();
            src(border).setTo(Scalar(255, 255, 255));
            Scalar _mean = mean(src);
            int mean_total = _mean[0] + _mean[1] + _mean[2];

            if (mean_total > 763)
            {
                imwrite(filenames[i] + ".jpg", cropped);
                imshow("cropped", cropped);
                waitKey(wait_time);
            }

        }
    }
    return 0;
}
#包括“opencv2/imgproc.hpp”
#包括“opencv2/highgui.hpp”
#包括
使用名称空间cv;
使用名称空间std;
矢量分割HW(Mat src、int dim、双阈值1、双阈值2)
{
席灰色,减少,精明;
如果(src.channels()==1)
{
灰色=src;
}
如果(src.channels()==3)
{
拉普拉斯(src,灰色,CV_8UC1);
CVT颜色(灰色、灰色、灰色);
imshow(“索贝尔”,灰色);
}
减少(灰色、减少、暗淡、减少平均值);
Canny(减少,Canny,阈值1,阈值2);
向量pts;
findNonZero(canny,pts);
向量矩形;
Rect Rect(0,0,gray.cols,gray.rows);
如果(!pts.size())
{
推回(rect);
}
int ref_x=0;
int ref_y=0;
对于(size_t i=0;i0表示不等待
矢量文件名;
String folder=“c:/croping/*.*;//您可以更改此值或通过argv[1]进行设置
glob(文件夹、文件名,true);
对于(size_t i=0;i763)
{
imwrite(文件名[i]+“.jpg”,裁剪);
imshow(“裁剪”,裁剪);
等待键(等待时间);
}
}
}
返回0;
}

IMHO,这个问题对于StackOverflow来说太广泛了。搜索图像包括:1)遍历目录2)打开图像文件3)使用库解码文件格式4)根据需要调整图像5)比较或搜索位图。这里列出的项目太多了。@ThomasMatthews我理解你的意思。但是,主要目的是确定图像是否具有完全白色的背景。如果发布代码。我可以对它进行必要的修改。@sturkmen您只需要代码的裁剪部分吗?因为整件事都超过5000行了。我将很快发布一个基于adrien barral答案的示例代码。我想这会有帮助的。实际上,您有一个裁剪代码。您可以为所有图片重新运行它。如果一张图片已经被裁剪,它将保持不变。我想知道你使用这段代码的结果。它找到了多少张图片?