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

时间:2017-08-07 15:14:27

标签: c++ image opencv

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

2 个答案:

答案 0 :(得分:1)

我可以计算图像ROI的渐变(例如,第10列到第15列中的所有行)。 然后计算渐变的能量(渐变图像的所有像素的总和)。

如果能量非常低,则背景均匀(您无法通过此算法了解背景颜色)。否则你会有纹理背景。

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

第二种方法: 如果您确定背景为白色,则可以获得第一种方法的ROI,然后迭代所有像素,并检查其颜色。如果有超过" n"如果像素的颜色与" 255,255,255"不同,您可以将图像标记为"非白色背景"。

答案 1 :(得分:1)

你可以尝试下面的代码

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

希望它会有所帮助

#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;
}