Hough变换介绍
Hough变换介绍:
   简单来说,就是一个叫做Hough的人提出的,主要是将空间坐标转换到参数空间。比如一条直线:y = kx + b吧,我们看到这个后就会想到用x,y两个轴,然后画个图像去描述这条直线。但是还有一些人不按常规出牌,用k和b来描述一条直线。
   但是还有另外一个问题就出现了,k有不存在的啊,一条竖直的直线怎么搞?出现了无穷大了就。
   我们看到的图片是一个有限的范围,所以一定可以有办法将无穷大转换为有穷大。此时,极坐标学的好的人出现了,我们之所以看到的图片是个范围,是因为距离是一定的。极坐标两个参数,一个是rho,一个是theta,rho表示的是距离原点的距离,显然是有限的;theta只有360度,这样就可以保证图片能在计算机中进行处理喽。
参考地址如下:
点击打开链接
Hough变换步骤:
   简单介绍完了,就该开始Hough变换喽,先不多说,直接上流程图(老师作业,赶作业嘛,较为草率,仅做参考)。
实现代码:
#include <iostream>
#include <Eigen/Dense>
#include <cv.h>
#include <highgui\highgui.hpp>
#include <highgui\highgui_c.h>
#include <cv.hpp>#define PI 3.141592654using namespace std;
using namespace cv;
using Eigen::MatrixXd;//函数声明部分
void GetSobel(IplImage*);
MatrixXd ReadImg(IplImage*);
void Threshholding(IplImage* ImgSrc);void main()
{int ThetaDivide = 6;                                  //用来记录角度划分的数目int RhoDivide = 1.8;                                      //用来记录距离划分的数目int maxRho = -999999, minRho = 999999;                   //用来记录Rho的最大和最小值IplImage* src = cvLoadImage("test.png", 0);              //导入图片GetSobel(src);Mat srcLine = imread("test.png", 0);IplImage* Sobel = cvLoadImage("SobelResultImage.jpg", 0);             //导入图片Threshholding(Sobel);IplImage* Threshold = cvLoadImage("ThreshholdingResultImg.jpg", 0);               //导入图片MatrixXd PixelMatrix(Threshold->height, Threshold->width);          //将阈值处理或的图片的每个像素读取到PixelMatrix矩阵中PixelMatrix = ReadImg(Threshold);IplImage* FinalLine;             //二值化影像结果CvSize ImgResultSize; ImgResultSize.height = src->height; ImgResultSize.width = src->width;FinalLine = cvCreateImage(ImgResultSize, 8, 1);                //此处通道一定要与图像的通道数目对应,否则程序运行将出现崩溃//寻找rho的最大值,最小值int rho;                                                    //用来记录某个点距离原点的距离ρfor (int i = 0; i < Threshold->height; i++)for (int j = 0; j < Threshold->width; j++){for (int k = 0; k < ThetaDivide; k++)            //按照180个方向计算直线{rho = i * cos(k * PI / ThetaDivide) + j * sin(k * PI / ThetaDivide);if (rho < minRho)   minRho = rho;if (rho > maxRho)  maxRho = rho + 1;}}MatrixXd PolarLines(((maxRho - minRho) / RhoDivide + 1), ThetaDivide);for (int i = 0; i < (maxRho - minRho) / RhoDivide + 1; i++)for (int j = 0; j < ThetaDivide; j++){PolarLines(i, j) = 0;}for (int i = 0; i < Threshold->height; i++)for (int j = 0; j < Threshold->width; j++){for (int k = 0; k < ThetaDivide; k++)            //按照角度划分方向计算直线{if (PixelMatrix(i, j) == 255){//cout << i << " " << j << endl;rho = i * cos(k * PI / ThetaDivide) + j * sin(k * PI / ThetaDivide);int t = PolarLines((rho - minRho) / RhoDivide, k)++;}}}int count = 0;//int maxX = -9999, maxY = -9999, minX = 9999, minY = 9999;for (int t = 0; t < (maxRho - minRho) / RhoDivide; t++)for (int k = 0; k < ThetaDivide; k++){if (PolarLines(t, k) > 80){cout << t << " " << k << " " << PolarLines(t, k) << endl;Point pt1, pt2;float a = sin(k * PI / ThetaDivide);float b = cos(k * PI / ThetaDivide);float x0 = (t * RhoDivide + minRho)*a;float y0 = (t * RhoDivide + minRho)*b;//各个参数的含义参见该文:http://b217dgy.blog.51cto.com/5704306/1318934pt1.x = cvRound(x0 + 1000 * (-b));pt1.y = cvRound(y0 + 1000 * a);pt2.x = cvRound(x0 - 1000 * (-b));pt2.y = cvRound(y0 - 1000 * a);line(srcLine, pt2, pt1, CV_RGB(255, 255, 255), 1);                    //最后一个参数值决定了画线的粗细count++;}}cout << count << endl;namedWindow("Hough", CV_WINDOW_AUTOSIZE);imshow("Hough", srcLine);waitKey();}void Threshholding(IplImage* ImgSrc)
{MatrixXd PixelMatrix(ImgSrc->height, ImgSrc->width);PixelMatrix = ReadImg(ImgSrc);//--------------------------------------------------将灰度化图像进行二值化---------------------------------------------------------IplImage* ThreshholdingResultImg;             //二值化影像结果CvSize ImgResultSize; ImgResultSize.height = ImgSrc->height; ImgResultSize.width = ImgSrc->width;ThreshholdingResultImg = cvCreateImage(ImgResultSize, 8, 1);             //此处通道一定要与图像的通道数目对应,否则程序运行将出现崩溃int ThreshholdValue;                      //用来设置阈值ThreshholdValue = 100;for (int i = 0; i < ImgSrc->height; i++){for (int j = 0; j < ImgSrc->width; j++){if (PixelMatrix(i, j) > ThreshholdValue){((uchar *)(ThreshholdingResultImg->imageData + ThreshholdingResultImg->widthStep * i))[j] = 255;}else{((uchar *)(ThreshholdingResultImg->imageData + ThreshholdingResultImg->widthStep * i))[j] = 0;}}}cvSaveImage("ThreshholdingResultImg.jpg", ThreshholdingResultImg);//---------------------------------------------------------------------------------------------------------------------------------
}void GetSobel(IplImage* ImgSrc)
{//建立矩阵存储像素值的大小,Matrix矩阵起点下标值为0,即括号中填写的应为0MatrixXd PixelMatrix(ImgSrc->height, ImgSrc->width);PixelMatrix = ReadImg(ImgSrc);//----------------------------------------------------此处计算Sobel梯度-----------------------------------------------------------IplImage* SobelResultImgu;             //滤波影像结果CvSize ImgResultSize; ImgResultSize.height = ImgSrc->height; ImgResultSize.width = ImgSrc->width;SobelResultImgu = cvCreateImage(ImgResultSize, 8, 1);             //此处通道一定要与图像的通道数目对应,否则程序运行将出现崩溃for (int i = 0; i < ImgSrc->height; i++){for (int j = 0; j < ImgSrc->width; j++){int t = i + 1;int k = j + 1;int t1 = i - 1;int k1 = j - 1;if (t >= ImgSrc->height)    t = t - 1;if (k >= ImgSrc->width) k = k - 1;if (t1 < 0) t1 = t1 + 1;if (k1 < 0) k1 = k1 + 1;//对像素进行Robert's梯度计算float Gx = -PixelMatrix(t1, k1) - 2 * PixelMatrix(t1, j) - PixelMatrix(t1, k) +PixelMatrix(t, k1) + 2 * PixelMatrix(t, j) + PixelMatrix(t, k);float Gy = -PixelMatrix(t1, k1) - 2 * PixelMatrix(i, k1) - PixelMatrix(t, k1) +PixelMatrix(t, k) + 2 * PixelMatrix(i, k) + PixelMatrix(t, k);((uchar *)(SobelResultImgu->imageData + SobelResultImgu->widthStep * i))[j] = sqrt(Gx * Gx + Gy * Gy);}}cvSaveImage("SobelResultImage.jpg", SobelResultImgu);//----------------------------------------------------------------------------------------------------------------------------------
}MatrixXd ReadImg(IplImage* ImgSrc){MatrixXd PixelMatrix(ImgSrc->height, ImgSrc->width);for (int i = 0; i < ImgSrc->height; i++){for (int j = 0; j < ImgSrc->width; ++j)PixelMatrix(i, j) = ((uchar *)(ImgSrc->imageData + ImgSrc->widthStep * i))[j];}return PixelMatrix;
}

实现后的结果:

原图
Sobel计算结果
二值化图像结果

参考资料:

   在写这些代码时,当然是参考了资料的,老师的PPT自然是参考了的(不过作为学生不能上传喽)
   不过有很多好的课程或者报告之类的,我是直接从网上下载,所以应该可以用做学习交流吧,文件放在360云盘里:
   https://yunpan.cn/cRbDan9vAqim4  访问密码 50f4
   另外就是Opencv的配置,参考的是:http://wenku.baidu.com/view/f2feccb9fd0a79563c1e723a.html

Hough变换——直线检测(投票方法实现)相关推荐

  1. Hough变换直线检测

    作者:云外阳光 链接:https://www.zhihu.com/question/35268803/answer/82100453 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转 ...

  2. 【机器视觉学习笔记】Hough变换直线检测(C++)

    目录 源码 效果 平台:Windows 10 20H2 Visual Studio 2015 OpenCV 4.5.3 本文源码摘自OpenCV2马拉松第22圈--Hough变换直线检测原理与实现 源 ...

  3. hough变换直线检测_CV学习笔记(十五):直线检测

    在这一篇文章中我们将学习使用OpenCV中的 HoughLines 函数和 HoughLinesP 函数来检测图像中的直线. 在这个函数中,使用的是霍夫变换(Hough Transform) 这是计算 ...

  4. java+对图像进行直线检测_Java调用OpenCV进行Hough变换直线检测

    private BitmapHoughTransFormLine(Bitmap bmp) { Mat rgbMat = new Mat();  //存储原图像的矩阵 Mat grayMat = new ...

  5. 图像分割 - Hough变换直线检测

    目录 1. Hough 直线检测 2. HoughLinesP 函数 1. Hough 直线检测 霍夫变换(Hough 变换):利用对偶原理,把原空间的问题转换到对偶空间去求解 这里涉及到空间转换,将 ...

  6. hough变换直线检测_python+opencv实现霍夫变换检测直线

    作者:Ruff_XY 功能: 创建一个滑动条来控制检测直线的长度阈值,即大于该阈值的检测出来,小于该阈值的忽略 注意:这里用的函数是HoughLinesP而不是HoughLines,因为HoughLi ...

  7. hough变换检测直线 matlab,求能够运行的用matlab进行hough变换直线检测的程序。急!...

    满意答案 love8047g 2013.05.15 采纳率:43%    等级:13 已帮助:12527人 直接运行: RGB = imread('gantrycrane.png'); I = rgb ...

  8. OpenCV2马拉松第22圈——Hough变换直线检測原理与实现

    计算机视觉讨论群162501053 转载请注明:http://blog.csdn.net/abcd1992719g/article/details/27220445 收入囊中 Hough变换 概率Ho ...

  9. 【车道线识别】基于matlab hough变换道路检测直线检测【含Matlab源码 2074期】

    ⛄一.Hough变换图片车道线检测简介 1 引言 随着人们生活水平的提高, 科技的不断进步, 智能驾驶技术逐渐受到了研究者们的广泛研究和关注.先进驾驶辅助系统 (Advanced Driver Ass ...

最新文章

  1. (C++)数组作为函数参数
  2. 必须为元素类型 association 声明属性 oftype。_CSS相关的选择器和属性介绍
  3. 自已动手写控件 --- 我第一次学习写自定义控件
  4. Redis-17Redis内存回收策略
  5. 学习Matlab强大的符号计算(解方程)
  6. This EntitySet of type xxx does not support the 'Edit' operation
  7. redis异步写入mysql_异步操作redis,mysql
  8. 正则表达式的捕获性分组/反向引用
  9. Python第一次周考(0402)
  10. 《模式识别》自学笔记——(三)统计决策
  11. delphi 监控文件变化_监控Linux文件变化,防止系统被黑
  12. python fun函数输入某年某月_Python编程实现输入某年某月某日计算出这一天是该年第几天的方法...
  13. 阿里天池工业蒸汽量预测baseline-数据探索篇
  14. 第九周项目三小星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星星
  15. Scratch3.0 二次开发(4)修改界面字体大小
  16. 计算广告及搜索广告简介
  17. 数字信号处理matlab实验报告,数字信号处理,matlab实验报告
  18. sai笔记7-制作笔刷
  19. 海思嵌入式开发-003-Hi3861烧录报错,找不到Hi3861_wifiiot_app_allinone.bin文件
  20. Netflow相关技术

热门文章

  1. php TCPDF 输出表格到pdf
  2. idea解决jar包冲突的实用技巧
  3. 条条大路通云端,华为云应用平台ROMA破解传统政企上云困境
  4. matlab-3D装箱代码
  5. ddos攻击的简单应急处理办法
  6. 物联网实践实习日报表
  7. PQA怎样检测采样通道掉电
  8. 三变量二次函数的存在、恒成立_Simplelife_新浪博客
  9. Kahn拓扑排序模板
  10. python蒙特卡洛方法圆周率_蒙特卡罗方法 python 实现