hough变换检测直线原理:

假设在图像中存在一条直线y=k*x+b(此时k,b未知)。取直线上的任意两点进行说明,设为(x0,y0),(x1,y1)。

所有经过点(x0,y0)的直线满足:-x0*k+y0=b ---式1,那么以k、b为直角坐标轴做式1对应直线;

所有经过点(x1,y1)的直线满足:-x1*k+y1=b ---式2,那么以k、b为直角坐标轴做式2对应直线;

两直线交于一点(kk,bb),此时该交点对应的直线y=kk*x+bb就是(x0,y0),(x1,y1)所确定的直线。

在hough变换中,我们首先将直线方程转换为极坐标形式:x*cos(theta)+y*sin(theta)=r ---式3(theta,r未知)。同上述原理,假设已知直线上的点的坐标,那么经过该点的曲线方程就对应着hough变换空间(即theta,r坐标系)的一条曲线,同一条直线上的点必定在hough变换空间相交于一点(theta*,r*),该点就是待检测直线方程式3对应的theta、r。当然,在hough变换空间两条曲线相交确定的(theta,r)并不能足以说明我们检测到了一条直线,只有当在(theta,r)这一点累加的曲线个数很大,通常是超过了我们提前设定的某个阈值时,我们才认为在(theta,r)是对应有一条直线的,否则我们应该使用极大值抑制的方法将这些干扰点(theta,r)去掉。下图是copy过来的,大概看看就行。

以下是hough变换检测直线的封装类,因实际需求,这里我是专门用来检测任意四边形的四条边的。

1 public classLineFilter {2 private intw;3 private inth;4 private inthalfX;5 private inthalfY;6 private intrmax;7 private intlineNum;8 private int[] output;9 private int[] n;10 private int[][] acc;11 private double[] sinValue;12 private double[] cosValue;13 private Listlist;14

15 //Acc累加器,同一个r,theta的点进行累加,累加个数为val

16 public classAcc {17 private int r = 0;18 private int theta = 0;19 private int val = 0;20 publicAcc() {21 }22 }23

24 public int[] lineDetect(int width, int height, int lineNumber, int[] input) {25 init(width, height, lineNumber);26 /*

27 * 转换:直角坐标空间~极坐标空间28 * 不断计算累加,最终得到相同(theta,r)的像素点累加个数acc[theta][r]29 **/

30 for (int theta = 0; theta < 180; theta++) {31 for (int x = 0; x < w; x++) {32 for (int y = 0; y < h; y++) {33 if (input[y * w + x] ==Color.BLACK) {34 int r = (int) ((x - halfX) * cosValue[theta] + (y - halfY) *sinValue[theta]);35 r = r + rmax;//r的原本取值范围为(-ramx,ramx),加rmax后取值范围为(0,2ramx)

36 if (r >= 0 && r < 2 *rmax)37 acc[theta][r]++;38 }39 }40 }41 }42 /*

43 * 很重要的一步:在3*3窗口内对累加值进行极大值抑制,保留窗口内累加值最大的(theta,r);44 * 之后将theta,r,acc[theta][r]添加进list里面;45 * 对list进行部分排序;46 * 之后取出list前面lineNum个Acc对象,通过theta和r值找出直角坐标空间的直线47 **/

48 rankList(acc);49 System.out.println(".........acc个数:" +list.size());50 n = new int[lineNum];51 for (int i = 0; i < lineNum; i++) {52 Acc acc =list.get(i);53 n[i] =drawLine(acc.r, acc.theta, n[i]);54 System.out.println("检测出的第" + i + "条直线点的累积个数:" + acc.r + "..." + acc.theta + "..." +acc.val);55 System.out.println("实际输出第" + i + "条直线点的个数:" +n[i]);56 }57 returnoutput;58 }59

60 private void init(int width, int height, intlineNumber) {61 w =width;62 h =height;63 halfX = w / 2;64 halfY = h / 2;65 lineNum =lineNumber;66 output = new int[w *h];67 int max =Math.max(w, h);68 rmax = (int) (Math.sqrt(2.0) *max);69 acc = new int[180][2 *rmax];70 list = new ArrayList<>();71 sinValue = new double[180];72 cosValue = new double[180];73 Arrays.fill(output, Color.WHITE);74 for (int theta = 0; theta < 180; theta++) {75 sinValue[theta] = Math.sin((theta * Math.PI) / 180);76 cosValue[theta] = Math.cos((theta * Math.PI) / 180);77 }78 }79

80 /*

81 * 排序Acc数组,只对前面几个Acc进行排序,找出lineSize个较大的Acc82 **/

83 private void rankList(int[][] acc) {84 /*

85 * 对(theta,r)进行极大值抑制,因为有时候因为计算误差或者直线不是很直的原因,86 * 同一条直线上的点转换到极坐标空间时,就会出现多对不同的(theta,r),多对不同的(theta,r)转换到直角坐标空间就出现了多条直线,87 * 这就是为什么原本图像中只有一条直线最后在该位置检测出了多条直线,因此在进行极坐标到直角坐标转换之前,88 * 有必要对(theta,r)进行极大值抑制,只保留累积值val最大的那一对(theta,r)89 **/

90 for (int theta = 0; theta < 180; theta++) {91 for (int r = 0; r < 2 * rmax; r++) {92 int val =acc[theta][r];93 boolean onlyLine = true;94 if (val > 0) {95 for (int tt = -1; tt <=1; tt++) {96 for (int rr = -1; rr <= 1; rr++) {97 int newtheta = theta +tt;98 int newr = r +rr;99 if (newtheta < 0 || newtheta >= 180)100 newtheta = 0;101 if (newr < 0 || newr >= 2 * rmax) newr = 0;102 if (acc[newtheta][newr] > val) onlyLine = false;103 }104 }105 /*

106 *在3*3窗口内累加值最大的(theta,r)我们才添加进list ,107 * 并标记theta,r,以及累加值val108 **/

109 if(onlyLine) {110 Acc subAcc = newAcc();111 subAcc.r = r -rmax;112 subAcc.theta =theta;113 subAcc.val =acc[theta][r];114 list.add(subAcc);115 }116 }117 }118 }119 /*

120 * 设置需要检测的直线条数为lineNum,121 * 按val值大小升序排列list,当然只需要进行前面部分的排序即可122 **/

123 for (int i = 0; i < lineNum; i++) {124 int max =i;125 for (int j = i + 1; j < list.size(); j++) {126 if (list.get(j).val >list.get(max).val) {127 max =j;128 }129 }130 if (max !=i) {131 Acc accmax =list.get(max);132 Acc acci =list.get(i);133 list.set(max, acci);134 list.set(i, accmax);135 }136 }137 }138

139 /*

140 *转换:极坐标空间~直角坐标空间141 *r=(x-halfx)*cos(theta)+(y-halfy)*sin(theta);142 * 已知r,theta,x或者y的情况下,通过该式计算出符合条件的y或者x。143 * 画出lineNum条直线144 **/

145 private int drawLine(int r, int theta, intn) {146 if (theta >= 45 && theta <= 135) {147 for (int x = 0; x < w; x++) {148 int y = (int) ((r - (x - halfX) * cosValue[theta]) / sinValue[theta]) +halfY;149 if (y >= 0 && y = 0 && x

166 }

java hough_hough变换检测直线Java相关推荐

  1. Hough变换检测直线与圆的原理

    霍夫变换的基本原理 霍夫变换(Hough Transform)可以理解为图像处理中的一种特征提取技术,通过投票算法检测具有特定形状的物体.霍夫变换运用两个坐标空间之间的变换将在一个空间中具有相同形状的 ...

  2. hough变换检测直线 matlab,Matlab实现Hough变换检测图像中的直线

    Hough变换的原理: 将图像从图像空间变换至参数空间,变换公式如下: 变换以后,图像空间与参数空间存在以下关系: 图像空间中的一点在参数空间是一条曲线,而图像空间共线的各点对应于参数空间交于一点的各 ...

  3. 小白学习图像处理7——Hough变换检测直线

    文章目录 一.Hough变换的原理 1.过定点的直线方程 2.两点确定一条直线 3.方程的形式 二.实现过程 三.程序代码 1.程序片段 2.总程序 四.matlab 的hough函数 一.Hough ...

  4. Java实现人脸检测,java线程教程

    @Auther: DarkKing @Date: 2019/10/2 11:06 @Description: */ public class DetectFace { //定义程序的基础路径 priv ...

  5. Python-Anaconda练习candy算子用于边缘提取,再用hough变换检测直线边缘

    img: 待检测的图像. threshold: 阈值,可先项,默认为10 line_length: 检测的最短线条长度,默认为50 line_gap: 线条间的最大间隙.增大这个值可以合并破碎的线条. ...

  6. python 图像变化检测_python hough变换检测直线的实现方法

    1 原理 2 检测步骤 将参数空间(ρ,θ) 量化成m*n(m为ρ的等份数,n为θ的等份数)个单元,并设置累加器矩阵,初始值为0: 对图像边界上的每一个点(x,y)带入ρ=xcosθ+ysinθ,求得 ...

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

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

  8. java代码安全检测机制,Java语言有多种实现的机制,下列( )技术不属于代码安全检测。...

    "元曲四大家"指的是关汉卿.白朴.马致远和纪君祥. ( )不是Windows 7中用户账户类型. 口腔白色念珠菌感染患者常选用弱酸性漱口液. 在a>b?a+b:a-b表达式中 ...

  9. 基于Hough变换的直线和圆的检测与提取

    学数字图像处理有挺长时间了,正好最近这段时间有空,学习了一下Hough变换,作了几个比较简单的东西,分享出来,希望能和大家一起学习,也希望各位能提出宝贵的意见,共同进步,文采不好,欢迎拍砖,下面正式进 ...

最新文章

  1. 第十五届全国大学生智能汽车竞赛室外光电组全国总决赛方案
  2. VTK:可视化之MultipleRenderWindows
  3. 久谦咨询python笔试题目_【久谦咨询面试|面试题】-看准网
  4. 《剑指Offer》 二进制中1的个数
  5. jekenis安装与部署_入门兵器谱,测试相关软件系列——Jenkins自动化部署实录
  6. Android开发人员的10大抱怨
  7. 【网络安全工程师面试合集】安全角度谈UDP、TCP和DHCP协议
  8. Directx工具修复工具,专注修复C++动态链接DLL文件
  9. 解决各种IE兼容问题
  10. c语言课程设计题目 吃豆子,C语言吃豆子游戏
  11. win10点文件夹转圈圈假死机
  12. CMD 禁用 笔记本自带的键盘
  13. 初玩《剑与家园》体验和对游戏设计的一些思考
  14. html隐藏visibility,CSS Visibility(可见性)
  15. matlab :检测文档图片中的字母l
  16. 离散数学重点(第二部分)
  17. 基于WINDOS系统自带工具IIS配置文件下载服务器
  18. 大二Web课程设计——家乡主题网页设计(web前端网页制作课作业) 四川旅游网页设计制作
  19. 【U8】固定资产新年度第一月份期初和期末对不上
  20. 什么是企业管理系统,应如何选择?

热门文章

  1. android ifw 启动广告,应用控制器清爽无广告版-应用控制器官方最新版v1.9.5 免费版-腾牛安卓网...
  2. C语言——函数递归实现
  3. 2021-10-09 P1314 聪明的质检员
  4. modelsim仿真quartus软件IP核错误及解决办法
  5. epub电子书如何用IOS苹果手机打开?
  6. SecureCRT乱码的问题
  7. pta乙级1031查验身份证(AC)
  8. 用分数形式精确表达有理数和循环无理数
  9. 思科devnet_思科释放新网络的无尽潜能
  10. EBS OAF开发中属性集(Attribute Set)的介绍和手工实现