opencv - OpenCV查找子图像

标签 opencv image-recognition

我有一台足以同时扫描多张图片的扫描仪。
不幸的是,所有图片都存储在一个jpg文件中,仅以
白色边框。有什么方法可以自动找到子图像并将其存储
在单独的文件中?我当时正在考虑使用OpenCV来完成工作,但是
我找不到正确的功能。是否有人知道哪个OpenCV函数将起作用,或者是否有其他方法(使用linux)?

谢谢,
康斯坦丁

最佳答案

我处理图像的快速而肮脏的解决方案如下所示。我希望有类似问题的人可以以此为起点来使用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;
}

关于opencv - OpenCV查找子图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11746072/

相关文章:

OpenCV 和感兴趣区域 (ROI)?

python - 如何从 OpenCV "cv2.keypoint"对象中提取 x,y 坐标?

python - convolve2d和filter2D之间的差异。为什么输出形状有所不同?

image-processing - 提高 OpenCV 中 cvMatchShapes 的匹配精度

image-processing - 是否有可能从扫描或照片中识别出一幅简单的童趣画的主题?

opencv - 每个 EmguCV dll 所需的所有 OpenCV dll 的列表

opencv - OpenCV 245首次构建错误

java - 如何提高在 MNIST 上训练的模型的数字识别?

machine-learning - 如何让图像识别深度网络检测微小差异

c - Obj-C 图像识别库?