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