在极坐标中,圆的表示方式为:

x=x0+rcosθ

y=y0+rsinθ

圆心为(x0,y0),r为半径,θ为旋转度数,值范围为0-359

如果给定圆心点和半径,则其它点是否在圆上,我们就能检测出来了。在图像中,我们将每个非0像素点作为圆心点,以一定的半径进行检测,如果有一个点在圆上,我们就对这个圆心累加一次。如果检测到一个圆,那么这个圆心点就累加到最大,成为峰值。因此,在检测结果中,一个峰值点,就对应一个圆心点。

霍夫圆检测的函数:

skimage.transform.hough_circle(imageradius)

radius是一个数组,表示半径的集合,如[3,4,5,6]

返回一个3维的数组(radius index, M, N), 第一维表示半径的索引,后面两维表示图像的尺寸。

例1:绘制两个圆形,用霍夫圆变换将它们检测出来。

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from skimage import draw,transform,feature
  4.  
  5. img = np.zeros((250, 250,3), dtype=np.uint8)
  6. rr, cc = draw.circle_perimeter(60, 60, 50) #以半径50画一个圆
  7. rr1, cc1 = draw.circle_perimeter(150, 150, 60) #以半径60画一个圆
  8. img[cc, rr,:] =255
  9. img[cc1, rr1,:] =255
  10.  
  11. fig, (ax0,ax1) = plt.subplots(1,2, figsize=(8, 5))
  12.  
  13. ax0.imshow(img) #显示原图
  14. ax0.set_title('origin image')
  15.  
  16. hough_radii = np.arange(50, 80, 5) #半径范围
  17. hough_res =transform.hough_circle(img[:,:,0], hough_radii) #圆变换
  18.  
  19. centers = [] #保存所有圆心点坐标
  20. accums = [] #累积值
  21. radii = [] #半径
  22.  
  23. for radius, h in zip(hough_radii, hough_res):
  24. #每一个半径值,取出其中两个圆
  25. num_peaks = 2
  26. peaks =feature.peak_local_max(h, num_peaks=num_peaks) #取出峰值
  27. centers.extend(peaks)
  28. accums.extend(h[peaks[:, 0], peaks[:, 1]])
  29. radii.extend([radius] * num_peaks)
  30.  
  31. #画出最接近的圆
  32. image =np.copy(img)
  33. for idx in np.argsort(accums)[::-1][:2]:
  34. center_x, center_y = centers[idx]
  35. radius = radii[idx]
  36. cx, cy =draw.circle_perimeter(center_y, center_x, radius)
  37. image[cy, cx] =(255,0,0)
  38.  
  39. ax1.imshow(image)
  40. ax1.set_title('detected image')

结果图如下:原图中的圆用白色绘制,检测出的圆用红色绘制。

例2,检测出下图中存在的硬币。

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from skimage import data, color,draw,transform,feature,util
  4.  
  5. image = util.img_as_ubyte(data.coins()[0:95, 70:370]) #裁剪原图片
  6. edges =feature.canny(image, sigma=3, low_threshold=10, high_threshold=50) #检测canny边缘
  7.  
  8. fig, (ax0,ax1) = plt.subplots(1,2, figsize=(8, 5))
  9.  
  10. ax0.imshow(edges, cmap=plt.cm.gray) #显示canny边缘
  11. ax0.set_title('original iamge')
  12.  
  13. hough_radii = np.arange(15, 30, 2) #半径范围
  14. hough_res =transform.hough_circle(edges, hough_radii) #圆变换
  15.  
  16. centers = [] #保存中心点坐标
  17. accums = [] #累积值
  18. radii = [] #半径
  19.  
  20. for radius, h in zip(hough_radii, hough_res):
  21. #每一个半径值,取出其中两个圆
  22. num_peaks = 2
  23. peaks =feature.peak_local_max(h, num_peaks=num_peaks) #取出峰值
  24. centers.extend(peaks)
  25. accums.extend(h[peaks[:, 0], peaks[:, 1]])
  26. radii.extend([radius] * num_peaks)
  27.  
  28. #画出最接近的5个圆
  29. image = color.gray2rgb(image)
  30. for idx in np.argsort(accums)[::-1][:5]:
  31. center_x, center_y = centers[idx]
  32. radius = radii[idx]
  33. cx, cy =draw.circle_perimeter(center_y, center_x, radius)
  34. image[cy, cx] = (255,0,0)
  35.  
  36. ax1.imshow(image)
  37. ax1.set_title('detected image')

椭圆变换是类似的,使用函数为:

skimage.transform.hough_ellipse(img,accuracy, threshold, min_size, max_size)

输入参数:

img: 待检测图像。

accuracy: 使用在累加器上的短轴二进制尺寸,是一个double型的值,默认为1

thresh: 累加器阈值,默认为4

min_size: 长轴最小长度,默认为4

max_size: 短轴最大长度,默认为None,表示图片最短边的一半。

返回一个 [(accumulator, y0, x0, a, b, orientation)] 数组,accumulator表示累加器,(y0,x0)表示椭圆中心点,(a,b)分别表示长短轴,orientation表示椭圆方向

例:检测出咖啡图片中的椭圆杯口

  1. import matplotlib.pyplot as plt
  2. from skimage import data,draw,color,transform,feature
  3.  
  4. #加载图片,转换成灰度图并检测边缘
  5. image_rgb = data.coffee()[0:220, 160:420] #裁剪原图像,不然速度非常慢
  6. image_gray = color.rgb2gray(image_rgb)
  7. edges = feature.canny(image_gray, sigma=2.0, low_threshold=0.55, high_threshold=0.8)
  8.  
  9. #执行椭圆变换
  10. result =transform.hough_ellipse(edges, accuracy=20, threshold=250,min_size=100, max_size=120)
  11. result.sort(order='accumulator') #根据累加器排序
  12.  
  13. #估计椭圆参数
  14. best = list(result[-1]) #排完序后取最后一个
  15. yc, xc, a, b = [int(round(x)) for x in best[1:5]]
  16. orientation = best[5]
  17.  
  18. #在原图上画出椭圆
  19. cy, cx =draw.ellipse_perimeter(yc, xc, a, b, orientation)
  20. image_rgb[cy, cx] = (0, 0, 255) #在原图中用蓝色表示检测出的椭圆
  21.  
  22. #分别用白色表示canny边缘,用红色表示检测出的椭圆,进行对比
  23. edges = color.gray2rgb(edges)
  24. edges[cy, cx] = (250, 0, 0)
  25.  
  26. fig2, (ax1, ax2) = plt.subplots(ncols=2, nrows=1, figsize=(8, 4))
  27.  
  28. ax1.set_title('Original picture')
  29. ax1.imshow(image_rgb)
  30.  
  31. ax2.set_title('Edge (white) and result (red)')
  32. ax2.imshow(edges)
  33.  
  34. plt.show()

霍夫椭圆变换速度非常慢,应避免图像太大。

python数字图像处理(16):霍夫圆和椭圆变换的更多相关文章

  1. 「转」python数字图像处理(18):高级形态学处理

    python数字图像处理(18):高级形态学处理   形态学处理,除了最基本的膨胀.腐蚀.开/闭运算.黑/白帽处理外,还有一些更高级的运用,如凸包,连通区域标记,删除小块区域等. 1.凸包 凸包是指一 ...

  2. python数字图像处理(17):边缘与轮廓

    在前面的python数字图像处理(10):图像简单滤波 中,我们已经讲解了很多算子用来检测边缘,其中用得最多的canny算子边缘检测. 本篇我们讲解一些其它方法来检测轮廓. 1.查找轮廓(find_c ...

  3. python数字图像处理(15):霍夫线变换

    在图片处理中,霍夫变换主要是用来检测图片中的几何形状,包括直线.圆.椭圆等. 在skimage中,霍夫变换是放在tranform模块内,本篇主要讲解霍夫线变换. 对于平面中的一条直线,在笛卡尔坐标系中 ...

  4. python数字图像处理(1):环境安装与配置

    一提到数字图像处理编程,可能大多数人就会想到matlab,但matlab也有自身的缺点: 1.不开源,价格贵 2.软件容量大.一般3G以上,高版本甚至达5G以上. 3.只能做研究,不易转化成软件. 因 ...

  5. 初始----python数字图像处理--:环境安装与配置

    一提到数字图像处理编程,可能大多数人就会想到matlab,但matlab也有自身的缺点: 1.不开源,价格贵 2.软件容量大.一般3G以上,高版本甚至达5G以上. 3.只能做研究,不易转化成软件. 因 ...

  6. 霍夫圆检测 opencv

    进行霍夫圆变换中有一个API:HoughCircles(). 第五个参数为double类型的minDist(),为霍夫变换检测到的圆的圆心之间的最小距离,即让算法能明显区分的两个不同圆之间的最小距离. ...

  7. python数字图像处理(二)关键镜头检测

    镜头边界检测技术简述 介绍 作为视频最基本的单元帧(Frame),它的本质其实就是图片,一系列帧通过某种顺序组成在一起就构成了视频.镜头边界是视频相邻两帧出现了某种意义的变化,即镜头边界反映了视频内容 ...

  8. python数字图像处理(19):骨架提取与分水岭算法

    骨架提取与分水岭算法也属于形态学处理范畴,都放在morphology子模块内. 1.骨架提取 骨架提取,也叫二值图像细化.这种算法能将一个连通区域细化成一个像素的宽度,用于特征提取和目标拓扑表示. m ...

  9. python数字图像处理(三)边缘检测常用算子

    在该文将介绍基本的几种应用于边缘检测的滤波器,首先我们读入saber用来做为示例的图像 #读入图像代码,在此之前应当引入必要的opencv matplotlib numpy saber = cv2.i ...

随机推荐

  1. JAVA中获取路径

    内容来自于snannan_268 关键字: java中获取路径 JAVA中获取路径: 1.jsp中取得路径:   以工程名为TEST为例: (1)得到包含工程名的当前页面全路径:request.get ...

  2. PMBOK(第五版)学习笔记二-十大知识领域(P87)

    五大项目管理过程组:启动.规划.执行.监控.收尾过程组 十大知识领域是:项目整合管理.项目范围管理.项目时间管理.项目成本管理.项目质量管理.项目人力资源管理.项目沟通管理.项目风险管理.项目采购管理 ...

  3. 神奇的decimal,也许面试会问到哦~

    这段时间忙的像狗一样,写博客的事情也就耽搁了,继续扯,为什么说decimal神奇呢,大家都知道decimal是基元类型,但是 这个decimal类型在IL中居然没有相应的IL指令,也就是说CLR根本不 ...

  4. 【转载】CentOS 6.4下Squid代理服务器的安装与配置

    一.简介 代理服务器英文全称是Proxy Server,其功能就是代理网络用户去取得网络信息. Squid是一个缓存Internet 数据的软件,其接收用户的下载申请,并自动处理所下载的数据.当一个用 ...

  5. 好用的排名函数~ROW_NUMBER(),RANK(),DENSE_RANK() 三兄弟

    排名函数三兄弟,一看名字就知道,都是为了排名而生!但是各自有各自的特色!以下一个例子说明问题!(以下栗子没有使用Partition By 的关键字,整个结果集进行排序) RANK 每个值一个排名,同样 ...

  6. 将一列包含多个ID拆分多行

    看到个不常见的问题~然后在 Inner Sql Server2008 里面找到一个思路. 如果下面的表结构,如何拆分多行并对应员工号呢? 首先创建测试表 CREATE TABLE Department ...

  7. C++/CLI——读书笔记《Visual C++/CLI从入门到精通》 第Ⅰ部分

    =================================版权声明================================= 版权声明:本文为博主原创文章 未经许可不得转载  请通过右 ...

  8. pl/sql developer——instant-client 简单配置

    instant-client(数据库即时客户端) 官方说明:即时客户端在一个单独的针对 Instant Client 的 OTN 开发和分发许可下提供,它允许大多数许可下载.重新分发和部署到生产环境中 ...

  9. 注解学习(模仿springMvc的注解注入方式)

    最近在看springMvc的源码,看到了该框架的注入注解的部分觉的有点吃力,可能还是对注解的方面的知识还认识的不够深刻,所以特意去学习注解方面的知识.由于本人也是抱着学习的态度来阅读源码,若文章在表述 ...

  10. 命令行向php传入参数的两种方法

    ##$argv or $argc  $argv 包含当运行于命令行下时传递给当前脚本的参数的数组.  $argv[0]  就是脚本文件名. $argc 包含当运行于命令行下时传递给当前脚本的参数的数目 ...