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对url格式解析的方法
May 13 Python
Python3.2中Print函数用法实例详解
May 19 Python
python调用Delphi写的Dll代码示例
Dec 05 Python
python微信公众号之关注公众号自动回复
Oct 25 Python
python基于C/S模式实现聊天室功能
Jan 09 Python
Python中的random.uniform()函数教程与实例解析
Mar 02 Python
利用python在大量数据文件下删除某一行的例子
Aug 21 Python
对python中assert、isinstance的用法详解
Nov 27 Python
Python获取二维数组的行列数的2种方法
Feb 11 Python
通过代码实例解析Pytest运行流程
Aug 20 Python
python 如何将office文件转换为PDF
Sep 22 Python
如何用 Python 制作 GitHub 消息助手
Feb 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中两个float(浮点数)比较实例分析
2015/09/27 PHP
PHP 输出缓冲控制(Output Control)详解
2016/08/25 PHP
php利用imagemagick实现复古老照片效果实例
2017/02/16 PHP
php使用gearman进行任务分发操作实例详解
2020/02/26 PHP
php+websocket 实现的聊天室功能详解
2020/05/27 PHP
JavaScript中使用自然对数ln的方法
2015/06/14 Javascript
深入浅析JavaScript面向对象和原型函数
2016/02/06 Javascript
jQuery实现智能判断固定导航条或侧边栏的方法
2016/09/04 Javascript
JavaScript函数参数的传递方式详解
2017/03/06 Javascript
nodejs个人博客开发第五步 分配数据
2017/04/12 NodeJs
浅谈Angular2 模块懒加载的方法
2017/10/04 Javascript
详解js正则表达式验证时间格式xxxx-xx-xx形式
2018/02/09 Javascript
AngularJS发送异步Get/Post请求方法
2018/08/13 Javascript
node.js实现为PDF添加水印的示例代码
2018/12/05 Javascript
[01:14:10]2014 DOTA2国际邀请赛中国区预选赛 SPD-GAMING VS Orenda
2014/05/22 DOTA
简单讲解Python中的数字类型及基本的数学计算
2016/03/11 Python
20招让你的Python飞起来!
2016/09/27 Python
Python实现对字符串的加密解密方法示例
2017/04/29 Python
对python中url参数编码与解码的实例详解
2019/07/25 Python
基于h5py的使用及数据封装代码
2019/12/26 Python
keras获得某一层或者某层权重的输出实例
2020/01/24 Python
Tensorflow中的dropout的使用方法
2020/03/13 Python
Nginx+Uwsgi+Django 项目部署到服务器的思路详解
2020/05/08 Python
利用CSS3实现自定义滚动条代码分享
2016/08/18 HTML / CSS
中国专业的综合网上购物商城:京东
2016/08/02 全球购物
Rossignol金鸡美国官网:始于1907年法国百年雪具品牌
2019/03/06 全球购物
全球才华横溢工匠的家居装饰、珠宝和礼物:NOVICA
2021/01/22 全球购物
给交警的表扬信
2014/01/12 职场文书
军校大学生个人的自我评价
2014/02/17 职场文书
2014年机关工会工作总结
2014/12/19 职场文书
河童之夏观后感
2015/06/11 职场文书
趣味运动会简讯
2015/07/20 职场文书
给原生html中添加水印遮罩层的实现示例
2021/04/02 Javascript
sql时间段切分实现每隔x分钟出一份高速门架车流量
2022/02/28 SQL Server
python数字图像处理:图像的绘制
2022/06/28 Python
MySQL深分页问题解决思路
2022/12/24 MySQL