18-霍夫变换

霍夫变换

霍夫变化 :(Hough Transform)是图像处理中的一种特征提取技术,在一个参数空间中通过计算累计结果的局部最大值(累计局部最大值) 得到一个符合该特定形状的集合作为霍夫变换的结果;
霍夫变换主要分为两种: 霍夫直线变换与霍夫圆变换;
1、标准霍夫变换;HoughLines()
2、多尺度霍夫变换;HoughLines()
3、累计霍夫变换;HoughLineP()
4、霍夫圆变换 : HoughCircles()

霍夫线变换

1、霍夫变换输入一般为边缘二值图,用以寻找轮廓中的直线、圆;
2、霍夫线变换可分为:标准霍夫变换、多尺度霍夫变换、累计概率霍夫变换3种;
3、霍夫线变换的原理为:线性坐标系与极坐标之间的转换;

4、HoughLines参数说明:
src : 输入图像,一般为8位单通道二值图像;
lines : 线条输出矢量(极坐标表示形式:(ρ,θ)),EmguCV中可以用VectorOfPointF类型存储,x坐标存储ρ值,y坐标存储θ值;
rho : 像素扫描步长(ρ);
theta : 角度扫描步长(θ);
threshold:设定有足够交点数的极坐标才认为是直线;
srn,stn : 多尺度霍夫变换使用;

5、累计霍夫变换:EmguCV提供了两种封装方法,方法1返回值为空,计算直线点通过方法参数输出;方法2返回值为LineSegment2D类型,直线点坐标返回输出;


使用第一种方法,可以使用VectorOfRect类型存储计算坐标点:

Hough线变换Demo

1、HoughLines()计算的坐标点输出为极坐标点,需要自己换算到直角坐标系;
2、HoughLineP()计算输出为直线的两端点,不需要自己换算;
3、阈值,最低线段长度,允许连接最大距离影响实际作用效果;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using Emgu.CV.Util;
using System.Drawing;

namespace lesson18
{
   
    class Program
    {
   
        static void Main(string[] args)
        {
   
            //Mat src = CvInvoke.Imread("1.bmp");
            //Mat grayimg = new Mat();
            //Mat edge = new Mat();
            //CvInvoke.CvtColor(src, grayimg, ColorConversion.Bgr2Gray);


            //CvInvoke.Canny(grayimg, edge, 100, 200, 3, false);
            //CvInvoke.Imshow("canny image", edge);
            //VectorOfPointF lines = new VectorOfPointF(); //lines存储的是极坐标值
            //CvInvoke.HoughLines(edge, lines, 10, Math.PI / 180, 600, 0, 0);

            //for(int i = 0; i < lines.Size; i++)
            //{
   
            // float rho = lines[i].X; //将极坐标值转换到线坐标系中
            // float theta = lines[i].Y;
            // double a = Math.Cos(theta), b = Math.Sin(theta);
            // double x0 = rho * a, y0 = rho * b; //线坐标系中对应的点
            // Point pt1 = new Point(); 
            // Point pt2 = new Point();

            // pt1.X = (int)Math.Round(x0 + 1000 * (-b)); //求取对应点上下两点的坐标,1000为线距
            // pt1.Y = (int)Math.Round(y0 + 1000 * a);
            // pt2.X = (int)Math.Round(x0 - 1000 * (-b));
            // pt2.Y = (int)Math.Round(y0 - 1000 * a);

            // CvInvoke.Line(src, pt1, pt2, new MCvScalar(0, 0, 255), 2, LineType.EightConnected);
            //}

            //CvInvoke.Imshow("hough test", src);

            ///累计霍夫变换
            Mat src = CvInvoke.Imread("mask.jpg");
            Mat grayimg = new Mat();
            Mat cannyimg = new Mat();

            CvInvoke.CvtColor(src, grayimg, ColorConversion.Bgr2Gray);
            CvInvoke.Canny(grayimg, cannyimg, 100, 200, 3, false);

            LineSegment2D[] lines = CvInvoke.HoughLinesP(cannyimg, 10, Math.PI / 180, 30, 5, 10); //累计霍夫变换自动计算出直线的两端点

            for(int i = 0; i < lines.Length;i++)
            {
   
                Point pt1 = lines[i].P1;  //直线两端点
                Point pt2 = lines[i].P2;

                CvInvoke.Line(src, pt1, pt2, new MCvScalar(0, 255, 0), 2, LineType.EightConnected);
            }
            CvInvoke.Imshow("hough test", src);

            CvInvoke.WaitKey(0);
        }
    }
}


标准Hough 线变换


累计霍夫线变换:

Hough圆变换

1、OpenCV/EmguCV中使用霍夫梯度法进行圆检测;

2、API : HoughCircles()
参数说明:
circles : CircleF类型参数;
method : 方法,只支持霍夫梯度法;
dp : 1 : 原图搜索,2 : 取图像一半搜索;
param1 : 传递给Canny算子的高阈值;
param2 : 中心点累加器阈值(圆心最少有多少次重合才认为是一个圆);
minRadius,maxRadius : 检测的 最大最小圆范围

Hough圆变换Demo

1、参数取值直接影响实验效果

...
Mat src = CvInvoke.Imread("2.png");
Mat dst = Mat.Zeros(src.Rows,src.Cols,DepthType.Cv8U,3);
 Mat grayimg = new Mat();
 CvInvoke.CvtColor(src, grayimg, ColorConversion.Bgr2Gray);
 CvInvoke.Imshow("input", grayimg);
 CircleF[] circles = CvInvoke.HoughCircles(grayimg, HoughType.Gradient, 1, 30, 100, 30, 10, 200);  //minRadius设置为100,则所有圆都被过滤
 //CircleF[] circles = CvInvoke.HoughCircles(grayimg, HoughType.Gradient, 1, 80, 200, 30, 120, 200);
 for (int i = 0; i < circles.Length; i++)
 {
                   
     CvInvoke.Circle(dst, new Point((int)circles[i].Center.X, (int)circles[i].Center.Y), (int)circles[i].Radius, 
                         new MCvScalar(255, 255, 0), 3, LineType.EightConnected);
 }

 CvInvoke.Line(dst, new Point(10, 10), new Point(100, 100),new MCvScalar(127,127,0),2);

 CvInvoke.Imshow("hough circle test", dst);

 CvInvoke.WaitKey(0);

全部评论

相关推荐

2025-12-12 19:01
南京航空航天大学 C++
秋招没咋投,准备&nbsp;wxg&nbsp;转正之后摆烂了。结果不堪字节&nbsp;HR&nbsp;的骚扰还是面了一下字节。之前想去字节的时候怎么面都挂。现在想着随便面一下结果三面技术面都意外顺利还有加面。十月中旬字节发了意向,wxg&nbsp;转正结果无响应。十月底字节拉了保温群,wxg&nbsp;口头通过,系统显示考核中。十一月初和字节&nbsp;ld&nbsp;交流之后得知&nbsp;base&nbsp;居然能选海外,甚至能小&nbsp;wlb&nbsp;一下,wxg&nbsp;无响应无人联系。十一月中旬把字节&nbsp;base&nbsp;转到了海外,wxg&nbsp;流程灰了,一问超时忘处理了,过两天又变考核中了。十一月下旬字节换了海外&nbsp;HR&nbsp;对接,问了期望薪资,wxg&nbsp;考核终于显示通过,无&nbsp;HR&nbsp;保温,无其他保温。十一月底给字节报了个天价,想吓吓他们,同时告诉微信字节要开了,微信无响应。同样十一月底字节&nbsp;HR&nbsp;告诉我确实给不到那么高,但是能拿期权补上,问能不能接受。微信无响应。同样十一月底字节&nbsp;HR&nbsp;告知了具体方案,符合预期。&nbsp;微信无响应。十二月上旬催&nbsp;wxg&nbsp;不开我就盲拒了,wxg&nbsp;HR&nbsp;火急火燎的打电话问情况,问期望。我给了一个不算夸张的总包数字,因为今年市场在涨,过了三天还不联系我,我再催,约时间下午打电话,非得在我给出的数字上压下去几万,微信又不差这点,为什么不能满足我,让我没有拒绝的理由呢?一番纠结抗争,求稳还是追求挑战,最终选择接受迎接新的挑战,因为堂吉诃德永远不会停下脚步!回想起来,在&nbsp;wxg&nbsp;谈薪的阶段,我认为并没有给予我一定的重视,即使&nbsp;HR&nbsp;表示我在实习期间的表现和之前的面评都很靠前。也没有感觉到想要争取我,虽然我表示拒了&nbsp;offer&nbsp;之后要给我加面委定&nbsp;t6&nbsp;再涨,但我三个月没面试让我面面委那就是白给,还是算了。有缘再见了我亲爱的&nbsp;wxg,再见了曾经的梦中情厂,再见亲爱的&nbsp;mt,再见亲爱的朋友们。也再见,北京的一切。我想润了。秋招结束,卸载牛客,下一个三年,下一个五年,下一个十年后再来看看。
面试中的大熊猫爱吃薯...:我嫉妒得狗眼通红
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务