VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 4445|回复: 4

关于OPENCV中HoughLines函数中获取直线的算法问题

[复制链接]
86_avatar_middle
最佳答案
0 
online_vip 发表于 2019-3-25 15:53:57 | 显示全部楼层 |阅读模式
3驿站币
书中提供的代码有个地方计算问题不懂 HoughLines 代码中返回的lines   
float rho = lines[0], theta = lines[1];
Point pt1, pt2;
double a = cos(theta), b = sin(theta);
这个a=cos(theta)  b = sin(theta)不就是已经计算出了直角坐标系点的X值和Y值  
为什么又x0=a*rho, y0=b*rho这两个代码是什么意思  

  1. #include "opencv2/highgui/highgui.hpp"
  2. #include "opencv2/imgproc/imgproc.hpp"
  3. #include <iostream>

  4. using namespace cv;
  5. using namespace std;

  6. int main(int argc, char** argv)
  7. {
  8.     const char* filename ="pic1.png";
  9.     Mat src = imread(filename, 0);

  10.     Mat dst, cdst;
  11.     /*采用 Canny 算法做边缘检测
  12.     //void cvCanny( const CvArr* image, CvArr* edges, double threshold1,
  13.     //double threshold2, int aperture_size=3 );
  14.     //threshold1 第一个阈值
  15.     //threshold2 第二个阈值
  16.     //aperture_size Sobel 算子内核大小 (见 cvSobel).
  17.     //函数 cvCanny 采用 CANNY 算法发现输入图像的边缘而且在输出图像中标识这些边缘。
  18.     //threshold1和threshold2 当中的小阈值用来控制边缘连接,大的阈值用来控制强边缘的初始分割。*/
  19.     Canny(src, dst, 50, 200, 3);
  20.     cvtColor(dst, cdst, CV_GRAY2BGR);//灰度化
  21. #if 0
  22.     vector<Vec2f> lines;
  23.     /*利用 Hough 变换在二值图像中找到直线
  24.     CvSeq* cvHoughLines2( CvArr* image, void* line_storage, int method,
  25.                       double rho, double theta, int threshold,
  26.                       double param1=0, double param2=0 );
  27.     line_storage :检测到的线段存储仓.
  28.     Hough 变换变量,是下面变量的其中之一:
  29.         CV_HOUGH_STANDARD - 传统或标准 Hough 变换. 每一个线段由两个浮点数 (ρ, θ) 表示,
  30.             其中 ρ 是直线与原点 (0,0) 之间的距离,θ 线段与 x-轴之间的夹角。因此,矩阵类
  31.             型必须是 CV_32FC2 type.
  32.         CV_HOUGH_PROBABILISTIC - 概率 Hough 变换(如果图像包含一些长的线性分割,则效率更高).
  33.             它返回线段分割而不是整个线段。每个分割用起点和终点来表示,所以矩阵(或创建的序列)
  34.             类型是 CV_32SC4.
  35.         CV_HOUGH_MULTI_SCALE - 传统 Hough 变换的多尺度变种。
  36.             线段的编码方式与 CV_HOUGH_STANDARD 的一致。
  37.         rho 与象素相关单位的距离精度。
  38.         theta 弧度测量的角度精度。*/
  39.     HoughLines(dst, lines, 1, CV_PI/180, 100, 0, 0 );

  40.     for( size_t i = 0; i < lines.size(); i++ )//将求得的线条画出来
  41.     {
  42.         float rho = lines[i][0], theta = lines[i][1];
  43.         Point pt1, pt2;
  44.         double a = cos(theta), b = sin(theta);
  45.         double x0 = a*rho, y0 = b*rho;
  46.         pt1.x = cvRound(x0 + 1000*(-b));
  47.         pt1.y = cvRound(y0 + 1000*(a));
  48.         pt2.x = cvRound(x0 - 1000*(-b));
  49.         pt2.y = cvRound(y0 - 1000*(a));
  50.         line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA);
  51.     }
  52. #else
  53.     vector<Vec4i> lines;
  54.     HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 );
  55.     for( size_t i = 0; i < lines.size(); i++ )
  56.     {
  57.         Vec4i l = lines[i];
  58.         line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA);
  59.     }
  60. #endif
  61.     imshow("source", src);
  62.     imshow("detected lines", cdst);

  63.     waitKey();

  64.     return 0;
  65. }
复制代码

关于OPENCV中HoughLines函数中获取直线的算法问题 关于OPENCV中HoughLines函数中获取直线的算法问题 关于OPENCV中HoughLines函数中获取直线的算法问题

最佳答案

查看完整内容

先回答问题 double a = cos(theta), b = sin(theta); 这个a=cos(theta) b = sin(theta) 是单位线段的直角坐标系点的X值和Y值 ,这里r=1。 x0=a*rho, y0=b*rho这两个代码分别是x=r *cos(θ) ,y=r *sin(θ) 再看要回答的一个陷阱。 你问的是这里。 for( size_t i = 0; i < lines.size(); i++ )//将求得的线条画出来 { float rho = lines[0], theta = lines[1]; Point pt1, pt2; double a = co ...




上一篇:为什么VS2015安装C#安装不了
下一篇:需要使用128位类型怎么办?
75_avatar_middle
最佳答案
0 
在线会员 发表于 2019-3-25 15:53:58 | 显示全部楼层
本帖最后由 xx_player 于 2019-3-27 10:08 编辑

先回答问题
double a = cos(theta), b = sin(theta);
这个a=cos(theta)  b = sin(theta) 是单位线段的直角坐标系点的X值和Y值  ,这里r=1。
x0=a*rho, y0=b*rho这两个代码分别是x=r *cos(θ) ,y=r *sin(θ)
再看要回答的一个陷阱。
你问的是这里。
for( size_t i = 0; i < lines.size(); i++ )//将求得的线条画出来
{
        float rho = lines[0], theta = lines[1];
        Point pt1, pt2;
        double a = cos(theta), b = sin(theta);
        double x0 = a*rho, y0 = b*rho;
        pt1.x = cvRound(x0 + 1000*(-b));
        pt1.y = cvRound(y0 + 1000*(a));
        pt2.x = cvRound(x0 - 1000*(-b));
        pt2.y = cvRound(y0 - 1000*(a));
        line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA);
}
这里难明白的是1000这个常数。通用画线函数,搞了1个硬编码。似乎还要学生把它背到。
比较坑人。至少用#define LINE_LEN 1000 替换放在外面,还不止于那么坏。问题还远不止这。
从上述代码看出lines里面保存的线段和角度,没有固定的两个点,它的方法就是把线段正方向,负方向
放大1000倍,作为曲线上的两个点。这时再看你那个图片,线都出了原位置,不是等比例的,是乱画。
由于图片清晰,还是可以骗不少人地。还可以根据不同人搞300,500,800等让大小比较接近。看起来像。
街上算命地就是这样搞的。实际上这样搞,有没有用还不一定。
再看搞没搞对,演示了算法,存在质疑。看下面图片

关于OPENCV中HoughLines函数中获取直线的算法问题

这图显示怎么放大线段到1000即当r=1000时的计算方法。
明显,x0 + 1000*(-b)几个等式中的a和b,
作者对它,到底  a 是 cos(theta)还是 a 是 sin(theta);
b是cos(theta)还是 b 是 sin(theta);
没搞清楚,就出书了,可能是粘贴过来,认为它应该是对地。世界上应该的,有很多呀。
当然,认为我演算错了,我就闭嘴。我从不坚持真理。人爱搞就搞下去,耗得他的精力。
没演算也就忽略过去了,不在意会抽时间去做个debug。世界上要做的事也还多,哪做的完。
公式可以直接用三角函数这样写
#define PI 3.1415926  //180度的弧度值
        pt1.x = cvRound(rho  + 1000)*cos(theta));
        pt1.y = cvRound((rho + 1000)*sin(theta));
        pt2.x = cvRound((rho  - 1000)*cos(PI+theta));
        pt2.y = cvRound((rho  - 1000)*sin(PI+ theta));
1)展开 = rho*cos(theta) + 1000*cos(theta);
其中 x0=rho*cos(theta)
2)展开 = rho*sin(theta) + 1000*sin(theta);
其中 y0=rho*sin(theta)
........................


关于OPENCV中HoughLines函数中获取直线的算法问题



评分

参与人数 1驿站币 +2 热心值 +2 收起 理由
86_avatar_small x635775712 + 2 + 2 很给力!

查看全部评分

86_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2019-3-25 16:49:42 | 显示全部楼层
书上介绍的太少  就几行      网上 找到了一篇介绍这个的原理   
原来是我基础太弱了  以前学的都忘没影了  先恶补下这方面的知识再说
https://blog.csdn.net/maginy/article/details/37758079
86_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2019-3-27 11:34:52 | 显示全部楼层
xx_player 发表于 2019-3-26 21:08
先回答问题
double a = cos(theta), b = sin(theta);
这个a=cos(theta)  b = sin(theta) 是单位线段的直 ...

膜拜! 查了两天的资料  还问了同学  都不如你这一张图  讲的明白

86_avatar_middle
最佳答案
0 
ico_lz  楼主| 发表于 2019-3-27 11:41:16 | 显示全部楼层
xx_player 发表于 2019-3-26 21:08
先回答问题
double a = cos(theta), b = sin(theta);
这个a=cos(theta)  b = sin(theta) 是单位线段的直 ...

膜拜大牛  查了一整天资料 问了同学 都不如你这一张图 通俗易懂!!
HoughLinesP这个函数直接输出了线段的两端坐标 估计也是这个算法
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号 )|网站地图wx_jqr

GMT+8, 2020-10-25 16:43

Powered by CcTry.CoM

© 2009-2020 cctry.com

快速回复 返回顶部 返回列表