图像处理之霍夫变换圆检测算法

合集下载

霍夫变换检测圆原理

霍夫变换检测圆原理

霍夫变换检测圆原理霍夫变换是一种用于在数字图像或视频中检测几何形状的技术。

其中一种最常用的应用是在二维空间中检测圆形。

霍夫变换的基本原理是将图像空间中的每个点转换为霍夫空间中的一组参数,该参数描述了一个可能的圆,然后在霍夫空间中搜索最具有代表性的参数集合,以确定图像中是否存在圆。

本文将详细介绍霍夫变换检测圆的原理和过程。

1. 霍夫变换霍夫变换是一种将图像中的点集映射到参数空间中表示为极坐标的技术。

对于给定的形状,如直线、圆形或椭圆,霍夫变换可以生成一组参数,以描述该形状的每个可能的实例。

这可以通过对每个可能的中心点和半径组合进行枚举来实现,在霍夫空间中将它们表示为参数空间的样条曲线。

2. 检测圆圆在霍夫空间中用其圆心坐标和半径表示。

要检测一个圆,首先需要在图像空间中检测出可能的圆心。

这可以通过在图像中运行边缘检测算法,如Canny算子,来找到。

找到圆心后,需要枚举半径来计算每个可能的圆周上的点,并将这些点转换到霍夫空间中。

在霍夫空间中,表示每个圆形的样条曲线交点组成强投票区域,这些点表示了最有可能表示检测到的圆形的半径和中心点的参数组合。

- 预处理图像,包括调整亮度、增强对比度、边缘检测等- 使用霍夫变换算法将图像空间中的点转换为霍夫空间中的参数点- 找到霍夫空间中的投票区域,它表示了每个可能的圆形的中心点和半径- 确定投票最多的区域,并将其作为检测到的圆形的属性优点:- 可以用于检测各种形状,不仅仅是圆形- 在处理边缘检测和圆检测问题时具有广泛的适用性- 可以处理噪声or具有较高的鲁棒性- 需要较长的计算时间和更高的计算能力- 对于大规模数据集,内存需求也很高- 在处理复杂形状时可能会有问题。

例如,如果两个圆形共享一条边,则霍夫变换可能会将它们错误地识别为单个圆形5. 总结霍夫变换是一种强大的技术,可以用于在图像或视频中检测几何形状。

在特定的应用程序中,它可以提供更准确和鲁棒的结果,而不会受到传统计算机视觉方法的限制。

霍夫圆算法识别重叠圆

霍夫圆算法识别重叠圆

霍夫圆算法可以用于识别图像中的重叠圆。

霍夫圆检测算法是霍夫变换的一个扩展,它专门用于在数字图像中检测圆形形状。

其基本原理是通过寻找图像中所有可能的圆心和半径组合来确定圆形。

具体步骤如下:
1. 边缘检测:首先对原始图像执行Canny边缘检测以获取边缘信息。

2. 计算梯度:使用Sobel算子或其他梯度计算方法,确定每个像素点的邻域梯度值。

3. 初始化累加器:创建一个累加器空间,用于记录所有可能的圆心(a,b)和半径r。

4. 遍历边缘点:对于Canny边缘二值图中的所有非零像素点,按照其梯度方向(即切线的垂直方向)画线,并将这些线段经过的累加器中的点(a,b)对应的N(a,b)增加1。

5. 统计排序:统计并排序累加器中的值,较大的N(a,b)表明对应点更可能是真实的圆心。

6. 估计半径:针对每个可能的圆心(a,b),计算Canny图中所有非零点到圆心的距离,并进行排序。

根据设定的阈值选择可能的半径。

当需要处理重叠圆的情况时,霍夫圆算法可能需要进一步的优化或与其他技术结合使用以提高准确率和鲁棒性。

例如,可以通过调整参数、增强边缘检测的准确性或采用多尺度分析等策略来改善检测性能。

hough 变换检测圆的一般步骤

hough 变换检测圆的一般步骤

hough 变换检测圆的一般步骤霍夫变换是一种图像处理算法,可用于检测图像中的圆形。

下面是霍夫变换检测圆的一般步骤:1.导入图像:首先,将要检测圆的图像导入到计算机中。

图像可以来自于摄像机、存储设备或是从其他算法的输出中获得。

2.灰度化处理:将彩色图像转换为灰度图像。

这是因为灰度图像只有一个通道,可以简化后续处理步骤。

3. 边缘检测:使用边缘检测算法(如Canny算子)对灰度图像进行处理,提取图像中的边缘。

这一步骤可以帮助找到圆形的边界。

4.霍夫变换:将边缘图像输入到霍夫变换中。

霍夫变换将边缘点从笛卡尔坐标系转换到霍夫空间,形成二维投票器矩阵。

在投票器矩阵中,每个圆形都有一个对应的概率值,用于表示该圆形的可能性。

5.阈值设置:在霍夫变换之后,需要设置一个阈值来确定哪些圆形应被认为是检测到的圆形。

根据应用的需求和图像的噪声程度,可以调整阈值的大小。

较高的阈值会产生较少的圆形,而较低的阈值会产生较多的圆形。

6.圆形检测:根据阈值从投票器矩阵中选择可能的圆形。

这些圆形可能包含噪声或重叠的圆形。

因此,需要进行圆形重叠或去噪的处理。

7.圆形参数提取:从霍夫空间中获取每个候选圆形的参数,如圆心的坐标和半径长度。

8.绘制圆形:根据提取的参数,在原始图像上绘制检测到的圆形。

这样一来,圆形就会在图像中展示出来。

9.输出结果:最后,将包含检测到的圆形的图像保存或显示出来。

可以使用不同的颜色或标记形式来区分不同的圆形。

霍夫变换是一种广泛应用于图像处理和计算机视觉领域的算法。

通过这一变换,我们可以快速准确地检测图像中的圆形,为后续的分析和应用提供基础。

霍夫变换原理检测圆的原理

霍夫变换原理检测圆的原理

霍夫变换原理检测圆的原理霍夫变换(Hough Transform)是一种数字图像处理技术,主要用于检测图像中的模式或物品,如直线、圆或任何其他形状。

其中,检测圆的原理是基于霍夫变换的圆检测算法。

首先,需要明确圆的数学表达式。

圆的一般方程为:(x –a)^2 + (y –b)^2 = r^2其中,a和b表示圆心的坐标,r表示半径。

基于这个数学表达式,可以推导出霍夫圆变换的算法原理。

相比于霍夫直线变换,霍夫圆变换需要考虑三个参数:圆心x坐标、圆心y坐标和半径r。

因此,在霍夫圆变换中,需要构建一个三维空间来表示所有满足圆方程的点。

具体而言,可以将三个参数分别设定成三个坐标轴,其中,x轴表示圆心x坐标,y轴表示圆心y坐标,z轴表示半径r。

接下来,对于给定的图像,利用霍夫圆变换来检测其中所有圆。

步骤如下:1. 选择图像中的一个点。

2. 在三维空间中,遍历所有可能的圆心位置和半径大小。

3. 如果当前遍历到的圆心和半径位置满足圆的方程,那么就在三维空间中标记这个点。

4. 重复步骤1~3,对于所有图像中的点进行遍历。

5. 经过遍历后,在三维空间中,所有标记的点都应该落在同一频繁性最高的球面上。

6. 在球面上,可以定义一个圆心和半径,这个圆心和半径就是最终检测出的圆的位置和大小。

7. 重复步骤1~6,对于所有图像中的圆进行遍历。

霍夫圆变换需要对所有可能的圆心位置和半径大小进行遍历,因此计算量非常大。

为了减少计算时间,通常采用一些优化方法,例如逐步增加圆的半径大小或设定一个半径范围。

总体而言,霍夫圆变换是一种有效的圆检测算法,它不仅可以检测出图像中的所有圆,还可以确定它们的位置和大小。

在计算机视觉、医学图像处理等领域广泛应用。

hough变换检测圆原理

hough变换检测圆原理

hough变换检测圆原理
Hough变换是一种常用的图像处理算法,用于检测图像中的圆形目标。

其原理是将图像中的每个像素点转换为极坐标系下的参数空间,并在该空间中寻找圆心和半径相对应的峰值。

具体实现步骤如下:
1. 对图像进行边缘检测,得到一系列边缘点。

2. 在极坐标系下,将每个边缘点表示为一个三元组(r,θ,a),
其中r表示边缘点到图像原点的距离,θ表示边缘点与x轴的夹角,a表示圆心坐标在x轴上的投影。

3. 在参数空间中建立一个二维数组,表示每个可能的圆心(a,b)和半径r对应的计数值。

4. 遍历所有的边缘点,在参数空间中对应的位置上增加计数值。

5. 在参数空间中寻找计数值最大的位置,该位置所对应的圆心
和半径即为检测到的圆形目标。

通过Hough变换,我们可以快速高效地检测图像中的圆形目标。

该算法在计算复杂度和空间复杂度上相对较高,但其检测精度和鲁棒性较为优秀,广泛应用于计算机视觉和机器人领域。

- 1 -。

霍夫变换检测圆算法流程

霍夫变换检测圆算法流程

霍夫变换检测圆算法流程下载温馨提示:该文档是我店铺精心编制而成,希望大家下载以后,能够帮助大家解决实际的问题。

文档下载后可定制随意修改,请根据实际需要进行相应的调整和使用,谢谢!并且,本店铺为大家提供各种各样类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,如想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by theeditor.I hope that after you download them,they can help yousolve practical problems. The document can be customized andmodified after downloading,please adjust and use it according toactual needs, thank you!In addition, our shop provides you with various types ofpractical materials,such as educational essays, diaryappreciation,sentence excerpts,ancient poems,classic articles,topic composition,work summary,word parsing,copy excerpts,other materials and so on,want to know different data formats andwriting methods,please pay attention!霍夫变换检测圆的算法流程详解霍夫变换是一种在图像处理中广泛使用的经典算法,尤其在检测直线、圆等几何形状方面表现出色。

霍夫变换圆形检测

霍夫变换圆形检测

霍夫变换圆形检测霍夫变换检测圆的原理:⼤家都知道三点可以确定⼀个圆,以这三点做所有半径的圆则必有⼀个公共交点,这个交点为以三点为圆的圆⼼。

霍夫变换检测圆形的原理跟检测直线的原理是⼀样的。

圆的表达式为(x-a)2+(y-b)2=r2,把问题转换成在求解经过像素点最多的 (a,b,r) 参数对。

常⽤检测圆的⽅法:(本⽂⽤的不是该⽅法)参考链接:https:///lancer2015/p/6852488.htmlhttps:///poem_qianmo/article/details/26977557代码如下:#include <opencv2/opencv.hpp> #include <iostream>#include <math.h>using namespace cv;using namespace std;int main(int argc, char** argv) {Mat src, dst;src = imread("L:/8.png");if (!src.data){printf("could not load image...\n");return -1;}char INPUT_TITLE[] = "input image";char OUTPUT_TITLE[] = "hough circle demo";namedWindow(INPUT_TITLE, CV_WINDOW_AUTOSIZE);namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE);imshow(INPUT_TITLE, src);//中值滤波Mat moutput;//GaussianBlur(src, moutput,Size(5,5),0,0);medianBlur(src, moutput, 3);cvtColor(moutput, moutput, CV_BGR2GRAY);//霍夫圆检测vector<Vec3f>pcircles;HoughCircles(moutput,pcircles, CV_HOUGH_GRADIENT, 1, 10, 100, 30, 5, 50); src.copyTo(dst);for (size_t i = 0; i < pcircles.size(); i++){Vec3f cc = pcircles[i];circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 0, 255), 1.5, LINE_AA); //画圆形 //参数:1.要画的图像 2.圆⼼ 3.半径 4.颜⾊ 5.线的粗细 6.线条类型circle(dst, Point(cc[0], cc[1]), 2, Scalar(0, 255, 0), 2, LINE_AA); //画圆⼼ }imshow(OUTPUT_TITLE, dst);waitKey(0);return0;}实验结果:原图检测图:。

霍夫变换检测同心圆

霍夫变换检测同心圆

霍夫变换检测同心圆引言霍夫变换是一种图像处理技术,用于检测图像中的特定形状。

本文将介绍如何使用霍夫变换来检测同心圆。

首先,我们将简要介绍霍夫变换的原理和应用领域。

然后,我们将详细讨论如何在图像中检测同心圆,并提供相关代码示例和实验结果。

霍夫变换原理霍夫变换是由Paul Hough于1962年提出的一种图像处理技术。

它可以用来检测图像中的直线、圆等特定形状。

霍夫变换的基本思想是将图像空间中的点映射到参数空间中,从而使特定形状在参数空间中对应于一个明显的峰值。

以检测直线为例,对于每个图像空间中的点(x, y),我们可以通过一条直线方程ρ = x cos(θ) + y sin(θ)来表示。

其中,ρ是直线到原点的距离,θ是直线与x轴之间的角度。

通过遍历所有可能的ρ和θ值,并统计通过每个点(x, y)的直线数量,在参数空间中找到峰值点即可得到最终检测到的直线。

类似地,我们可以将同心圆表示为一组参数(a, b, r),其中(a, b)是圆心坐标,r 是半径。

通过遍历所有可能的(a, b, r)值,并统计通过每个点(x, y)的圆数量,在参数空间中找到峰值点即可得到最终检测到的同心圆。

霍夫变换检测同心圆步骤以下是使用霍夫变换检测同心圆的步骤:1.读取图像:首先,我们需要从文件或其他数据源中读取待处理的图像。

2.预处理图像:为了提高检测效果,我们通常需要对图像进行预处理。

常见的预处理操作包括灰度化、平滑滤波、边缘检测等。

3.参数空间初始化:根据待检测同心圆的半径范围,初始化参数空间。

参数空间通常以三维数组形式表示,其中第一维表示圆心x坐标,第二维表示圆心y坐标,第三维表示半径r。

4.遍历图像空间:对于每个图像空间中的点(x, y),计算其对应于参数空间中所有可能(a, b, r)值的投票。

投票操作可以简单地增加对应(a, b, r)位置的计数器。

5.寻找峰值点:在参数空间中找到投票数量最多的点,该点对应于检测到的同心圆。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

图像处理之霍夫变换圆检测算法一:霍夫变换检测圆的数学原理根据极坐标,圆上任意一点的坐标可以表示为如上形式, 所以对于任意一个圆, 假设中心像素点p(x0, y0)像素点已知, 圆半径已知,则旋转360由极坐标方程可以得到每个点上得坐标同样,如果只是知道图像上像素点, 圆半径,旋转360°则中心点处的坐标值必定最强.这正是霍夫变换检测圆的数学原理.二:算法流程该算法大致可以分为以下几个步骤三:运行效果图像从空间坐标变换到极坐标效果, 最亮一点为圆心.图像从极坐标变换回到空间坐标,检测结果显示:四:关键代码解析个人觉得这次注释已经是非常的详细啦,而且我写的还是中文注释[java]view plaincopy1./**2. * 霍夫变换处理 - 检测半径大小符合的圆的个数3. * 1. 将图像像素从2D空间坐标转换到极坐标空间4. * 2. 在极坐标空间中归一化各个点强度,使之在0〜255之间5. * 3. 根据极坐标的R值与输入参数(圆的半径)相等,寻找2D空间的像素点6. * 4. 对找出的空间像素点赋予结果颜色(红色)7. * 5. 返回结果2D空间像素集合8. * @return int []9. */10.public int[] process() {11.12.// 对于圆的极坐标变换来说,我们需要360度的空间梯度叠加值13. acc = new int[width * height];14.for (int y = 0; y < height; y++) {15.for (int x = 0; x < width; x++) {16. acc[y * width + x] = 0;17. }18. }19.int x0, y0;20.double t;21.for (int x = 0; x < width; x++) {22.for (int y = 0; y < height; y++) {23.24.if ((input[y * width + x] & 0xff) == 255) {25.26.for (int theta = 0; theta < 360; theta++) {27. t = (theta * 3.14159265) / 180; // 角度值0 ~ 2*PI28. x0 = (int) Math.round(x - r * Math.cos(t));29. y0 = (int) Math.round(y - r * Math.sin(t));30.if (x0 < width && x0 > 0 && y0 < height && y0 > 0) {31. acc[x0 + (y0 * width)] += 1;32. }33. }34. }35. }36. }37.38.// now normalise to 255 and put in format for a pixel array39.int max = 0;40.41.// Find max acc value42.for (int x = 0; x < width; x++) {43.for (int y = 0; y < height; y++) {44.45.if (acc[x + (y * width)] > max) {46. max = acc[x + (y * width)];47. }48. }49. }50.51.// 根据最大值,实现极坐标空间的灰度值归一化处理52.int value;53.for (int x = 0; x < width; x++) {54.for (int y = 0; y < height; y++) {55. value = (int) (((double) acc[x + (y * width)] / (double) max) *255.0);56. acc[x + (y * width)] = 0xff000000 | (value << 16 | value << 8 |value);57. }58. }59.60.// 绘制发现的圆61. findMaxima();62. System.out.println("done");63.return output;64.}完整的算法源代码, 已经全部的加上注释[java]view plaincopy1.package com.gloomyfish.image.transform.hough;2./***3. *4. * 传入的图像为二值图像,背景为黑色,目标前景颜色为为白色5. * @author gloomyfish6. *7. */8.public class CircleHough {9.10.private int[] input;11.private int[] output;12.private int width;13.private int height;14.private int[] acc;15.private int accSize = 1;16.private int[] results;17.private int r; // 圆周的半径大小18.19.public CircleHough() {20. System.out.println("Hough Circle Detection...");21. }22.23.public void init(int[] inputIn, int widthIn, int heightIn, int radius) {24. r = radius;25. width = widthIn;26. height = heightIn;27. input = new int[width * height];28. output = new int[width * height];29. input = inputIn;30.for (int y = 0; y < height; y++) {31.for (int x = 0; x < width; x++) {32. output[x + (width * y)] = 0xff000000; //默认图像背景颜色为黑色33. }34. }35. }36.37.public void setCircles(int circles) {38. accSize = circles; // 检测的个数39. }40.41./**42. * 霍夫变换处理 - 检测半径大小符合的圆的个数43. * 1. 将图像像素从2D空间坐标转换到极坐标空间44. * 2. 在极坐标空间中归一化各个点强度,使之在0〜255之间45. * 3. 根据极坐标的R值与输入参数(圆的半径)相等,寻找2D空间的像素点46. * 4. 对找出的空间像素点赋予结果颜色(红色)47. * 5. 返回结果2D空间像素集合48. * @return int []49. */50.public int[] process() {51.52.// 对于圆的极坐标变换来说,我们需要360度的空间梯度叠加值53. acc = new int[width * height];54.for (int y = 0; y < height; y++) {55.for (int x = 0; x < width; x++) {56. acc[y * width + x] = 0;57. }58. }59.int x0, y0;60.double t;61.for (int x = 0; x < width; x++) {62.for (int y = 0; y < height; y++) {63.64.if ((input[y * width + x] & 0xff) == 255) {65.66.for (int theta = 0; theta < 360; theta++) {67. t = (theta * 3.14159265) / 180; // 角度值0 ~ 2*PI68. x0 = (int) Math.round(x - r * Math.cos(t));69. y0 = (int) Math.round(y - r * Math.sin(t));70.if (x0 < width && x0 > 0 && y0 < height && y0 > 0) {71. acc[x0 + (y0 * width)] += 1;72. }73. }74. }75. }76. }77.78.// now normalise to 255 and put in format for a pixel array79.int max = 0;80.81.// Find max acc value82.for (int x = 0; x < width; x++) {83.for (int y = 0; y < height; y++) {84.85.if (acc[x + (y * width)] > max) {86. max = acc[x + (y * width)];87. }88. }89. }90.91.// 根据最大值,实现极坐标空间的灰度值归一化处理92.int value;93.for (int x = 0; x < width; x++) {94.for (int y = 0; y < height; y++) {95. value = (int) (((double) acc[x + (y * width)] / (double) max) * 255.0);96. acc[x + (y * width)] = 0xff000000 | (value << 16 | value <<8 | value);97. }98. }99.100.// 绘制发现的圆101. findMaxima();102. System.out.println("done");103.return output;104. }105.106.private int[] findMaxima() {107. results = new int[accSize * 3];108.int[] output = new int[width * height];109.110.// 获取最大的前accSize个值111.for (int x = 0; x < width; x++) {112.for (int y = 0; y < height; y++) {113.int value = (acc[x + (y * width)] & 0xff);114.115.// if its higher than lowest value add it and then sort 116.if (value > results[(accSize - 1) * 3]) {117.118.// add to bottom of array119. results[(accSize - 1) * 3] = value; //像素值120. results[(accSize - 1) * 3 + 1] = x; // 坐标X121. results[(accSize - 1) * 3 + 2] = y; // 坐标Y122.123.// shift up until its in right place124.int i = (accSize - 2) * 3;125.while ((i >= 0) && (results[i + 3] > results[i])) { 126.for (int j = 0; j < 3; j++) {127.int temp = results[i + j];128. results[i + j] = results[i + 3 + j];129. results[i + 3 + j] = temp;130. }131. i = i - 3;132.if (i < 0)133.break;134. }135. }136. }137. }138.139.// 根据找到的半径R,中心点像素坐标p(x, y),绘制圆在原图像上140. System.out.println("top " + accSize + " matches:");141.for (int i = accSize - 1; i >= 0; i--) {142. drawCircle(results[i * 3], results[i * 3 + 1], results[i * 3 + 2]);143. }144.return output;145. }146.147.private void setPixel(int value, int xPos, int yPos) {148./// output[(yPos * width) + xPos] = 0xff000000 | (value << 16 | val ue << 8 | value);149. output[(yPos * width) + xPos] = 0xffff0000;150. }151.152.// draw circle at x y153.private void drawCircle(int pix, int xCenter, int yCenter) { 154. pix = 250; // 颜色值,默认为白色155.156.int x, y, r2;157.int radius = r;158. r2 = r * r;159.160.// 绘制圆的上下左右四个点161. setPixel(pix, xCenter, yCenter + radius);162. setPixel(pix, xCenter, yCenter - radius);163. setPixel(pix, xCenter + radius, yCenter);164. setPixel(pix, xCenter - radius, yCenter);165.166. y = radius;167. x = 1;168. y = (int) (Math.sqrt(r2 - 1) + 0.5);169.170.// 边缘填充算法,其实可以直接对循环所有像素,计算到做中心点距离来做171.// 这个方法是别人写的,发现超赞,超好!172.while (x < y) {173. setPixel(pix, xCenter + x, yCenter + y);174. setPixel(pix, xCenter + x, yCenter - y);175. setPixel(pix, xCenter - x, yCenter + y);176. setPixel(pix, xCenter - x, yCenter - y);177. setPixel(pix, xCenter + y, yCenter + x);178. setPixel(pix, xCenter + y, yCenter - x);179. setPixel(pix, xCenter - y, yCenter + x);180. setPixel(pix, xCenter - y, yCenter - x);181. x += 1;182. y = (int) (Math.sqrt(r2 - x * x) + 0.5);183. }184.if (x == y) {185. setPixel(pix, xCenter + x, yCenter + y);186. setPixel(pix, xCenter + x, yCenter - y);187. setPixel(pix, xCenter - x, yCenter + y);188. setPixel(pix, xCenter - x, yCenter - y);189. }190. }191.192.public int[] getAcc() {193.return acc;194. }195.196.}测试的UI类:[java]view plaincopy1.package com.gloomyfish.image.transform.hough;2.3.import java.awt.BorderLayout;4.import java.awt.Color;5.import java.awt.Dimension;6.import java.awt.FlowLayout;7.import java.awt.Graphics;8.import java.awt.Graphics2D;9.import java.awt.GridLayout;10.import java.awt.event.ActionEvent;11.import java.awt.event.ActionListener;12.import java.awt.image.BufferedImage;13.import java.io.File;14.15.import javax.imageio.ImageIO;16.import javax.swing.BorderFactory;17.import javax.swing.JButton;18.import javax.swing.JFrame;19.import javax.swing.JPanel;20.import javax.swing.JSlider;21.import javax.swing.event.ChangeEvent;22.import javax.swing.event.ChangeListener;23.24.public class HoughUI extends JFrame implements ActionListener, ChangeListener {25./**26. *27. */28.public static final String CMD_LINE = "Line Detection";29.public static final String CMD_CIRCLE = "Circle Detection";30.private static final long serialVersionUID = 1L;31.private BufferedImage sourceImage;32.// private BufferedImage houghImage;33.private BufferedImage resultImage;34.private JButton lineBtn;35.private JButton circleBtn;36.private JSlider radiusSlider;37.private JSlider numberSlider;38.public HoughUI(String imagePath)39. {40.super("GloomyFish-Image Process Demo");41.try{42. File file = new File(imagePath);43. sourceImage = ImageIO.read(file);44. } catch(Exception e){45. e.printStackTrace();46. }47. initComponent();48. }49.50.private void initComponent() {51.int RADIUS_MIN = 1;52.int RADIUS_INIT = 1;53.int RADIUS_MAX = 51;54. lineBtn = new JButton(CMD_LINE);55. circleBtn = new JButton(CMD_CIRCLE);56. radiusSlider = new JSlider(JSlider.HORIZONTAL, RADIUS_MIN, RADIUS_MAX, RADIUS_INIT);57. radiusSlider.setMajorTickSpacing(10);58. radiusSlider.setMinorTickSpacing(1);59. radiusSlider.setPaintTicks(true);60. radiusSlider.setPaintLabels(true);61. numberSlider = new JSlider(JSlider.HORIZONTAL, RADIUS_MIN, RADIUS_MAX, RADIUS_INIT);62. numberSlider.setMajorTickSpacing(10);63. numberSlider.setMinorTickSpacing(1);64. numberSlider.setPaintTicks(true);65. numberSlider.setPaintLabels(true);66.67. JPanel sliderPanel = new JPanel();68. sliderPanel.setLayout(new GridLayout(1, 2));69. sliderPanel.setBorder(BorderFactory.createTitledBorder("Settings:"));70. sliderPanel.add(radiusSlider);71. sliderPanel.add(numberSlider);72. JPanel btnPanel = new JPanel();73. btnPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));74. btnPanel.add(lineBtn);75. btnPanel.add(circleBtn);76.77.78. JPanel imagePanel = new JPanel(){79.80.private static final long serialVersionUID = 1L;81.82.protected void paintComponent(Graphics g) {83.if(sourceImage != null)84. {85. Graphics2D g2 = (Graphics2D) g;86. g2.drawImage(sourceImage, 10, 10, sourceImage.getWidth(), sourceImage.getHeight(),null);87. g2.setPaint(Color.BLUE);88. g2.drawString("原图", 10, sourceImage.getHeight() + 30);89.if(resultImage != null)90. {91. g2.drawImage(resultImage, resultImage.getWidth() + 20, 10, resultImage.getWidth(), resultImage.getHeight(), null);92. g2.drawString("最终结果,红色是检测结果", resultImage.getWidth() + 40, sourceImage.getHeight() + 30);93. }94. }95. }96.97. };98.this.getContentPane().setLayout(new BorderLayout());99.this.getContentPane().add(sliderPanel, BorderLayout.NORTH);100.this.getContentPane().add(btnPanel, BorderLayout.SOUTH);101.this.getContentPane().add(imagePanel, BorderLayout.CENTER);102.103.// setup listener104.this.lineBtn.addActionListener(this);105.this.circleBtn.addActionListener(this);106.this.numberSlider.addChangeListener(this);107.this.radiusSlider.addChangeListener(this);108. }109.110.public static void main(String[] args)111. {112. String filePath = System.getProperty ("user.home") + "/Desktop/" + "zhigang/hough-test.png";113. HoughUI frame = new HoughUI(filePath);114.// HoughUI frame = new HoughUI("D:\\image-test\\lines.png");115. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);116. frame.setPreferredSize(new Dimension(800, 600));117. frame.pack();118. frame.setVisible(true);119. }120.121.@Override122.public void actionPerformed(ActionEvent e) {123.if(e.getActionCommand().equals(CMD_LINE))124. {125. HoughFilter filter = new HoughFilter(HoughFilter.LINE_TYPE);126. resultImage = filter.filter(sourceImage, null);127.this.repaint();128. }129.else if(e.getActionCommand().equals(CMD_CIRCLE))130. {131. HoughFilter filter = new HoughFilter(HoughFilter.CIRCLE_TYPE);132. resultImage = filter.filter(sourceImage, null);133.// resultImage = filter.getHoughSpaceImage(sourceImage, null);134.this.repaint();135. }136.137. }138.139.@Override140.public void stateChanged(ChangeEvent e) {141.// TODO Auto-generated method stub142.143. }144.}五:霍夫变换检测圆与直线的图像预处理使用霍夫变换检测圆与直线时候,一定要对图像进行预处理,灰度化以后,提取图像的边缘使用非最大信号压制得到一个像素宽的边缘, 这个步骤对霍夫变换非常重要.否则可能导致霍夫变换检测的严重失真。

相关文档
最新文档