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程序中用csv模块来操作csv文件的基本使用教程
Mar 03 Python
Python 安装setuptools和pip工具操作方法(必看)
May 22 Python
使用Python的turtle模块画图的方法
Nov 15 Python
Python3实现的简单验证码识别功能示例
May 02 Python
手把手教你使用Python创建微信机器人
Apr 29 Python
对Python中class和instance以及self的用法详解
Jun 26 Python
详解python解压压缩包的五种方法
Jul 05 Python
Win10环境python3.7安装dlib模块趟过的坑
Aug 01 Python
pytorch 模型可视化的例子
Aug 17 Python
Python 序列化和反序列化库 MarshMallow 的用法实例代码
Feb 25 Python
如何用python插入独创性声明
Mar 31 Python
python 批量压缩图片的脚本
Jun 02 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/11/04 PHP
jquery $(document).ready() 与window.onload的区别
2009/12/28 Javascript
jquery基础教程之deferred对象使用方法
2014/01/22 Javascript
jquery禁用右键示例
2014/04/28 Javascript
jQuery中[attribute]选择器用法实例
2014/12/31 Javascript
基于jQuery仿淘宝产品图片放大镜代码分享
2020/06/23 Javascript
学习javascript面向对象 掌握创建对象的9种方式
2016/01/04 Javascript
node.js 动态执行脚本
2016/06/02 Javascript
JS文件上传神器bootstrap fileinput详解
2021/01/28 Javascript
node.js连接MongoDB数据库的2种方法教程
2017/05/17 Javascript
input file样式修改以及图片预览删除功能详细概括(推荐)
2017/08/17 Javascript
jQuery实现每隔一段时间自动更换样式的方法分析
2018/05/03 jQuery
解决element-ui中下拉菜单子选项click事件不触发的问题
2018/08/22 Javascript
React 路由懒加载的几种实现方案
2018/10/23 Javascript
JavaScript实现留言板案例
2020/03/17 Javascript
在Python的Tornado框架中实现简单的在线代理的教程
2015/05/02 Python
Python虚拟环境Virtualenv使用教程
2015/05/18 Python
Python基于QRCode实现生成二维码的方法【下载,安装,调用等】
2017/07/11 Python
Python实现的字典值比较功能示例
2018/01/08 Python
pandas删除指定行详解
2019/04/04 Python
python opencv实现图像边缘检测
2019/04/29 Python
使用Python爬取弹出窗口信息的实例
2020/03/14 Python
深入分析python 排序
2020/08/24 Python
非常震撼的纯CSS3人物行走动画
2016/02/24 HTML / CSS
处理HTML5新标签的浏览器兼容版问题
2017/03/13 HTML / CSS
英国家庭和商业健身器材购物网站:Fitness Options
2018/07/05 全球购物
印度最好的在线药品订购网站:PharmEasy
2018/11/30 全球购物
娇韵诗香港官网:Clarins香港
2020/08/13 全球购物
银行优秀员工推荐信
2015/03/24 职场文书
旅游投诉信范文
2015/07/02 职场文书
三十年同学聚会致辞
2015/07/28 职场文书
二年级数学教学反思
2016/02/16 职场文书
八年级数学教学反思
2016/02/17 职场文书
物业管理交接协议书
2016/03/24 职场文书
ES6 解构赋值的原理及运用
2021/05/25 Javascript
Python多个MP4合成视频的实现方法
2021/07/16 Python