Open CV 提取直线

要求

需求是这样的:我们要提取出下图填空题中的空行,以便统计空行数。

clipboard.png

显然,这是我自己随手写的,但是直线还算比较直。我觉得这个应该也能做吧。

开始做

好,那就试试吧,首先我增加下亮度,整个图灰蒙蒙的看着难受。

clipboard.png

通过如下代码操作:


Mat src_output;
src.convertTo(src_output, -1,3,0);//3是亮度

在2、3、4、6个亮度中我选了个3,看着还行。

接着我们要将背景色变为黑色(就是反相)

为啥要反相?
来,你不反相试试:

clipboard.png

据沙雕老师嗯嗯叽叽的解释,形态学操作的背景要求是黑色的xxxx之类的。(我才不信)

好,在二值化的同时我们乖乖反相一下:


//二值化
cvtColor(src_output, graySrc, CV_BGR2GRAY);
threshold(graySrc, graySrc, 0,255, THRESH_BINARY_INV | THRESH_OTSU);
imshow("th_out", graySrc);

其中 THRESH_BINARY_INV 就是二值化并反相的参数

接着我们要做形态学操作了:


//先准备一个Kernel(Size比较重要,这里的20,1表示长20px、高为1px。那么这个kernel就表示你要找长20高1的图形)
Mat kernel = getStructuringElement(MORPH_RECT, Size(20, 1));
//告诉形态学Ex你要对谁操作,保存到谁那,进行什么操作(是开还是闭还是别的),你的kernel叫啥
morphologyEx(graySrc, graySrc, MORPH_OPEN, kernel);

形态学操作后,我们得到几个直线:

clipboard.png

是不是多了一条?没办法,谁让我quantum写连着了。

好,既然只剩直线了,那我们就上霍夫老哥的直线检测了。

//霍夫直线检测
//注意api
vector<Vec4i> lines;
HoughLinesP(graySrc, lines,1,CV_PI / 180.0,10,7.0,0);
这里需要注意,API是HoughLinesP(graySrc, lines,1,CV_PI / 180.0,10,7.0,0);
后面有个P!千万别忘了!害死我了找了半天问题。

讲霍夫检测到的直线全部存放在lines里,接下来我们就foreach画出来。

for (size_t i = 0; i < lines.size(); i++)
{
    Vec4i currPoints = lines[i];
    //这里可以骚着写
    line(src, Point(currPoints[0],currPoints[1]), Point(lines[i][2],lines[i][3]), Scalar(0, 0, 255));
}

我就画在原图上。

结果

clipboard.png

全部代码

(src是原图)

    #pragma region 直线检测
    
    Mat src_output;
    src.convertTo(src_output, -1,3,0);//3是亮度
    imshow("src_out2", src_output);//现在这个亮度还不错
    
    //二值化
    cvtColor(src_output, graySrc, CV_BGR2GRAY);
    threshold(graySrc, graySrc, 0,255, THRESH_BINARY_INV | THRESH_OTSU);
    imshow("th_out", graySrc);

    //形态学操作
    Mat kernel = getStructuringElement(MORPH_RECT, Size(20, 1));
    
    morphologyEx(graySrc, graySrc, MORPH_OPEN, kernel);
    imshow("mor", graySrc);

    //霍夫直线检测
    //注意api
    vector<Vec4i> lines;
    HoughLinesP(graySrc, lines,1,CV_PI / 180.0,10,7.0,0);
    for (size_t i = 0; i < lines.size(); i++)
    {
        Vec4i currPoints = lines[i];
        //这里可以骚着写
        line(src, Point(currPoints[0],currPoints[1]), Point(lines[i][2],lines[i][3]), Scalar(0, 0, 255));

    }
    imshow("src", src);

    #pragma endregion

    waitKey(0);
    

Mortal
6 声望2 粉丝