由于项目的需要,需要使用霍夫直线检测进行处理图像。这里进行笔记记录,话不多说,先上代码:
- #include
- #include
- using namespace cv;
- using namespace std;
- int main()
- {
- Mat img = imread("result1.png");
- Mat gray, canny, binaryImage;
- cvtColor(img, gray, CV_RGB2GRAY);
-
- threshold(gray, binaryImage, 100, 225, THRESH_BINARY);
- imshow("binaryImage", binaryImage);
-
- Canny(binaryImage, canny, 50, 120);
-
- vector
lines; - HoughLinesP(canny, lines, 1, CV_PI / 180, 50, 200, 30);
-
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50)
- {
- //将满足条件的点画出
- line(img, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);
- cout << " " << "(" << x1 << "," << y1 << ")" << " " << "(" << x2 << "," << y2 << ")" << endl;
- //line(canny, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);
- }
- }
- imshow("img2", img);
- imwrite("shuchu.png", img);
- waitKey(0);
- return 0;
- }
上面的代码并没有进行什么滤波与二值化处理,是最简单的一种方式。
首先是对霍夫直线检测代码之中HoughLinesP函数进行解释:
void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLineLength=0, double maxLineGap=0 )
第一个参数:InputArray image,表示输入的图像。
第二个参数:OutputArray lines,表示输出的量,其中包含有相应的输出的直线的坐标。
第三个参数:double rho, 以像素为单位的距离精度。
第四个参数:double theta,以弧度为单位的角度精度。
一般前四个参数是不用管的,主要是看后面的三个参数。
第五个参数:int threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。 大于阈值 threshold 的线段才可以被检测通过并返回到结果中。
第六个参数: double minLineLength,存在默认值0,表示可以显示的最低线段长度。
第七个参数:double maxLineGap,有默认值0,允许将同一行点与点之间连接起来的最大的距离。
这里每个参数的含义可以详见博客如下所示:
网上只是给出了如何进行霍夫直线的提取,但是具体信息的提取过程,网上并没有,所以由于项目的需要,想了以下的方式可以进行对于可用信息的提取。
使用的图片是已经截取好的,因为实际的项目之中,背景的干扰是非常小的。由于此处进行的是模拟实验,我想到的办法只有是在不进行原有的像素改变的过程之中,对于图片内容的截取。具体的截取过程见我的另一篇博客:基于OpenCV使用鼠标在图片之中提取自己想要的信息进行显示_YllasdW的博客-CSDN博客基于OpenCV使用鼠标在图片之中圈出自己想要的信息进行显示https://blog.csdn.net/m0_47489229/article/details/126959813
上面写的代码的运行结果如下所示:

但是我需要进行提取的是在直板两端平行的线,由上面结果可知实际图像之中是存在五条线,那么这里如何进行提取两端的线呢?
我这个地方也是仔细想了一想,但是也是非常的简单,我的思路如下所示:
①两个直线之间的间距问题,既然是存在三条直线,提取两端的直线,那两端的直线的间距必然是相对而言比较大的。
②起始点和终止点之间的距离,这个地方只能是作为第二个条件存在,在判断出第一个条件之后,提取两边最长的线段(当然这个思路不是特别好,但是我这里想着这样其实也是可以的)。
③提取两边直线的斜率最为相近的两条直线(相比于条件②,这个更加靠谱一点)
代码思路,上面几个条件使用过程,我采用使用思路①和思路③进行结合的方式,所需要使用的信息是在输出结果之中,输出点之中起始点和终止点就是可以的。
在正式进行的过程,发现存在一个问题,就是思路①之中,直线可能并不是平行线,那么如何进行评价呢?所以对于思路①不如选定自己直线上面的同一纵坐标对应的横坐标进行比对,选取第一组的横坐标作为标准,依次进行相减,得到的数值取一个平均值,当数值大于这个数是一组,小于又是另外一组,进而可以分为左右两组直线。(发现自己好机智😀)
(由于我要提取的是4096*2160像素的图片,因此要恢复信息)见到上面的图片是没有问题的,但是当我恢复到原始的图像的大小的时候,发现是存在干扰问题的。

因此,图片进行提取的时候特别注意平行线的提取,一定要提取满足符合要求的地方,其余地方进行选取的时候,不要提取干扰的地方。


上面的数据就是很正常了。但是在写上述实现功能①代码时候,出现
这种情况也是需要进行考虑.
代码修改成为如下所示:
-
- #include
- #include
- using namespace cv;
- using namespace std;
- int main()
- {
- Mat img = imread("result1.png");
-
- //设定图片的大小
- resize(img, img, Size(4096, 2160));
- Mat gray, canny, binaryImage;
- cvtColor(img, gray, CV_RGB2GRAY);
-
- threshold(gray, binaryImage, 100, 225, THRESH_BINARY);
- imshow("binaryImage", binaryImage);
-
- Canny(binaryImage, canny, 50, 120);
-
- vector
lines; - HoughLinesP(canny, lines, 1, CV_PI / 180, 50, 200, 30);
-
-
- int q1 = 0; //垂直直线
- int q = 0; //不是垂直直线的条数
- double k[20] ,b[20];//用来存放至直线的y=kx+b,这个地方用来存放k和b,为什么要变成20,因为他里面不能够放入变量
- //这里设定当y相同的时候求取x的值,y设定为2160/2
- double X[20];
- double avX = 0;//x的平均值
-
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50)
- {
- //将满足条件的点画出
- line(img, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255 ), 2);
- cout << i << " " << "(" << x1 << "," << y1 << ")" << " " << "(" << x2 << "," << y2 << ")" << endl;
-
-
-
- if (x1 != x2)
- {
- //求取直线
- k[i] = (double)((y1 - y2) / (x1 - x2));
- b[i] = (double)(y1 - k[i] * x1);
-
- X[i] = (double)((2160.0f / 2.0f) - b[i]) / k[i];
- avX = avX + X[i];
- cout << "k[i]:" << k[i] << " " << "b[i]:" << b[i] << " X[i]:" << b[i] << " avX:" << avX << endl;
-
- q++;
-
- }
- else {
- X[i] = x1;
- avX = avX + X[i];
-
- q1++;
- }
-
- }
- }
- cout << "直线的条数:" << q +q1 <
-
- avX = (double)(avX / (double)(q + q1));
-
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50)
- {
- if (X[i] > avX)
- {
- cout << "右侧直线:" << i << endl;
- }
- else
- {
- cout << "左侧直线:" << i << endl;
- }
- }
-
- }
-
-
-
-
- imshow("img2", img);
- imwrite("shuchu.png", img);
- waitKey(0);
- return 0;
- }
运行结果如下所示:
可见线条2是竖直的直线,并且这里的直线分成了左右两个部分,接下来就是提取出左右斜率最为相近的两条直线.
-
- #include
- #include
- using namespace cv;
- using namespace std;
- int main()
- {
- Mat img = imread("result1.png");
-
- //设定图片的大小
- resize(img, img, Size(4096, 2160));
- Mat gray, canny, binaryImage;
- cvtColor(img, gray, CV_RGB2GRAY);
-
- threshold(gray, binaryImage, 100, 225, THRESH_BINARY);
- imshow("binaryImage", binaryImage);
-
- Canny(binaryImage, canny, 50, 120);
-
- vector
lines; - HoughLinesP(canny, lines, 1, CV_PI / 180, 50, 200, 30);
-
-
- int q1 = 0; //垂直直线
- int q = 0; //不是垂直直线的条数
- double k[20] ,b[20];//用来存放至直线的y=kx+b,这个地方用来存放k和b,为什么要变成20,因为他里面不能够放入变量
- //这里设定当y相同的时候求取x的值,y设定为2160/2
- double X[20];
- double avX = 0;//x的平均值
-
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50)
- {
- //将满足条件的点画出
- line(img, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255 ), 2);
- cout << i << " " << "(" << x1 << "," << y1 << ")" << " " << "(" << x2 << "," << y2 << ")" << endl;
-
-
-
- if (x1 != x2)
- {
- //求取直线
- k[i] = (double)((y1 - y2) / (x1 - x2));
- b[i] = (double)(y1 - k[i] * x1);
-
- X[i] = (double)((2160.0f / 2.0f) - b[i]) / k[i];
- avX = avX + X[i];
- cout << "k[i]:" << k[i] << " " << "b[i]:" << b[i] << " X[i]:" << b[i] << " avX:" << avX << endl;
-
- q++;
-
- }
- else {
- X[i] = x1;
- avX = avX + X[i];
-
- q1++;
- }
-
- }
- }
-
- imshow("img2", img);
- imwrite("shuchu.png", img);
-
- cout << "直线的条数:" << q +q1 <
-
- avX = (double)(avX / (double)(q + q1));
-
- double min = 0;//标记最小值---斜率差值
- int i1, i2;//左右直线
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50)
- {
- if (X[i] > avX)
- {
- cout << "右侧直线:" << i << endl;
-
- double e = k[i];//抽取右侧直线的斜率
- int i3 = i;//记录此时的右侧直线的i值
-
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50)
- {
- if (X[i] <= avX)//左侧直线操作
- {
- if (min < abs(k[i] - e))
- {
- min = abs(k[i] - e);
- i2 = i;
- i1 = i3;
- }
- }
- }
- }
-
-
-
- }
- else
- {
- cout << "左侧直线:" << i << endl;
- }
- }
-
- }
- cout << "两条最为相近的直线: " << "左边直线:" << i2 << " 右边直线:" << i1 << endl;
-
-
- waitKey(0);
- return 0;
- }
运行结果:
注意:上面提取出来的两条直线不是两个都是垂直的,如果要是有垂直的情况需要再想(后面再想)
并且注意上面标出的地方两条直线,代码如下所示:
-
- #include
- #include
- using namespace cv;
- using namespace std;
- int main()
- {
- Mat img = imread("result1.png");
- Mat img1 = img;
- //设定图片的大小
- resize(img, img, Size(4096, 2160));
- Mat gray, canny, binaryImage;
- cvtColor(img, gray, CV_RGB2GRAY);
-
- threshold(gray, binaryImage, 100, 225, THRESH_BINARY);
- imshow("binaryImage", binaryImage);
-
- Canny(binaryImage, canny, 50, 120);
-
- vector
lines; - HoughLinesP(canny, lines, 1, CV_PI / 180, 50, 200, 30);
-
-
- int q1 = 0; //垂直直线
- int q = 0; //不是垂直直线的条数
- double k[20] ,b[20];//用来存放至直线的y=kx+b,这个地方用来存放k和b,为什么要变成20,因为他里面不能够放入变量
- //这里设定当y相同的时候求取x的值,y设定为2160/2
- double X[20];
- double avX = 0;//x的平均值
-
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50)
- {
- //将满足条件的点画出
- line(img, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255 ), 2);
- cout << i << " " << "(" << x1 << "," << y1 << ")" << " " << "(" << x2 << "," << y2 << ")" << endl;
-
-
-
- if (x1 != x2)
- {
- //求取直线
- k[i] = (double)((y1 - y2) / (x1 - x2));
- b[i] = (double)(y1 - k[i] * x1);
-
- X[i] = (double)((2160.0f / 2.0f) - b[i]) / k[i];
- avX = avX + X[i];
- cout << "k[i]:" << k[i] << " " << "b[i]:" << b[i] << " X[i]:" << b[i] << " avX:" << avX << endl;
-
- q++;
-
- }
- else {
- X[i] = x1;
- avX = avX + X[i];
-
- q1++;
- }
-
- }
- }
-
- imshow("img2", img);
- imwrite("shuchu.png", img);
-
- cout << "直线的条数:" << q +q1 <
-
- avX = (double)(avX / (double)(q + q1));
-
- double min = 0;//标记最小值---斜率差值
- int i1, i2;//左右直线
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50)
- {
- if (X[i] > avX && (x1-x2 !=0 ))
- {
- cout << "右侧直线:" << i << endl;
-
- double e = k[i];//抽取右侧直线的斜率
- int i3 = i;//记录此时的右侧直线的i值
-
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50 )
- {
- if (X[i] <= avX && (x1 - x2 != 0))//左侧直线操作
- {
- if (min < abs(k[i] - e))
- {
- min = abs(k[i] - e);
- i2 = i;
- i1 = i3;
- }
- }
- }
- }
- }
- else
- {
- cout << "左侧直线:" << i << endl;
- }
- }
-
- }
- cout << "两条最为相近的直线: " << "左边直线:" << i2 << " 右边直线:" << i1 << endl;
-
- /*
- int x31 = 0,x32 = 4096,x41 = 0,x42 = 4096 ;
- int y31, y32, y41, y42;
- y31 = k[i2] * x31 + b[i2];
- y32 = k[i2] * x32 + b[i2];
- y41 = k[i1] * x41 + b[i1];
- y42 = k[i1] * x42 + b[i1];
- */
- resize(img1, img1, Size(4096, 2160));
- Vec4i I = lines[i2];
- double x31 = I[0];
- double y31 = I[1];
- double x32 = I[2];
- double y32 = I[3];
- line(img1, Point2d(x31, y31), Point2d(x32, y32), Scalar(0, 255, 255), 2);
- line(img1, Point2d(1706, 999), Point2d(1725, 1354), Scalar(0, 255, 255), 2);
- line(img1, Point2d(1767, 479), Point2d(1781, 693), Scalar(0, 255, 255), 2);
- I = lines[i1];
- double x41 = I[0];
- double y41 = I[1];
- double x42 = I[2];
- double y42 = I[3];
-
- line(img1, Point2d(x41, y41), Point2d(x42, y42), Scalar(0, 255, 255), 2);
-
-
-
- imshow("img3", img1);
- imwrite("shuchu3.png", img1);
- waitKey(0);
- return 0;
- }
输出结果:

进而得到最为相似的平行的两条直线.
接下来就是将上述的直线进行拟合成为一条直线.
-
- #include
- #include
- using namespace cv;
- using namespace std;
- int main()
- {
- Mat img = imread("result1.png");
- Mat img1 = img;
- //设定图片的大小
- resize(img, img, Size(4096, 2160));
- Mat gray, canny, binaryImage;
- cvtColor(img, gray, CV_RGB2GRAY);
-
- threshold(gray, binaryImage, 100, 225, THRESH_BINARY);
- imshow("binaryImage", binaryImage);
-
- Canny(binaryImage, canny, 50, 120);
-
- vector
lines; - HoughLinesP(canny, lines, 1, CV_PI / 180, 50, 200, 30);
-
-
- int q1 = 0; //垂直直线
- int q = 0; //不是垂直直线的条数
- double k[20] ,b[20];//用来存放至直线的y=kx+b,这个地方用来存放k和b,为什么要变成20,因为他里面不能够放入变量
- //这里设定当y相同的时候求取x的值,y设定为2160/2
- double X[20];
- double avX = 0;//x的平均值
-
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50)
- {
- //将满足条件的点画出
- line(img, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255 ), 2);
- cout << i << " " << "(" << x1 << "," << y1 << ")" << " " << "(" << x2 << "," << y2 << ")" << endl;
-
-
-
- if (x1 != x2)
- {
- //求取直线
- k[i] = (double)((y1 - y2) / (x1 - x2));
- b[i] = (double)(y1 - k[i] * x1);
-
- X[i] = (double)((2160.0f / 2.0f) - b[i]) / k[i];
- avX = avX + X[i];
- cout << "k[i]:" << k[i] << " " << "b[i]:" << b[i] << " X[i]:" << b[i] << " avX:" << avX << endl;
-
- q++;
-
- }
- else {
- X[i] = x1;
- avX = avX + X[i];
-
- q1++;
- }
-
- }
- }
-
- imshow("img2", img);
- imwrite("shuchu.png", img);
-
- cout << "直线的条数:" << q +q1 <
-
- avX = (double)(avX / (double)(q + q1));
-
- double min = 0;//标记最小值---斜率差值
- int i1, i2;//左右直线
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50)
- {
- if (X[i] > avX && (x1-x2 !=0 ))
- {
- cout << "右侧直线:" << i << endl;
-
- double e = k[i];//抽取右侧直线的斜率
- int i3 = i;//记录此时的右侧直线的i值
-
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50 )
- {
- if (X[i] <= avX && (x1 - x2 != 0))//左侧直线操作
- {
- if (min < abs(k[i] - e))
- {
- min = abs(k[i] - e);
- i2 = i;
- i1 = i3;
- }
- }
- }
- }
- }
- else
- {
- cout << "左侧直线:" << i << endl;
- }
- }
-
- }
- cout << "两条最为相近的直线: " << "左边直线:" << i2 << " 右边直线:" << i1 << endl;
-
- /*
- int x31 = 0,x32 = 4096,x41 = 0,x42 = 4096 ;
- int y31, y32, y41, y42;
- y31 = k[i2] * x31 + b[i2];
- y32 = k[i2] * x32 + b[i2];
- y41 = k[i1] * x41 + b[i1];
- y42 = k[i1] * x42 + b[i1];
- */
- resize(img1, img1, Size(4096, 2160));
- Vec4i I = lines[i2];
- double x31 = I[0];
- double y31 = I[1];
- double x32 = I[2];
- double y32 = I[3];
- line(img1, Point2d(x31, y31), Point2d(x32, y32), Scalar(0, 255, 255), 2);
-
- I = lines[i1];
- double x41 = I[0];
- double y41 = I[1];
- double x42 = I[2];
- double y42 = I[3];
-
- line(img1, Point2d(x41, y41), Point2d(x42, y42), Scalar(0, 255, 255), 2);
-
- //画出拟合直线
- double K = (double)(k[i2] + k[i1]) / 2.0;
- double B = (double)(b[i2] + b[i1]) / 2.0;
- double x51 = 0;
- double y51 = K * x51 + B;
-
- double x52 = 4096;
- double y52 = K * x52 + B;
- line(img1, Point2d(x51, y51), Point2d(x52, y52), Scalar(255, 0, 0), 3);
-
-
- imshow("img3", img1);
- imwrite("shuchu3.png", img1);
- waitKey(0);
- return 0;
- }
输出结果:

就是这样,上述思路之中主要是进行提取两条平行线的思路需要注意,一步一步来就是非常简单的.
最终版,但是上面的代码并不能检测到竖直直线的存在,反正最后写出来了,可麻烦了,代码不想看第二遍,代码如下所示:
-
-
- #include
- #include
- using namespace cv;
- using namespace std;
- int main()
- {
- Mat img = imread("左相机123.bmp");
- Mat img1 = img;
- Mat img3 = imread("左相机123.bmp");
- //设定图片的大小
- resize(img, img, Size(4096, 2160));
- Mat gray, canny, binaryImage;
- cvtColor(img, gray, CV_RGB2GRAY);
-
- threshold(gray, binaryImage, 150, 220, THRESH_BINARY);
- imshow("binaryImage", binaryImage);
-
- Canny(binaryImage, canny, 50, 120);
-
- vector
lines; - HoughLinesP(canny, lines, 1, CV_PI / 180, 50, 200, 30);
-
-
- int q1 = 0; //垂直直线
- int q2 = 0;
- int qs = 0;
- bool S = false;//是否存在左右直线
- int q = 0; //不是垂直直线的条数
- double k[20] ,b[20];//用来存放至直线的y=kx+b,这个地方用来存放k和b,为什么要变成20,因为他里面不能够放入变量
- //这里设定当y相同的时候求取x的值,y设定为2160/2
- double X[20];//放入的是数竖直的线
- double avX = 0;//x的平均值 __ 不包括竖直直线
- double avXS = 0;//数值直线
- double maxR = 0;//记录竖直差
- double maxL = 0;
- double xr, xl;
-
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50)
- {
- //将满足条件的点画出
- line(img, Point2d(x1, y1), Point2d(x2, y2), Scalar(0, 255, 255), 2);
- cout << i << " " << "(" << x1 << "," << y1 << ")" << " " << "(" << x2 << "," << y2 << ")" << endl;
-
-
-
- if (x1 != x2)
- {
- //求取直线
- k[i] = (double)((y1 - y2) / (x1 - x2));
- b[i] = (double)(y1 - k[i] * x1);
-
- X[i] = (double)((2160.0f / 2.0f) - b[i]) / k[i];
- avX = avX + X[i];
- cout << "k[i]:" << k[i] << " " << "b[i]:" << b[i] << " X[i]:" << b[i] << " avX:" << avX << endl;
-
- q++;
-
- }
-
- else {//竖直直线
- X[i] = x1;
- avX = avX + X[i];
- avXS = avXS + X[i];
-
- qs++;
-
- if ((avX / qs - X[i]) > 5)/**************************************************************************************************************************************************/
- {
- S = true;
- }
-
-
-
-
- }
-
-
- }
- }
- avXS = avXS / qs;
- cout << "中间竖直直线x坐标" << avXS << endl;
-
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50)
- {
- if(S == true && x1 == x2)//两条直线之间的距离大于5个像素
- {
- if ((maxR < abs(x1 - avXS)) && x1 >= avXS)//选出最小的右侧竖直直线
- {
- maxR = abs(x1 - avXS);
- cout << "maxR:" << maxR << endl;
- q2++;
- }
- else if (x1 >= avXS) {
- q2++;
- cout << "maxR:" << maxR << endl;
- }
- if ((maxL < abs(x1 - avXS)) && x1 <= avXS)//选出最小的右侧竖直直线
- {
- maxL = abs(x1 - avXS);
- cout << "maxL:" << maxL << endl;
- q1++;
- }
- else if (x1 <= avXS)
- {
- q1++;
- cout << "maxL:" << maxL << endl;
- }
-
-
- }
- }
-
-
-
- }
-
-
-
- imshow("img2", img);
- imwrite("shuchu.png", img);
- waitKey(0);
-
- cout << "直线的总条数:" << q + q1 + q2 <
-
-
-
- cout << "左侧竖直直线条数:" << q1 << endl;
- cout << "右侧竖直直线条数:" << q2 << endl;
-
-
- avX = (double)(avX / (double)(q + q1 + q2));
- cout << "总直线x平均坐标" << avX << endl;
- cout << "竖直直线x平均坐标" << avXS << endl;
- double min = 0;//标记最小值---斜率差值
-
-
-
- double xrpoint, xlpoint;
- int i1, i2;//左右直线
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50)
- {
- if ((q1 > 0) && (q2 > 0) && (x1 - x2 == 0 ))//说明是存在两条竖直的直线
- {
-
- if ( (x1 >= avXS) && (maxR == abs(x1 - avXS)))//选出最大的右侧竖直直线
- {
- //划线并且记录
- line(img3, Point2d(x1, 0), Point2d(x1, 2160), Scalar(0, 255, 255), 2);
- xrpoint = x1;
- cout << "总直线x平均坐标1" << xrpoint << endl;
- cout << "划线" << endl;
- }
- if ((x1 <= avXS) && (maxL == abs(x1 - avXS)))//选出最小的左侧竖直直线
- {
- //划线并且记录
- line(img3, Point2d(x1, 0), Point2d(x1, 2160), Scalar(0, 255, 255), 2);
- xlpoint = x1;
- cout << "总直线x平均坐标2" << xlpoint << endl;
- cout << "划线" << endl;
- }
-
- }
- else if ((x1-x2 !=0 ))//右侧不是竖直直线---这个地方是之前写的,可以运行
- {
- cout << "右侧不是竖直的直线:" << i << endl;
-
- double e = k[i];//抽取右侧直线的斜率
- int i3 = i;//记录此时的右侧直线的i值
-
- for (size_t i = 0; i < lines.size(); i++)
- {
- Vec4i I = lines[i];
- double x1 = I[0];
- double y1 = I[1];
- double x2 = I[2];
- double y2 = I[3];
- //筛选满足条件的点
- if (abs(x1 - x2) + abs(y1 - y2) > 50 )
- {
- if (X[i] <= avX && (x1 - x2 != 0))//左侧不是竖直直线操作
- {
- if (min < abs(k[i] - e))
- {
- min = abs(k[i] - e);
- i2 = i;
- i1 = i3;
-
- }
- }
- }
- }
- }
- else
- {
- cout << "左侧直线:" << i << endl;
- }
- }
-
- }
-
-
- /*
- int x31 = 0,x32 = 4096,x41 = 0,x42 = 4096 ;
- int y31, y32, y41, y42;
- y31 = k[i2] * x31 + b[i2];
- y32 = k[i2] * x32 + b[i2];
- y41 = k[i1] * x41 + b[i1];
- y42 = k[i1] * x42 + b[i1];
- */
-
- if (q1 > 0 && q2 > 0)
- {
- //resize(img3, img3, Size(4096, 2160));
- line(img3, Point2d((xlpoint+ xrpoint)/2.0, 0), Point2d((xlpoint + xrpoint) / 2.0, 2160), Scalar(255, 0, 255), 2);
- cout << "存在两条竖直直线:" << "情况一:" << endl;
- imwrite("输出最终结果直线.png", img3);
- resize(img3, img3, Size(1024, 540));//显示改变大小
- imshow("img3", img3);
- waitKey(0);
- }
-
- else {
- resize(img1, img1, Size(4096, 2160));
- Vec4i I = lines[i2];
- double x31 = I[0];
- double y31 = I[1];
- double x32 = I[2];
- double y32 = I[3];
- line(img1, Point2d(x31, y31), Point2d(x32, y32), Scalar(0, 255, 255), 2);
-
- I = lines[i1];
- double x41 = I[0];
- double y41 = I[1];
- double x42 = I[2];
- double y42 = I[3];
-
- line(img1, Point2d(x41, y41), Point2d(x42, y42), Scalar(0, 255, 255), 2);
-
- //画出拟合直线
- double K = (double)(k[i2] + k[i1]) / 2.0;
- double B = (double)(b[i2] + b[i1]) / 2.0;
- double x51 = 0;
- double y51 = K * x51 + B;
-
- double x52 = 4096;
- double y52 = K * x52 + B;
- line(img1, Point2d(x51, y51), Point2d(x52, y52), Scalar(255, 0, 0), 3);
- cout << "斜率K:" << K << " B:" << B << endl;
-
-
- imwrite("shuchu3.png", img1);
- resize(img1, img1, Size(1024, 540));//显示改变大小
- imshow("img3", img1);
- waitKey(0);
- }
-
- return 0;
- }
效果图:

左右两条是提取的竖直直线,中间就是自己想要的那一条直线.
-
相关阅读:
硫化锌量子点/ZnS QDs 巯基SH/氨基/NH2/羧基COOH修饰硫化锌量子点/ZnS QDs
Day42——MySQL数据库基础操作
【Gazebo要素02】系统构成
基于SSM的概念可视化程序设计学习系统毕业设计源码021009
OCP Java17 SE Developers 复习题14
梳理下我自已对Reactor与及IO多路复用的select\poll\epoll的理解
Android两个应用同时使用后置摄像录像
java毕业设计儿童疫苗接种提醒系统小程序服务端Mybatis+系统+数据库+调试部署
程序员的三重境界:码农,高级码农、程序员!
容量推荐引擎:基于吞吐量和利用率的预测缩放
-
原文地址:https://blog.csdn.net/m0_47489229/article/details/127674452