机器视觉入门之路(三九--A,霍夫变换(hough transform)寻找直线,c++)

2023-11-13

xy坐标系直线:

y=kx+b

请看图:假定红色线段上的所有样本点(100个)都满足上面的直线方程。

(a图)

也就是说,红色的点(x1,y1)(x2,y2)(x3,y3)......(x98,y98)(x99,y99)(x100,y100)带入方程,只能求出一个k值和一个b值,假定为(k1,b1)。

换一种表达,在kb坐标系,(k1,b1)只是一个点。如图(仅仅示意而已):

(b图)

这就是hough(霍夫)变换的思想。即a图和b图是一一对应的,而霍夫寻找直线,就是通过(k1,b1)寻找a图中的红色样本点。

以上是原理,下面是常用的直线hough(霍夫)表达式:p=cos(theta)*x+y*sin(theta)

之所以如此,是为了对付诸如k=tg(90)之类的问题,下面推导一下y=kx+b如何演变为p=cos(theta)*x+y*sin(theta),看图:

因为k=-ctg(theta),

b=p/sin(theta),

所以y=-ctg(theta)*x+p/sin(theta)

即y=-x*cos(theta)/sin(theta)+p/sin(theta),

两边乘以sin(theta),得

y*sin(theta)=-x*cos(theta)+p,整理得:

p=cos(theta)*x+y*sin(theta)

在这通用式中,我们是通过(p,theta)来寻找直线的。

下面是hough(霍夫)找直线的代码,抄的图像处理(左飞),一直有一个问题不能释疑,今天一并解决。vc++代码如下:

void CLineBufProcess::HoughLine(BYTE* image0, BYTE* &image1, int &w, int &h,int Gaugetype,int scale)
{//Gaugetype==1,梯度图像,Gaugetype==2,canny图像,此处直接使用canny图像;scale=1
    
    double sinValue[360];
    double cosValue[360];
    int i,x,y;
    
    int p = (int)(sqrt((double)(w*w+h*h)+1));   
    
    BYTE* tempImage=(BYTE*)malloc(sizeof(BYTE)*w*h);

    CannySideGrandiant(image0, tempImage,w,h);//canny后使用hough找线
    
    if(image1!=NULL) free(image1);
    image1 = (BYTE*)malloc(sizeof(BYTE)*p*360);
    memset(image1,0,(p)*360);
    
    BYTE** HoughBuf = (BYTE**)malloc(sizeof(BYTE*)*(p));
    for(int y=0; y<p; y++)
    {
        HoughBuf [y] = image1+y*360; 
    }
    for(i=0; i<360 ; i++)
    {
        sinValue[i] = sin(i*3.1415926/180);
        cosValue[i] = cos(i*3.1415926/180);
    }
    int tp;
    //int k = 100;
    for(y=0; y<h; y++)
        for(x=0; x<w; x++)
        {
            
            for(i=0; i<360; i++)
            {
                if( tempImage[(y*w+x)] >this->m_grayThres)//
                {
                    tp = (int)( x*sinValue[i] + y*cosValue[i]);
                    if (tp<0||HoughBuf[tp][i]==255) continue;
                    HoughBuf[tp][i] += scale;
                }
            }
        }
        w = 360;
        h = p;
        free(HoughBuf);
        free(tempImage);
}

代码中红色的公式 tp = (int)( x*sinValue[i] + y*cosValue[i])是否与p=cos(theta)*x+y*sin(theta)不同?是的。但为什么他能找直线?并且是正确的,我试过没有千遍,但不会下50遍,当我有一天发现这个问题,大吃一惊,而且不能释怀,纠结啊!

现在释疑如下:

1,我们在visionpro toolgroup思考突破(一)中,有这样一句话,逻辑的好处是,即使你是错的,他永远在正确的错,p=sin(theta)*x+y*cos(theta)就是这种错的逻辑,但他永远在正确的错。

2,p=sin(theta)*x+y*cos(theta)与p=cos(theta)*x+y*sin(theta)是映射关系,一一对应,不会有第二种。

基于以上两点分析,这或许是我抄错了,最后发现左飞写错了(谁都有大意的时候)。若你要使用正确的(p,theta),请你更正错误,否则,不必修改。

最后,忽然联想到一个公式,p*exp(i*theta)=p*cos(theta)+P*i*sin(theta),不要和上面的公式混淆了。

坐标系中:

(x,y)---------------------(p,theta)

(x,y)=(p*cos(theta),p*sin(theta))

向量系中:

x+i*y=p*cos(theta)+p*sin(theta)*i

p*cos(theta)+p*sin(theta)*i=p*exp(i*theta)

最后这个叫欧拉公式,可以用无穷级数来证明。(有机会整理一下)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

机器视觉入门之路(三九--A,霍夫变换(hough transform)寻找直线,c++) 的相关文章

  • vue2 升级到 vue3 router 动态授权路由 异步加载报错 TypeError: Cannot read properties of undefined (reading ‘apply‘)

    使用 resolve gt require views item component resolve 会报错 TypeError Cannot read properties of undefined reading apply 我的解决历
  • 替换字符串中指定的字符串

    例如下面的例子 有时需要把某个字符串中的部分字符替换成另一个字符 可以使用std string 自带的函数replace replace第一个参数为起点 第二个为替换的长度 第三个为替换为的内容 for auto inventoryStat
  • 跟我学Spring Cloud(2020.0.0-M6版)-01-服务注册与服务发现-Eureka Server

    目录 1 所需要版本 2 创建基于web的Maven项目 SpringCloud 的服务注册中心 3 检查IntelliJ IDEA 的环境配置 4 检查java verison配置 5 检查Edit Configurations配置 6
  • 区块链技术基本概念

    链客 专为开发者而生 有问必答 此文章来自链客区块链技术问答社区 未经允许拒绝转载 区块链技术根本概念 了解这些名词是一个不错的开端 公钥加密系统 Alice有一把公钥和一把私钥 她可以用她的私钥创建数字签名 而Bob可以用她的公钥来验证这
  • 自定义 swap 函数

    背景 STL 中提供了 swap 算法 用于交换两个对象的值 其一般实现方法如下 namespace std template
  • c语言缩进用tab还是空格,程序员编码首行缩进使用Tab键好还是空格好?

    本文转载自CocoaChina 每个程序员都有自己喜欢的编码风格以及编码习惯 那么 问题来了 一个很常用也很简单的问题 让程序员分为两派 编程时 到时是使用Tab按键来进行首行缩进好呢还是敲空格按键好呢 少侠 别急 带老夫给你慢慢分析 Ta
  • Git入门与使用 (二) Git相关命令的介绍与使用

    文章目录 一 前言 二 理解Git的工作区 暂存区 本地仓库和远程仓库 三 Git相关命令的介绍与使用 1 初始化Git仓库 2 设置签名 2 1 设置仓库 项目级别的签名 2 2 设置系统用户级别的签名 3 查看Git仓库的状态 4 向暂
  • [转]Windows下安全权限设置详解

    一 Windows下安全权限设置详解 简 介 随着动网论坛的广泛应用和动网上传漏洞的被发现以及SQL注入式攻击越来越多的被使用 WEBSHELL让防火墙形同虚设 一台即使打了所有微软补丁 只让80端口对外开放的WEB服务器也逃不过被黑的命运
  • 刷脸庞大的交易市场从而也带来新的商机

    现在我们外出买东西付款 已经有了非常便捷的扫码支付功能 这个功能不仅是年轻人喜欢使用 就连中老年人也跟上的时代的步伐 许多超市 便利店已经菜市场 都能够看到二维码的身影 但是随着时代不断地进步 扫码付款这一新兴方式 接二连三地被曝出许多风险
  • Unity自动滚动字幕的实现

    Unity自动滚动字幕的实现 首先按照图片里的进行创建 然后用代码获取Scrollbar 在将Value值一直变为1 using System Collections using System Collections Generic usi
  • Jupyter程序安装和使用指南【操作示例】

    Jupyter Notebook 简称Jupyter 是一个交互式编辑器 它支持运行40多种编程语言 便于创建和共享文档 Jupyter本质上是一个Web应用程序 与其他编辑器相比 它具有小巧 灵活 支持实时代码 方便图表展示等优点 下面分
  • ECCV 2020 Representation Learning on Visual-Symbolic Graphs for Video Understanding

    动机 自然视频中的事件通常产生于演员和目标之间的时空交互 并且涉及多个共同发生的活动和目标类 因此 需要开发能够对时空视觉和语义上下文进行有效建模的算法 捕捉这种上下文的一种方法是使用基于图的建模 它在计算机视觉中有着丰富的历史 传统的基于
  • qt day3

  • java自动装配_Spring中自动装配的4种方式

    Spring容器可以在不使用和元素的情况下自动装配相互协作的bean之间的关系 助于减少编写一个大的基于Spring的应用程序的XML配置的数量使用元素的autowire属性为一个bean定义指定自动装配模式 在Spring中 我们有4种方
  • 计算机网络期末总结复习(全)

    文章目录 第一章 概述 1 1 计算机网络在信息时代的作用 我国互联网发展状况 1 2 因特网概述 1 网络 互连网 互联网 和因特网 2 因特网发展的三个阶段 3 因特网的标准化工作 4 因特网的组成 补充
  • 78页PPT全面揭示互联网与传统行业的融合与碰撞

    正如报告的主题 融合与碰撞 移动互联网和传统行业正在融合与碰撞之间进行行业重塑 纵观教育行业 现阶段已经有四种运营模式逐渐成熟 但仍存在自身问题和很多外部矛盾 找准发展趋势意义重大 一起来看看水深火热的TMT产业发展趋势吧
  • 【前端demo】背景渐变动画

    文章目录 效果 过程 代码 html css 其他demo 效果 效果预览 https codepen io karshey pen OJrXZwQ 过程 注意 直接在body上加height 100 可能也会出现height为0的情况 这
  • docker修改服务器参数怎么办,Docker(32)- 如何修改 docker 容器的启动参数

    如果你还想从头学起 Docker 可以看看这个系列的文章哦 前言 有时候创建容器时忘了添加 restart 参数 导致 Docker 服务重启后 容器不会自动启动 每次都需要手动启动 很不方便 那现在如何针对已创建的容器修改 restart
  • LeetCode——动态规划篇(二)

    刷题顺序及思路来源于代码随想录 网站地址 https programmercarl com 目录 343 整数拆分 力扣 LeetCode 96 不同的二叉搜索树 力扣 LeetCode 416 分割等和子集 力扣 LeetCode 104

随机推荐