基于opencv的图像线段检测与像素长度计算方法

4 篇文章 0 订阅

需求分析:检测图像中的直线并计算其像素长度与处理时长,将结果绘制在图像上。
输入原图像
在这里插入图片描述
最终输出图像
在这里插入图片描述
处理思路:
1.读入原图像
在这里插入图片描述
2.转灰度
在这里插入图片描述
3.二值化
在这里插入图片描述
4.膨胀操作
在这里插入图片描述
5.边缘检测
在这里插入图片描述
6.直线检测,显示检测的直线数量,依据线段AB的A点x,y与B点x,y进行线段筛选
在这里插入图片描述
7.最终的4条直线,计算直线长度与处理时长并将其绘制在图像上

#include<opencv2/opencv.hpp>
#include<iostream>
#include<opencv2/highgui/highgui.hpp>
#include<vector>
#include <opencv2/imgproc.hpp>
using namespace std;
using namespace cv;

int main()
{
    double t = getTickCount();
    //原图
    Mat src;
    src = imread("D:/program/1.jpg");
    imshow("src", src);

    //转灰度
    Mat src_gray;
    cvtColor(src, src_gray, COLOR_BGR2GRAY);
//    imshow("src_gray", src_gray);

    //二值化
    Mat src_threshold;
    threshold(src_gray,src_threshold,160,255,THRESH_BINARY);//frame_gray(x,y)>160  frame_threshold(x,y)=255 else 0
//    imshow("src_threshold",src_threshold);

    //膨胀操作
    Mat element,src_dil;
    element = getStructuringElement(MORPH_RECT, Size(3, 3));
    dilate(src_threshold, src_dil, element);
    dilate(src_dil, src_dil, element);
//    imshow("src_dil", src_dil);

    //边缘检测
    Mat src_canny;
    Canny(src_dil, src_canny, 150, 200, 3);
//    imshow("src_canny", src_canny);

    //直线检测
    vector<Vec4f> plines;
    HoughLinesP(src_canny, plines, 4, CV_PI / 180.0, 350, 100, 20);
    //显示检测的直线数量
    cout<<"plines.size():"<<plines.size()<<endl;
    //依据线段AB的A点x,y与B点x,y进行线段筛选
    while(plines.size()>4)
    {
        for (size_t i = 0; i < plines.size(); i++)
        {
            Vec4f p = plines[i];
//            cout<<p[0]<<","<<p[3]<<endl;
            for (size_t j = 0; j < plines.size(); j++)
            {
                Vec4f q = plines[j];

//                cout<<q[0]<<","<<q[3]<<endl;
                if(p[0]!=q[0]&&p[1]!=q[1]&&p[2]!=q[2]&&p[3]!=q[3] && abs(p[0]-q[0])<=40&& abs(p[0]-q[0])>=20||abs(p[1]-q[1])<=40&&abs(p[2]-q[2])<=40&&abs(p[3]-q[3])<=40)
                {
                    plines.erase(plines.begin() + j);
                }
            }
        }
    }
    cout<<"plines.size()2:"<<plines.size()<<endl;
    cv::Mat img_black(src.rows, src.cols, CV_8UC1, cv::Scalar(0));
    //最终的4条直线
    for (size_t i = 0; i < plines.size(); i++)
    {
        Vec4f p = plines[i];
        line(img_black, Point(p[0], p[1]), Point(p[2], p[3]), Scalar(255), 1, LINE_AA);
        //计算直线长度
        int a = abs(p[2] - p[0]);
        int b = abs(p[3] - p[1]);
        double len = sqrt(pow(a, 2) + pow(b, 2));
        cout<<"point"<<i<<":"<<p[0]<<","<<p[1]<<","<<p[2]<<","<<p[3]<<" len:"<<len<<endl;
        putText(src,to_string(len),Point(p[0]+20,p[1]-20),FONT_HERSHEY_SIMPLEX,0.6,Scalar(0,0,0),1,8,false);
        cv::RNG rng(time(0));
        circle(src, Point(p[0],p[1]), 10, Scalar(255,0,255), -1);
        circle(src, Point(p[2],p[3]), 10, Scalar(0,255,0), -1);
    }
//    imshow("img_black", img_black);
    //时间
    double time = (getTickCount() - t) / getTickFrequency();
    cout<<"time:"<<time<<endl;
    putText(src,to_string(time)+"s",Point(10,40),FONT_HERSHEY_SIMPLEX,1,Scalar(0,0,255),1,8,false);
    imshow("dst", src);
    waitKey(0);
    return 0;
}

  • 10
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

visual_eagle

欢迎交流学习

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值