• opencv实践::切边


    问题描述
      真实案例,扫描仪扫描到的法律文件,需要切边,去掉边 缘空白,这样看上去才真实。

    #include <opencv2/opencv.hpp>
    #include <iostream>
    #include <math.h>
    
    using namespace cv;
    using namespace std;
    
    #define IMAGE_PATH "D:/case2.png"
    
    Mat src, gray_src, tmp_src, dst;
    int threshold_value = 100;
    int max_level = 255;
    const char* roi_win = "Final Result";
    
    void FindROI(int, void*);
    
    void Check_Skew(int, void*);
    
    
    int main(int argc, char** argv) {
        src = imread(IMAGE_PATH);
        if (src.empty()) {
            printf("could not load image...
    ");
            return -1;
        }
        namedWindow("input image", CV_WINDOW_AUTOSIZE);
        imshow("input image", src);
        
        //纠正图像角度
        Check_Skew(0, 0);
    
        //图像切边
        FindROI(0, 0);
    
        waitKey(0);
        return 0;
    }
    
    void Check_Skew(int, void*) {
        //寻找最大轮廓
        Mat canny_output;
        cvtColor(src, gray_src, COLOR_BGR2GRAY);
        //Canny 算法做边缘检测 
        Canny(gray_src, canny_output, threshold_value, threshold_value * 2, 3, false);
    
        //在二值图像中寻找轮廓 
        vector<vector<Point>> contours;
        vector<Vec4i> hireachy;
        findContours(canny_output, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
    
        //创建一张黑色的图,每个像素的每个通道都为0,Scalar(0,0,0)
        //Mat drawImg = Mat::zeros(src.size(), CV_8UC3);
    
        float maxw = 0;//矩形宽
        float maxh = 0;//矩形高
        double degree = 0;
        for (size_t t = 0; t < contours.size(); t++) {
            RotatedRect minRect = minAreaRect(contours[t]);
            //矩形角度绝对值
            degree = abs(minRect.angle);
            if (degree > 0) {
                maxw = max(maxw, minRect.size.width);
                maxh = max(maxh, minRect.size.height);
            }
            if (degree > 0) {
                if (maxw == minRect.size.width && maxh == minRect.size.height) {
                    degree = minRect.angle;
                }
            }
        }
        printf("max contours width : %f
    ", maxw);
        printf("max contours height : %f
    ", maxh);
        printf("max contours angle : %f
    
    
    ", degree);
    
        //寻找几何中心
        Point2f center(src.cols / 2, src.rows / 2);
        //旋转degree角度
        Mat rotm = getRotationMatrix2D(center, degree, 1.0);
        //对图像做仿射变换
        warpAffine(src, tmp_src, rotm, src.size(), INTER_LINEAR, 0, Scalar(255, 255, 255));
        imshow("Correct Image", tmp_src);
    }
    
    void FindROI(int, void*) {
        //灰度图
        cvtColor(tmp_src, gray_src, COLOR_BGR2GRAY);
        Mat canny_output;
        //Canny 算法做边缘检测 
        Canny(gray_src, canny_output, threshold_value, threshold_value * 2, 3, false);
    
        //在二值图像中寻找轮廓 
        vector<vector<Point>> contours;
        vector<Vec4i> hireachy;
        findContours(canny_output, contours, hireachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
    
        //定义最小轮廓
        float minw = tmp_src.cols*0.5;
        float minh = tmp_src.rows*0.5;
        
        float minstW = 0.0;
        bool  bfirst = true;
        RotatedRect minstRect;
        Rect bbox;
        for (size_t t = 0; t < contours.size(); t++) {
            RotatedRect minRect = minAreaRect(contours[t]);
            if (minRect.size.width > minw && minRect.size.height > minh && minRect.size.width < (src.cols - 20)) {
                {
                    //找宽度最小的矩形,既是要找的图像。
                    printf("t = %d, w = %f , h = %f 
    ",t, minRect.size.width, minRect.size.height);
                    if (bfirst)
                    {
                        minstW = minRect.size.width;
                        minstRect = minRect;
                        bfirst = false;
                    }
                    else
                    {
                        float tmp = min(minstW, minRect.size.width);
                        if (tmp < minstW)
                        {
                            minstW = tmp;
                            minstRect = minRect;
                        }
                    }
                }
            }
        }
        bbox = minstRect.boundingRect();
        if (bbox.width > 0 && bbox.height > 0) {
            Mat roiImg = tmp_src(bbox);
            imshow(roi_win, roiImg);
        }
        return;
    }
  • 相关阅读:
    uva-442 Matrix Chain Multiplication
    mongodb笔记2
    用MODELLER构建好模型后对loop区域进行自动的优化过程
    Java乔晓松-android的四大组件之一Service(服务的绑定)
    内部排序之交换排序
    C,C++中的static
    [置顶] 贝叶斯分类(一)
    RabbitMQ和kafka从几个角度简单的对比--转
    rabbitmq Clustering Guide--官方
    How To Cluster Rabbit-MQ--reference
  • 原文地址:https://www.cnblogs.com/osbreak/p/11655087.html
Copyright © 2020-2023  润新知