Kernel-based Hough transform (KHT)移植
- 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\theta+ysin\theta=\rho
y=\frac{\rho-xcos\theta}{sin\theta}
w2=-\frac{w}{2},x1=w2,y1=\frac{\rho+w2cos\theta}{sin\theta}
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
整体测试程序见附录,但是测试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]: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 ↩ - [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)移植相关推荐
- Hough transform
Hough transform From Wikipedia, the free encyclopedia Jump to: navigation, search The Hough transfor ...
- hough变换检测圆周_一文解读经典霍夫变换(Hough Transform)
引言 本文讲述霍夫变换的一些内容,并加入一些理解性东西,参考了部分博客等相关性内容.希望能对霍夫变换有所了解,也希望看到的人如果发现错误及时帮忙纠正.博主水平有限,还望赐教. 历史和简介 历史 霍夫变 ...
- 概率霍夫变换(Progressive Probabilistic Hough Transform)原理详解
概率霍夫变换(Progressive Probabilistic Hough Transform)的原理很简单,如下所述: 1.随机获取边缘图像上的前景点,映射到极坐标系画曲线: 2.当极坐标系里面有 ...
- 论文翻译--[TPAMI 2021]Deep Hough Transform For Semantic Line Detection
目录 深度霍夫变换语义直线检测 摘要 1,引言 2,相关工作 3,方法 3.1直线参数化和反转 3.2 深度霍夫变换的特征变换 3.3 在参数空间上进行直线检测 3.4 反转映射 3.5 边缘导向 ...
- 霍夫(圆)变换(hough Transform/hough cirlce Transform)原理和实现
一.霍夫(圆)变换的广泛使用和简要历史 霍夫变换是一种特征提取方法,被广泛应用在图像处理和计算机视觉应用中.霍夫变换是用来辨别找出物件中的特征,例如:线条.他的算法流程大致如下,给定一个物件.要辨别的 ...
- Hough Transform 霍夫变换检测直线
Hough Transform 霍夫变换检测直线 从理论到代码,再从代码到理论 (1)理论之通俗理解: 1.在图像中检测直线的问题,其实质是找到构成直线的所有的像素点.那么问题就是从找到直线,变成找到 ...
- Hough Transform 的算法思想
1.Hough Transform 的算法思想 在直角坐标系和极坐标系中,点.线是对偶关系. 即直角坐标系中的点是极坐标系中的线,直角坐标系中的线是极坐标系中的点.反之也成立. 如下图所示,想要检测图 ...
- 文献学习(part38)--Adaptive hash retrieval with kernel based similarity
学习笔记,仅供参考,有错必纠 关键词:哈希:k-NN:内核:二进制索引:归一化欧氏距离 文章目录 Adaptive hash retrieval with kernel based similarit ...
- Matlab课后笔记之霍夫变换(Hough Transform)
文章目录 前言 一.代码实现结果图 二.实现代码及其注释 总结 前言 最近开始上计算机视觉的实验课,使用的软件是matlab.老师布置了一项给代码添加注释的作业,是有关于霍夫变换的.刚接触这个软件和它 ...
最新文章
- echarts自动生成图片的解决方案
- shiro+redis实现session共享
- 为什么前后端分离了,你比从前更痛苦?
- Only call `sigmoid_cross_entropy_with_logits` with named arguments解决
- 成功解决ValueError: If using all scalar values, you must pass an index
- 你以为妹子穿短裙真的是为了诱惑你吗?
- 自定义Gradle Plugin
- android音视频指南-支持的媒体格式
- Tachyou alluxio初识
- const成员函数重载
- 表格 滚动条 (tbody部分滚动)
- P1352 没有上司的舞会[树形dp]
- 一文读懂什么是硬件开发、智能硬件、硬件系统?
- C语言运算符优先级(超级详细)
- kingbase 修改数据库密码
- 从最终用户角度来看外部结构_从不同角度来看您最喜欢的游戏
- 任务栏优化工具TrueLaunchBar_我是亲民_新浪博客
- 约束(Constraint)SQL约束有哪几种?【常用的约束】【有例子】【非空约束】【唯一约束】【主键约束】【外键约束】【检查约束】
- html怎么把图做成3d效果,ps怎么制作立体效果 ps做图怎么做出立体的效果
- Mac用户学Python-Day1:安装与环境配置
热门文章
- 1.3 什么公司需要运维
- 学成案例——banner模块和精品模块制作
- mybatis传单个参数报错:There is no getter for property named 'user_id' in 'class java.lang.String
- python环境安装
- GPU Direct p2p、 Nvlink 、GPU DirectRDMA
- 网络协议 (一) TCP/IP 四层模型
- rsync数据同步+inotify实时同步
- cmake使用教程(实操版)
- 【与达梦同行】达梦驱动图谱
- 【Kevin Learn QMUI】-->QMUILinkTextView