美文网首页
C++ opencv-3.4.1 提取图片中的直线

C++ opencv-3.4.1 提取图片中的直线

作者: yanghedada | 来源:发表于2019-06-20 23:13 被阅读0次

    对于一张扫描的图,可能需要把答案写在上面,使阅卷方便,首先要做的就是把直线提出来。

    如图:


    直接进行直线出现许多的问题,所以我们需要对图片进行处理。

    1. 二值化
    2. 形态学操作,过滤文字
    3. 进行霍夫变换检测直线
    4. 对直线过滤
    #include <opencv2/opencv.hpp>
    #include <iostream>
    #include <math.h>
    
    using namespace cv;
    using namespace std;
    Mat src, dst, gray_src, roiImage;
    char input_image[] = "input image";
    char output_image[] = "output image";
    int max_count = 255;
    int threshold_value = 100;
    void morhpologyLines(int, void*);
    void detectLines(int, void*);
    
    int main(int argc, char ** argv){
    
        src = imread("case2.jpg",IMREAD_GRAYSCALE);
        if (src.empty()){
            printf("colud not load image ..\n");
            return -1;
        }
    
        namedWindow(input_image, CV_WINDOW_AUTOSIZE);
        namedWindow(output_image, CV_WINDOW_AUTOSIZE);
        imshow(input_image, src);
    
        Rect roi = Rect(10, 10, src.cols - 20, src.rows - 20);
        roiImage = src(roi);
        imshow("ROI image", roiImage);
    
        //createTrackbar("threshold", output_image, &threshold_value, max_count, detectLines);
        //detectLines(0, 0);
        morhpologyLines(0,0);
    
        waitKey(0);
        return 0;
    }
    
    void detectLines(int, void*){ // 效果太差了
        Canny(roiImage, dst, threshold_value, threshold_value * 2, 3, false);
        // threshold(roiImage, dst, 0, 255, THRESH_BINARY | THRESH_OTSU);
        imshow("canny", dst);
        vector<Vec4i> lines;
        HoughLinesP(dst, lines, 1, CV_PI / 180.0, 30, 30.0, 0);
        cvtColor(dst, dst, COLOR_GRAY2BGR);
        for (size_t t = 0; t < lines.size(); t++){
            Vec4i ln = lines[t];
            line(dst,Point(ln[0], ln[1]), Point(ln[2], ln[3]), Scalar(0, 0, 255), 2, 8, 0);
    
        }
        imshow(output_image, dst);
    }
    
    
    void morhpologyLines(int, void*){
        // binary image
        Mat binaryImage, morhpImage;
        threshold(roiImage, binaryImage, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
        imshow("binary", binaryImage);
    
    
        // morphology operation
        Mat kernel = getStructuringElement(MORPH_RECT, Size(20,1), Point(-1, -1));
        morphologyEx(binaryImage, morhpImage, MORPH_OPEN, kernel, Point(-1, -1));
        imshow("morpgology reslut", morhpImage);
        
        //dilate image
        kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
        dilate(morhpImage, morhpImage, kernel);
        imshow("morphology lines", morhpImage);
    
        // hough lines
        vector<Vec4i> lines, restLines;
        HoughLinesP(morhpImage, lines, 1, CV_PI / 180.0, 40, 40.0, 0);
        Mat resultImage = roiImage.clone();
        cvtColor(resultImage, resultImage, COLOR_GRAY2BGR);
        for (size_t t = 0; t < lines.size(); t++){
            Vec4i ln = lines[t];
            // cout << ln << endl;
            cout << ln[2] - ln[0] << endl;
            if ((ln[2] - ln[0]) > 100)
            {   
                bool yes = true;
                for (size_t r = 0; r < restLines.size(); r++){
                    Vec4i ln1 = restLines[r];
                    if (ln1[1] - ln[1] < 5)
                        yes = false;
                }
                if (yes){
                    line(resultImage, Point(ln[0], ln[1]), Point(ln[2], ln[3]), Scalar(0, 0, 255), 2, 8, 0);
                    putText(resultImage, "A", Point((ln[0] + ln[2]) / 2, (ln[1] + ln[3]) / 2), CV_FONT_HERSHEY_COMPLEX, 1.0, Scalar(12, 255, 300), 1, 8);
                    restLines.push_back(ln); 
                }
            }
        }
        imshow(output_image, resultImage);
    }
    

    二值化

    形态学操作

    霍夫检测直线

    相关文章

      网友评论

          本文标题:C++ opencv-3.4.1 提取图片中的直线

          本文链接:https://www.haomeiwen.com/subject/vmpdqctx.html