python数字图像处理(16):霍夫圆和椭圆变换
在极坐标中,圆的表示方式为:
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')
结果图如下:原图中的圆用白色绘制,检测出的圆用红色绘制。
例2,检测出下图中存在的硬币。
- 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')
椭圆变换是类似的,使用函数为:
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数字图像处理(16):霍夫圆和椭圆变换的更多相关文章
- 「转」python数字图像处理(18):高级形态学处理
python数字图像处理(18):高级形态学处理 形态学处理,除了最基本的膨胀.腐蚀.开/闭运算.黑/白帽处理外,还有一些更高级的运用,如凸包,连通区域标记,删除小块区域等. 1.凸包 凸包是指一 ...
- python数字图像处理(17):边缘与轮廓
在前面的python数字图像处理(10):图像简单滤波 中,我们已经讲解了很多算子用来检测边缘,其中用得最多的canny算子边缘检测. 本篇我们讲解一些其它方法来检测轮廓. 1.查找轮廓(find_c ...
- python数字图像处理(15):霍夫线变换
在图片处理中,霍夫变换主要是用来检测图片中的几何形状,包括直线.圆.椭圆等. 在skimage中,霍夫变换是放在tranform模块内,本篇主要讲解霍夫线变换. 对于平面中的一条直线,在笛卡尔坐标系中 ...
- python数字图像处理(1):环境安装与配置
一提到数字图像处理编程,可能大多数人就会想到matlab,但matlab也有自身的缺点: 1.不开源,价格贵 2.软件容量大.一般3G以上,高版本甚至达5G以上. 3.只能做研究,不易转化成软件. 因 ...
- 初始----python数字图像处理--:环境安装与配置
一提到数字图像处理编程,可能大多数人就会想到matlab,但matlab也有自身的缺点: 1.不开源,价格贵 2.软件容量大.一般3G以上,高版本甚至达5G以上. 3.只能做研究,不易转化成软件. 因 ...
- 霍夫圆检测 opencv
进行霍夫圆变换中有一个API:HoughCircles(). 第五个参数为double类型的minDist(),为霍夫变换检测到的圆的圆心之间的最小距离,即让算法能明显区分的两个不同圆之间的最小距离. ...
- python数字图像处理(二)关键镜头检测
镜头边界检测技术简述 介绍 作为视频最基本的单元帧(Frame),它的本质其实就是图片,一系列帧通过某种顺序组成在一起就构成了视频.镜头边界是视频相邻两帧出现了某种意义的变化,即镜头边界反映了视频内容 ...
- python数字图像处理(19):骨架提取与分水岭算法
骨架提取与分水岭算法也属于形态学处理范畴,都放在morphology子模块内. 1.骨架提取 骨架提取,也叫二值图像细化.这种算法能将一个连通区域细化成一个像素的宽度,用于特征提取和目标拓扑表示. m ...
- python数字图像处理(三)边缘检测常用算子
在该文将介绍基本的几种应用于边缘检测的滤波器,首先我们读入saber用来做为示例的图像 #读入图像代码,在此之前应当引入必要的opencv matplotlib numpy saber = cv2.i ...
随机推荐
- JAVA中获取路径
内容来自于snannan_268 关键字: java中获取路径 JAVA中获取路径: 1.jsp中取得路径: 以工程名为TEST为例: (1)得到包含工程名的当前页面全路径:request.get ...
- PMBOK(第五版)学习笔记二-十大知识领域(P87)
五大项目管理过程组:启动.规划.执行.监控.收尾过程组 十大知识领域是:项目整合管理.项目范围管理.项目时间管理.项目成本管理.项目质量管理.项目人力资源管理.项目沟通管理.项目风险管理.项目采购管理 ...
- 神奇的decimal,也许面试会问到哦~
这段时间忙的像狗一样,写博客的事情也就耽搁了,继续扯,为什么说decimal神奇呢,大家都知道decimal是基元类型,但是 这个decimal类型在IL中居然没有相应的IL指令,也就是说CLR根本不 ...
- 【转载】CentOS 6.4下Squid代理服务器的安装与配置
一.简介 代理服务器英文全称是Proxy Server,其功能就是代理网络用户去取得网络信息. Squid是一个缓存Internet 数据的软件,其接收用户的下载申请,并自动处理所下载的数据.当一个用 ...
- 好用的排名函数~ROW_NUMBER(),RANK(),DENSE_RANK() 三兄弟
排名函数三兄弟,一看名字就知道,都是为了排名而生!但是各自有各自的特色!以下一个例子说明问题!(以下栗子没有使用Partition By 的关键字,整个结果集进行排序) RANK 每个值一个排名,同样 ...
- 将一列包含多个ID拆分多行
看到个不常见的问题~然后在 Inner Sql Server2008 里面找到一个思路. 如果下面的表结构,如何拆分多行并对应员工号呢? 首先创建测试表 CREATE TABLE Department ...
- C++/CLI——读书笔记《Visual C++/CLI从入门到精通》 第Ⅰ部分
=================================版权声明================================= 版权声明:本文为博主原创文章 未经许可不得转载 请通过右 ...
- pl/sql developer——instant-client 简单配置
instant-client(数据库即时客户端) 官方说明:即时客户端在一个单独的针对 Instant Client 的 OTN 开发和分发许可下提供,它允许大多数许可下载.重新分发和部署到生产环境中 ...
- 注解学习(模仿springMvc的注解注入方式)
最近在看springMvc的源码,看到了该框架的注入注解的部分觉的有点吃力,可能还是对注解的方面的知识还认识的不够深刻,所以特意去学习注解方面的知识.由于本人也是抱着学习的态度来阅读源码,若文章在表述 ...
- 命令行向php传入参数的两种方法
##$argv or $argc $argv 包含当运行于命令行下时传递给当前脚本的参数的数组. $argv[0] 就是脚本文件名. $argc 包含当运行于命令行下时传递给当前脚本的参数的数目 ...