我有一台足够大的扫描仪可以同时扫描多张图片。 不幸的是,所有图片都存储在一个jpg文件中,仅由 白色边框。有没有办法自动查找子图像并存储它们 在单独的文件?我正在考虑使用OpenCV来完成工作,但是 我找不到合适的功能。有人知道哪个OpenCV功能可行,或者是否有其他方法(使用linux)?
谢谢, 康斯坦丁
答案 0 :(得分:0)
我的快速而肮脏的解决方案与我的图像一起使用就像这样。我希望有类似问题的人可以将此作为如何使用OpenCV的起点。
// g++ `pkg-config --cflags --libs opencv` parse.cp
// include standard OpenCV headers, same as before
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
// all the new API is put into "cv" namespace. Export its content
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
string imagename = argc > 1 ? argv[1] : "lena.jpg";
// the newer cvLoadImage alternative with MATLAB-style name
Mat imgf = imread("original/"+imagename);
if( !imgf.data ) // check if the image has been loaded properly
return -1;
int border = 1000;
Mat img(imgf.rows+2*border,imgf.cols+2*border,CV_8UC3,Scalar(255,255,255));
for (int i=0; i<imgf.cols; ++i) {
for (int j=0; j<imgf.rows; ++j) {
img.at<Vec3b>(j+border,i+border) = imgf.at<Vec3b>(j,i);
}
}
cout << "created border\n";
Mat mask;
img.copyTo(mask);
Scalar diff(2,2,2);
floodFill(mask, Point(0,0), Scalar(0,0,255), NULL, diff, diff);
cout << "flood filled\n";
imwrite("flood.png",mask);
for (int i=0; i<mask.cols; ++i) {
for (int j=0; j<mask.rows; ++j) {
if(mask.at<Vec3b>(j,i) != Vec3b(0,0,255)) {
mask.at<Vec3b>(j,i) = Vec3b(0,0,0);
} else {
mask.at<Vec3b>(j,i) = Vec3b(255,255,255);
}
}
}
cvtColor( mask, mask, CV_RGB2GRAY );
cout << "mask created\n";
imwrite("binary.png",mask);
Mat sobelX;
Mat sobelY;
Mat sobel;
Sobel(mask,sobelX,CV_16S,1,0);
Sobel(mask,sobelY,CV_16S,0,1);
sobel = abs(sobelX)+abs(sobelY);
for (int i=0; i<mask.cols; ++i) {
for (int j=0; j<mask.rows; ++j) {
mask.at<char>(j,i) = abs(sobelX.at<short>(j,i))+abs(sobelY.at<short>(j,i));
}
}
threshold(mask, mask, 127, 255, THRESH_BINARY);
cout << "sobel done\n";
imwrite("sobel.png",mask);
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(mask, contours, hierarchy,
CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
imwrite("contours.png",mask);
cout << "contours done\n";
// iterate through all the top-level contours
int idx = 0;
for( ; idx >= 0; idx = hierarchy[idx][0] )
{
RotatedRect box = minAreaRect(contours[idx]);
if(box.size.width > 100 && box.size.height > 100) {
Mat rot = getRotationMatrix2D(box.center,box.angle,1.0);
Mat rotimg;
warpAffine(img,rotimg,rot,Size(img.cols,img.rows));
imwrite("rotimg.png",rotimg);
Mat subimg(box.size.width,box.size.height,CV_8UC3);
getRectSubPix(rotimg,box.size,box.center,subimg);
stringstream name;
name << "subimg_"<< imagename << "_" << idx << ".png";
cout << name.str() << "\n";
imwrite(name.str(),subimg);
}
}
imwrite("img.png",img);
imwrite("mask.png",mask);
cout << "Done\n";
return 0;
}