Python实现霍夫圆和椭圆变换代码详解


Posted in Python onJanuary 12, 2018

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

x=x0+rcosθ

y=y0+rsinθ

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

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

霍夫圆检测的函数:

skimage.transform.hough_circle(image, radius)

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

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

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

import numpy as np
import matplotlib.pyplot as plt
from skimage import draw,transform,feature

img = np.zeros((250, 250,3), dtype=np.uint8)
rr, cc = draw.circle_perimeter(60, 60, 50) #以半径50画一个圆
rr1, cc1 = draw.circle_perimeter(150, 150, 60) #以半径60画一个圆
img[cc, rr,:] =255
img[cc1, rr1,:] =255

fig, (ax0,ax1) = plt.subplots(1,2, figsize=(8, 5))

ax0.imshow(img) #显示原图
ax0.set_title('origin image')

hough_radii = np.arange(50, 80, 5) #半径范围
hough_res =transform.hough_circle(img[:,:,0], hough_radii) #圆变换 

centers = [] #保存所有圆心点坐标
accums = [] #累积值
radii = [] #半径

for radius, h in zip(hough_radii, hough_res):
 #每一个半径值,取出其中两个圆
 num_peaks = 2
 peaks =feature.peak_local_max(h, num_peaks=num_peaks) #取出峰值
 centers.extend(peaks)
 accums.extend(h[peaks[:, 0], peaks[:, 1]])
 radii.extend([radius] * num_peaks)

#画出最接近的圆
image =np.copy(img)
for idx in np.argsort(accums)[::-1][:2]:
 center_x, center_y = centers[idx]
 radius = radii[idx]
 cx, cy =draw.circle_perimeter(center_y, center_x, radius)
 image[cy, cx] =(255,0,0)

ax1.imshow(image)
ax1.set_title('detected image')

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

Python实现霍夫圆和椭圆变换代码详解

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

Python实现霍夫圆和椭圆变换代码详解

import numpy as np
import matplotlib.pyplot as plt
from skimage import data, color,draw,transform,feature,util

image = util.img_as_ubyte(data.coins()[0:95, 70:370]) #裁剪原图片
edges =feature.canny(image, sigma=3, low_threshold=10, high_threshold=50) #检测canny边缘

fig, (ax0,ax1) = plt.subplots(1,2, figsize=(8, 5))

ax0.imshow(edges, cmap=plt.cm.gray) #显示canny边缘
ax0.set_title('original iamge')

hough_radii = np.arange(15, 30, 2) #半径范围
hough_res =transform.hough_circle(edges, hough_radii) #圆变换 

centers = [] #保存中心点坐标
accums = [] #累积值
radii = [] #半径

for radius, h in zip(hough_radii, hough_res):
 #每一个半径值,取出其中两个圆
 num_peaks = 2
 peaks =feature.peak_local_max(h, num_peaks=num_peaks) #取出峰值
 centers.extend(peaks)
 accums.extend(h[peaks[:, 0], peaks[:, 1]])
 radii.extend([radius] * num_peaks)

#画出最接近的5个圆
image = color.gray2rgb(image)
for idx in np.argsort(accums)[::-1][:5]:
 center_x, center_y = centers[idx]
 radius = radii[idx]
 cx, cy =draw.circle_perimeter(center_y, center_x, radius)
 image[cy, cx] = (255,0,0)

ax1.imshow(image)
ax1.set_title('detected image')

Python实现霍夫圆和椭圆变换代码详解

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

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表示椭圆方向

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

import matplotlib.pyplot as plt
from skimage import data,draw,color,transform,feature

#加载图片,转换成灰度图并检测边缘
image_rgb = data.coffee()[0:220, 160:420] #裁剪原图像,不然速度非常慢
image_gray = color.rgb2gray(image_rgb)
edges = feature.canny(image_gray, sigma=2.0, low_threshold=0.55, high_threshold=0.8)

#执行椭圆变换
result =transform.hough_ellipse(edges, accuracy=20, threshold=250,min_size=100, max_size=120)
result.sort(order='accumulator') #根据累加器排序

#估计椭圆参数
best = list(result[-1]) #排完序后取最后一个
yc, xc, a, b = [int(round(x)) for x in best[1:5]]
orientation = best[5]

#在原图上画出椭圆
cy, cx =draw.ellipse_perimeter(yc, xc, a, b, orientation)
image_rgb[cy, cx] = (0, 0, 255) #在原图中用蓝色表示检测出的椭圆

#分别用白色表示canny边缘,用红色表示检测出的椭圆,进行对比
edges = color.gray2rgb(edges)
edges[cy, cx] = (250, 0, 0) 

fig2, (ax1, ax2) = plt.subplots(ncols=2, nrows=1, figsize=(8, 4))

ax1.set_title('Original picture')
ax1.imshow(image_rgb)

ax2.set_title('Edge (white) and result (red)')
ax2.imshow(edges)

plt.show()

Python实现霍夫圆和椭圆变换代码详解

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

总结

以上就是本文关于Python实现霍夫圆和椭圆变换代码详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

Python 相关文章推荐
Python Trie树实现字典排序
Mar 28 Python
Python查看多台服务器进程的脚本分享
Jun 11 Python
Python中用于检查英文字母大写的isupper()方法
May 19 Python
Python实现SVN的目录周期性备份实例
Jul 17 Python
django 通过ajax完成邮箱用户注册、激活账号的方法
Apr 17 Python
python实现超市扫码仪计费
May 30 Python
Python实例方法、类方法、静态方法的区别与作用详解
Mar 25 Python
PyCharm专业最新版2019.1安装步骤(含激活码)
Oct 09 Python
Python While循环语句实例演示及原理解析
Jan 03 Python
python GUI库图形界面开发之PyQt5单选按钮控件QRadioButton详细使用方法与实例
Feb 28 Python
python 线程的五个状态
Sep 22 Python
详解python中的异常捕获
Dec 15 Python
微信跳一跳python自动代码解读1.0
Jan 12 #Python
Tornado 多进程实现分析详解
Jan 12 #Python
快速了解Python相对导入
Jan 12 #Python
Python实现翻转数组功能示例
Jan 12 #Python
Python实现求数列和的方法示例
Jan 12 #Python
python+matplotlib演示电偶极子实例代码
Jan 12 #Python
Python实现读取及写入csv文件的方法示例
Jan 12 #Python
You might like
Syphon 虹吸式咖啡壶冲煮–拨动法
2021/03/03 冲泡冲煮
NOT NULL 和NULL
2007/01/15 PHP
phpMyadmin 用户权限中英对照
2010/04/02 PHP
php XMLWriter类的简单示例代码(RSS输出)
2011/09/30 PHP
mysqli_set_charset和SET NAMES使用抉择及优劣分析
2013/01/13 PHP
mysql desc(DESCRIBE)命令实例讲解
2016/09/24 PHP
深入理解PHP的远程多会话调试
2017/09/21 PHP
PHP convert_uudecode()函数讲解
2019/02/14 PHP
php无限极分类实现方法分析
2019/07/04 PHP
PHP基于openssl实现非对称加密代码实例
2020/06/19 PHP
js右键菜单效果代码
2007/07/21 Javascript
jQuery EasyUI API 中文文档 - Calendar日历使用
2011/10/19 Javascript
JSCode all of Brower 全局屏蔽网页右键功能 具体实现
2013/06/05 Javascript
jquery动态增加text元素以及删除文本内容实例代码
2013/07/01 Javascript
js添加table的行和列 具体实现方法
2013/07/22 Javascript
jquery delay()介绍及使用指南
2014/09/02 Javascript
javascript基于prototype实现类似OOP继承的方法
2015/12/16 Javascript
JavaScript判断数字是否为质数的方法汇总
2016/06/02 Javascript
基于jQuery下拉选择框插件支持单选多选功能代码
2016/06/07 Javascript
微信小程序 wxapp画布 canvas详细介绍
2016/10/31 Javascript
js实现无缝滚动图
2017/02/22 Javascript
js实现简单的获取验证码按钮效果
2017/03/03 Javascript
vue移动端裁剪图片结合插件Cropper的使用实例代码
2017/07/10 Javascript
JavaScript累加、迭代、穷举、递归等常用算法实例小结
2018/05/08 Javascript
微信JS-SDK实现微信会员卡功能(给用户微信卡包里发送会员卡)
2019/07/25 Javascript
[45:32]Liquid vs LGD 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
python3转换code128条形码的方法
2019/04/17 Python
使用virtualenv创建Python环境及PyQT5环境配置的方法
2019/09/10 Python
python单例模式原理与创建方法实例分析
2019/10/26 Python
如何通过Python实现RabbitMQ延迟队列
2020/11/28 Python
利用Python实现自动扫雷小脚本
2020/12/17 Python
python 基于opencv实现图像增强
2020/12/23 Python
Python的collections模块真的很好用
2021/03/01 Python
巴西最大的巴士票务门户:Quero Passagem
2020/11/21 全球购物
2015年小学师德师风建设工作总结
2015/10/23 职场文书
php 原生分页
2021/04/01 PHP