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中easy_install 和 pip 的安装及使用
Jun 05 Python
基于python OpenCV实现动态人脸检测
May 25 Python
python实现简单flappy bird
Dec 24 Python
PyCharm 创建指定版本的 Django(超详图解教程)
Jun 18 Python
pytorch打印网络结构的实例
Aug 19 Python
pygame实现打字游戏
Feb 19 Python
如何使用Python脚本实现文件拷贝
Nov 20 Python
Python TCPServer 多线程多客户端通信的实现
Dec 31 Python
在python下实现word2vec词向量训练与加载实例
Jun 09 Python
python-jwt用户认证食用教学的实现方法
Jan 19 Python
聊一聊python常用的编程模块
May 14 Python
解决python3安装pandas出错的问题
May 20 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
用定制的PHP应用程序来获取Web服务器的状态信息
2006/10/09 PHP
PHP安装memcached扩展笔记
2015/05/28 PHP
php生成固定长度纯数字编码的方法
2015/07/09 PHP
PHP后台实现微信小程序登录
2018/08/03 PHP
JS中Iframe之间传值的方法
2013/03/11 Javascript
jquery设置元素的readonly和disabled的写法
2013/09/22 Javascript
纯JS实现动态时间显示代码
2014/02/08 Javascript
jquery获取tr并更改tr内容示例代码
2014/02/13 Javascript
jQuery级联操作绑定事件实例
2014/09/02 Javascript
常用的JS验证和函数汇总
2014/12/23 Javascript
js实现图片点击左右轮播
2015/07/08 Javascript
第五篇Bootstrap 排版
2016/06/21 Javascript
node.js实现快速截图
2016/08/27 Javascript
js实现表格筛选功能
2017/01/18 Javascript
Omi v1.0.2发布正式支持传递javascript表达式
2017/03/21 Javascript
Bootstrap Table使用整理(二)
2017/06/09 Javascript
jQuery Ajax使用FormData上传文件和其他数据后端web.py获取
2017/06/11 jQuery
微信小程序按钮点击动画效果的实现
2019/09/04 Javascript
Nodejs监控事件循环异常示例详解
2019/09/22 NodeJs
使用Mock.js生成前端测试数据
2020/12/13 Javascript
使用AutoJs实现微信抢红包的代码
2020/12/31 Javascript
python 3.6 +pyMysql 操作mysql数据库(实例讲解)
2017/12/20 Python
python匿名函数lambda原理及实例解析
2020/02/07 Python
Python并发concurrent.futures和asyncio实例
2020/05/04 Python
sklearn的predict_proba使用说明
2020/06/28 Python
浅析css3中matrix函数的使用
2016/06/06 HTML / CSS
英国天然有机美容护肤品:Neal’s Yard Remedies
2018/05/05 全球购物
逻辑链路控制协议
2016/10/01 面试题
大学生毕业自我鉴定范文
2013/09/19 职场文书
产品售后服务承诺书
2014/05/21 职场文书
2014年政协委员工作总结
2014/12/01 职场文书
2015初一年级组工作总结
2015/07/24 职场文书
解决Nginx 配置 proxy_pass 后 返回404问题
2021/03/31 Servers
电脑无法安装Windows 11怎么办?无法安装Win11的解决方法
2021/11/21 数码科技
vue-cil之axios的二次封装与proxy反向代理使用说明
2022/04/07 Vue.js
Python各协议下socket黏包问题原理
2022/04/12 Python