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 获取本机ip地址的两个方法
Feb 25 Python
跟老齐学Python之做一个小游戏
Sep 28 Python
Python如何爬取实时变化的WebSocket数据的方法
Mar 09 Python
浅谈python之高阶函数和匿名函数
Mar 21 Python
Python函数中参数是传递值还是引用详解
Jul 02 Python
numpy数组广播的机制
Jul 12 Python
Pytorch 实现自定义参数层的例子
Aug 17 Python
sklearn+python:线性回归案例
Feb 24 Python
python上传时包含boundary时的解决方法
Apr 08 Python
python通过cython加密代码
Dec 11 Python
python中zip()函数遍历多个列表方法
Feb 18 Python
python爬虫爬取某网站视频的示例代码
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图片的裁剪与缩放生成符合需求的缩略图
2013/01/11 PHP
基于PHP Web开发MVC框架的Smarty使用说明
2013/04/19 PHP
以实例全面讲解PHP中多进程编程的相关函数的使用
2015/08/18 PHP
php提高网站效率的技巧
2015/09/29 PHP
分析PHP中单双引号的误区和双引号小隐患
2016/07/19 PHP
PHP调用接口用post方法传送json数据的实例
2018/05/31 PHP
Thinkphp5.0 框架实现控制器向视图view赋值及视图view取值操作示例
2019/10/12 PHP
[原创]js与自动伸缩图片 自动缩小图片的多浏览器兼容的方法总结
2007/03/12 Javascript
JQuery 常用方法基础教程
2009/02/06 Javascript
JQuery 选择器、过滤器介绍
2011/02/14 Javascript
ajax的hide隐藏问题解决方法
2012/12/11 Javascript
javascript中的五种基本数据类型
2015/08/26 Javascript
基于Flowplayer打造一款免费的WEB视频播放器附源码
2015/09/06 Javascript
整理关于Bootstrap列表组的慕课笔记
2017/03/29 Javascript
JavaScript闭包_动力节点Java学院整理
2017/06/27 Javascript
Angular2.0实现modal对话框的方法示例
2018/02/18 Javascript
vue cli 3.0 使用全过程解析
2018/06/14 Javascript
vue使用@scroll监听滚动事件时,@scroll无效问题的解决方法详解
2019/10/15 Javascript
在VUE中使用lodash的debounce和throttle操作
2020/11/09 Javascript
Python的Django框架中从url中捕捉文本的方法
2015/07/20 Python
实例Python处理XML文件的方法
2015/08/31 Python
Python实现excel转sqlite的方法
2017/07/17 Python
总结Python图形用户界面和游戏开发知识点
2019/05/22 Python
python 字符串常用方法汇总详解
2019/09/16 Python
Python字典深浅拷贝与循环方式方法详解
2020/02/09 Python
python import 上级目录的导入
2020/11/03 Python
Expedia印度:您的一站式在线旅游网站
2017/08/24 全球购物
高中生自我评价个人范文
2013/11/09 职场文书
餐厅楼面部长岗位职责范文
2014/02/16 职场文书
《灰椋鸟》教学反思
2014/04/27 职场文书
学校校庆演讲稿
2014/05/22 职场文书
党员带头倡议书
2015/04/29 职场文书
党小组意见范文
2015/06/08 职场文书
董事长开业致辞
2015/07/29 职场文书
SQL Server 数据库实验课第五周——常用查询条件
2021/04/05 SQL Server
SQL Server中的逻辑函数介绍
2022/05/25 SQL Server