• Kernel-based Hough transform KHT移植

    • 简介
    • 分析程序
    • 移植到自己程序中并用OpenCV画出检测出的直线
    • 附录 KHTOpenCV测试程序

Kernel-based Hough transform (KHT)移植

本周发现了一篇讲解可以很大程度加快霍夫变换的论文,并且已经有实现好的例程了,所以想试下看以后能不能用的上,算法名字叫Kernel-based Hough transform (KHT)。暂时还没看懂,不过经过试验,在我电脑上(i3-2310M)对于2560x1920的图像找出直线大约需要70ms,对比下一直使用的OpenCV的标准算法大约需要200ms,release版本只需要20ms,OpenCV release版本需要110ms

简介:

Fernandes and Oliveira1suggested an improved voting scheme for the Hough transform that allows a software implementation to achieve real-time performance even on relatively large images (e.g., 1280×960). The Kernel-based Hough transform uses the same (r,\theta ) parameterization proposed by Duda and Hart but operates on clusters of approximately collinear pixels. For each cluster, votes are cast using an oriented elliptical-Gaussian kernel that models the uncertainty associated with the best-fitting line with respect to the corresponding cluster. The approach not only significantly improves the performance of the voting scheme, but also produces a much cleaner accumulator and makes the transform more robust to the detection of spurious lines.2

该项目在SourceForge中公布源代码
下载链接:
http://iweb.dl.sourceforge.net/project/khtsandbox/khtsandbox/KHT%20Sandbox%201.0.2/kht_sandbox-1.0.2-source.zip
http://kht-sandbox.soft112.com/
下载解压后共三个文件夹

  • kht_source中是kst算法的源码
  • matlab中是matlab使用示例
  • sample_app中是使用示例

sample_app中的工程可以用vs2010打开转换下,sample_app_vc++9.sln和sample_app_vc++8.sln都可以转换成功(我只有vs2010,更低版本的应该也可以)
但工程属性需要改一下

  • 常规->输出目录$(SolutionDir)$(Configuration)\
  • 常规->中间目录$(Configuration)$\
  • 链接器->输出文件$(OutDir)$(TargetName)$(TargetExt)
  • 切换到Debug状态时还要再改一遍


默认是Release 状态, Ctrl+F5运行下,结果很好:图像大小为800x800左右,帧率依次为25,28,27,30,34,40,35,40



分析程序:

测试程序是用OpenIL(不过现在又叫DevIL,不懂)来读取图像的,原图是单色位图,但是读进来后一个像素还是一个字节的,我用一张小图片测试了一下,像素在数组中的位置还是从左到右,从上到下的。和OpenCV一样。所有图像读取后都存到images_list中,最重要的变换函数是

kht( lines, image->pixels_copy, image->width, image->height, 10, 2.0, 0.5, 0.002, 2 );

不过貌似这个函数会更改输入图像,全部置0,所以需要提前备份一份。
得到的每条直线的rho和theta,theta不是弧度制的,所以后面有一句将角度转成弧度制。

double theta = line.theta * deg_to_rad;

需要注意的是:求得的rho和theta是以图像中心为坐标原点的,用OpenCV画直线时需要转化一下。
画直线是用OpenGL和Glut实现的,OpenGL也是以图像中心为坐标原点的,所以最左下角的点的坐标为(-w/2,-h/2), 最右上角的点的坐标为(w/2,h/2)。

glBegin( GL_LINES ); //就是开始画直线了
glVertex2d( -aux, (line.rho + aux * cos_theta) * one_div_sin_theta );//给定第一个端点
glVertex2d( aux, (line.rho - aux * cos_theta) * one_div_sin_theta );//给定第二个端点

画线这一段原理是利用式1,直线上的所有点(x,y)都满足式1,解方程,再将x=-w/2和x=w/2带入求得两个端点。

xcosθ+ysinθ=ρ

xcos\theta+ysin\theta=\rho

y=ρ−xcosθsinθ

y=\frac{\rho-xcos\theta}{sin\theta}

w2=−w2,x1=w2,y1=ρ+w2cosθsinθ

w2=-\frac{w}{2},x1=w2,y1=\frac{\rho+w2cos\theta}{sin\theta}

x2=w2,y1=ρ−w2cosθsinθ

x2=w2,y1=\frac{\rho-w2cos\theta}{sin\theta}

移植到自己程序中并用OpenCV画出检测出的直线

移植到自己程序中只需将kht_source文件夹复制到自己程序文件夹内,并添加到工程中,在主函数前面包括进kht.h。

#include "./kht_source/kht.h"

复制要处理的图像数据,调用kht函数就可以了

Mat img_copy = img.clone();
static lines_list_t lines;
kht( lines, img_copy.data, img.cols, img.rows, 10, 2.0, 0.5, 0.002, 2 );

绘制直线就比较麻烦了,OpenCV的坐标原点是左上角,要做坐标变换。
设OpenGL中点的坐标为(x,y),OpenCV中点的坐标为(u,v),则:

u=x+w/2,v=h/2−y

u=x+w/2, v=h/2-y
但测试时发现还是出错 #待解决,程序中实际情况是

u=x+w/2,v=h/2+y

u=x+w/2, v=h/2+y
整体测试程序见附录,但是测试building_binary.bmp时出现问题,该图画出的直线和原来的示例不同。 #待解决

附录 KHT+OpenCV测试程序

// HoughLineTest.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <time.h>
#include "./kht_source/kht.h"
#include <opencv2/opencv.hpp>
using namespace cv;
#define mymin(x,y) (x<y?x:y)
#ifndef PI
#define PI 3.14
#endif
void drawline(Mat& imgs,vector<Point2f>& linesl);
void drawline(Mat& imgs,lines_list_t& lines);
int _tmain(int argc, _TCHAR* argv[])
{// Load input binary images.static const size_t images_count = 8;static const char *filenames[images_count]       = {"./images/chess_binary.bmp", "./images/road_binary.bmp", "./images/wall_binary.bmp", "./images/board_binary.bmp", "./images/church_binary.bmp", "./images/building_binary.bmp", "./images/beach_binary.bmp", "./images/simple_binary.bmp" };static const size_t relevant_lines[images_count] = {25,                          15,                         36,                         38,                          40,                           19,                             19,                          8                            };int test_flag = 0;while(test_flag){Mat img = imread(filenames[0],0);Mat img_copy = img.clone();static lines_list_t lines;//vector<Point2f> lines;time_t time_start,time_stop;time_start = clock();kht( lines, img_copy.data, img.cols, img.rows, 10, 2.0, 0.5, 0.002, 2 );//HoughLines(img_copy, lines, 1, CV_PI/180, 140, 0, 0 );time_stop = clock();std::cout<<time_stop-time_start<<std::endl;}for (size_t i=0; i!=images_count; ++i){Mat img = imread(filenames[i],0);if(img.channels()==1){Mat img_copy = img.clone();static lines_list_t lines;kht( lines, img_copy.data, img.cols, img.rows, 10, 2.0, 0.5, 0.002, 2 );
//          vector<Point2f> lines;
//           HoughLines(img_copy, lines, 1, CV_PI/180, 130, 0, 0 );drawline(img,lines);}}return 0;
}
void drawline(Mat& imgs,vector<Point2f>& lines)
{Mat imgl;cvtColor(imgs,imgl,CV_GRAY2BGR);for( size_t i=0,linenum=mymin(25,lines.size());i<linenum; i++ ){float rho = lines[i].x, theta = lines[i].y;Point pt1, pt2;double a = cos(theta), b = sin(theta);double x0 = a*rho, y0 = b*rho;pt1.x = cvRound(x0 + 2000*(-b));pt1.y = cvRound(y0 + 2000*(a));pt2.x = cvRound(x0 - 2000*(-b));pt2.y = cvRound(y0 - 2000*(a));cv::line( imgl, pt1, pt2, cvScalar(0,0,255), 1, CV_AA);}   imshow("Horize HoughLines",imgl);waitKey();
}
void drawline(Mat& imgs,lines_list_t& lines)
{Mat imgl;cvtColor(imgs,imgl,CV_GRAY2BGR);if(lines.size()){for( size_t i=0,linenum=mymin(25,lines.size());i<linenum; i++ ){line_t &line = lines[i];Point pt1,pt2;if(line.theta != 0.0){ int w2 = imgl.cols/2;int h2 = imgl.rows/2;static const double deg_to_rad = PI/ 180.0;double theta = line.theta * deg_to_rad;double rho = line.rho;double cos_theta = cos( theta );double one_div_sin_theta = 1 / sin( theta );pt1.x = 0;pt1.y = h2 + (line.rho + w2 * cos_theta) * one_div_sin_theta ;pt2.x = w2+w2;pt2.y = h2 + (line.rho - w2 * cos_theta) * one_div_sin_theta ;cv::line( imgl, pt1, pt2, cvScalar(0,0,250), 1, CV_AA); }else{int w2 = imgl.cols/2;int h2 = imgl.rows/2;pt1.x = w2 + line.rho;pt1.y = 0;pt2.x = w2 + line.rho;pt2.y = h2+h2;cv::line( imgl, pt1, pt2, cvScalar(0,0,250), 1, CV_AA); }}   }imshow("Horize HoughLines",imgl);waitKey();
}


  1. [1]:Fernandes L A F, Oliveira M M. Real-time line detection through an improved Hough transform voting scheme[J]. Pattern Recognition, 2008, 41(1):299-314.
    [2]: https://en.wikipedia.org/wiki/Hough_transform ↩
  2. [1]:Fernandes L A F, Oliveira M M. Real-time line detection through an improved Hough transform voting scheme[J]. Pattern Recognition, 2008, 41(1):299-314.
    [2]: https://en.wikipedia.org/wiki/Hough_transform ↩

Kernel-based Hough transform (KHT)移植相关推荐

  1. Hough transform

    Hough transform From Wikipedia, the free encyclopedia Jump to: navigation, search The Hough transfor ...

  2. hough变换检测圆周_一文解读经典霍夫变换(Hough Transform)

    引言 本文讲述霍夫变换的一些内容,并加入一些理解性东西,参考了部分博客等相关性内容.希望能对霍夫变换有所了解,也希望看到的人如果发现错误及时帮忙纠正.博主水平有限,还望赐教. 历史和简介 历史 霍夫变 ...

  3. 概率霍夫变换(Progressive Probabilistic Hough Transform)原理详解

    概率霍夫变换(Progressive Probabilistic Hough Transform)的原理很简单,如下所述: 1.随机获取边缘图像上的前景点,映射到极坐标系画曲线: 2.当极坐标系里面有 ...

  4. 论文翻译--[TPAMI 2021]Deep Hough Transform For Semantic Line Detection

    目录 深度霍夫变换语义直线检测 摘要 1,引言 2,相关工作 3,方法 3.1直线参数化和反转 3.2 深度霍夫变换的特征变换 3.3 在参数空间上进行直线检测 3.4  反转映射 3.5  边缘导向 ...

  5. 霍夫(圆)变换(hough Transform/hough cirlce Transform)原理和实现

    一.霍夫(圆)变换的广泛使用和简要历史 霍夫变换是一种特征提取方法,被广泛应用在图像处理和计算机视觉应用中.霍夫变换是用来辨别找出物件中的特征,例如:线条.他的算法流程大致如下,给定一个物件.要辨别的 ...

  6. Hough Transform 霍夫变换检测直线

    Hough Transform 霍夫变换检测直线 从理论到代码,再从代码到理论 (1)理论之通俗理解: 1.在图像中检测直线的问题,其实质是找到构成直线的所有的像素点.那么问题就是从找到直线,变成找到 ...

  7. Hough Transform 的算法思想

    1.Hough Transform 的算法思想 在直角坐标系和极坐标系中,点.线是对偶关系. 即直角坐标系中的点是极坐标系中的线,直角坐标系中的线是极坐标系中的点.反之也成立. 如下图所示,想要检测图 ...

  8. 文献学习(part38)--Adaptive hash retrieval with kernel based similarity

    学习笔记,仅供参考,有错必纠 关键词:哈希:k-NN:内核:二进制索引:归一化欧氏距离 文章目录 Adaptive hash retrieval with kernel based similarit ...

  9. Matlab课后笔记之霍夫变换(Hough Transform)

    文章目录 前言 一.代码实现结果图 二.实现代码及其注释 总结 前言 最近开始上计算机视觉的实验课,使用的软件是matlab.老师布置了一项给代码添加注释的作业,是有关于霍夫变换的.刚接触这个软件和它 ...

最新文章

  1. echarts自动生成图片的解决方案
  2. shiro+redis实现session共享
  3. 为什么前后端分离了,你比从前更痛苦?
  4. Only call `sigmoid_cross_entropy_with_logits` with named arguments解决
  5. 成功解决ValueError: If using all scalar values, you must pass an index
  6. 你以为妹子穿短裙真的是为了诱惑你吗?
  7. 自定义Gradle Plugin
  8. android音视频指南-支持的媒体格式
  9. Tachyou alluxio初识
  10. const成员函数重载
  11. 表格 滚动条 (tbody部分滚动)
  12. P1352 没有上司的舞会[树形dp]
  13. 一文读懂什么是硬件开发、智能硬件、硬件系统?
  14. C语言运算符优先级(超级详细)
  15. kingbase 修改数据库密码
  16. 从最终用户角度来看外部结构_从不同角度来看您最喜欢的游戏
  17. 任务栏优化工具TrueLaunchBar_我是亲民_新浪博客
  18. 约束(Constraint)SQL约束有哪几种?【常用的约束】【有例子】【非空约束】【唯一约束】【主键约束】【外键约束】【检查约束】
  19. html怎么把图做成3d效果,ps怎么制作立体效果 ps做图怎么做出立体的效果
  20. Mac用户学Python-Day1:安装与环境配置

热门文章

  1. 1.3 什么公司需要运维
  2. 学成案例——banner模块和精品模块制作
  3. mybatis传单个参数报错:There is no getter for property named 'user_id' in 'class java.lang.String
  4. python环境安装
  5. GPU Direct p2p、 Nvlink 、GPU DirectRDMA
  6. 网络协议 (一) TCP/IP 四层模型
  7. rsync数据同步+inotify实时同步
  8. cmake使用教程(实操版)
  9. 【与达梦同行】达梦驱动图谱
  10. 【Kevin Learn QMUI】-->QMUILinkTextView