需求分析:检测图像中的直线并计算其像素长度与处理时长,将结果绘制在图像上。
输入原图像
最终输出图像
处理思路:
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;
}