OpenCV-Python实现轮廓的特征值


Posted in Python onJune 09, 2021

前言

轮廓自身的一些属性特征及轮廓所包围对象的特征对于描述图像具有重要意义。本篇博文将介绍几个轮廓自身的属性特征及轮廓包围对象的特征。

宽高比

在轮廓中,我们可以通过宽高比来描述轮廓,例如矩形的轮廓宽高比为:

宽高比=宽度/高度

下面,我们来计算矩形轮廓的宽高比,代码如下:

import cv2

img = cv2.imread("26_1.jpg")
cv2.imshow("img", img)

# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

x, y, w, h = cv2.boundingRect(contours[0])
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 3)
cv2.imshow("img1", img)

aspectRatio=float(w)/h
print(aspectRatio)

cv2.waitKey()
cv2.destroyAllWindows()

运行之后,我们可以得到轮廓的宽高比约为3:

OpenCV-Python实现轮廓的特征值

Extend

我们还可以使用轮廓面积与矩形边界面积之比Extend来描述图像及其轮廓特征,数学计算公式图下:

Extend=轮廓面积/矩形边界面积

下面,我们来计算Extend,代码如下:

import cv2

img = cv2.imread("26_1.jpg")
cv2.imshow("img", img)

# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

x, y, w, h = cv2.boundingRect(contours[0])
rectArea=w*h#矩形边界面积
cntArea=cv2.contourArea(contours[0])#轮廓面积
extend=float(cntArea)/rectArea
print(extend)

本例中,轮廓面积与矩形边界面积的比值Extend大约为0.8:

OpenCV-Python实现轮廓的特征值

Solidity

我们还可以使用轮廓面积与凸包面积之比Solidity来衡量图像,轮廓以及凸包的特征。其数学计算公式为:

Slidity=轮廓面积/凸包面积

下面,我们来计算Slidity,代码如下:

import cv2

img = cv2.imread("26_1.jpg")
cv2.imshow("img", img)

# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

x, y, w, h = cv2.boundingRect(contours[0])
cntArea=cv2.contourArea(contours[0])#轮廓面积
hull=cv2.convexHull(contours[0])
hullArea=cv2.contourArea(hull)#凸包面积
solidity=float(cntArea)/hullArea
print(solidity)

运行之后,本例轮廓面积与凸包面积的比值solidity约为1:

OpenCV-Python实现轮廓的特征值

等效直径

在OpenCV中,我们还可以使用等效直径来衡量轮廓的特征值,该值是与轮廓面积相等的圆形的直径。其数学计算公式为:

OpenCV-Python实现轮廓的特征值

下面,我们来计算与轮廓面积相等的圆形直径,代码如下:

import cv2
import numpy as np

img = cv2.imread("26_1.jpg")
cv2.imshow("img", img)

# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

x, y, w, h = cv2.boundingRect(contours[0])
cntArea=cv2.contourArea(contours[0])#轮廓面积
equiDiameter=np.sqrt(4*cntArea/np.pi)
print(equiDiameter)
cv2.circle(img,(100,100),int(equiDiameter/2),(0,255,0),3)
cv2.imshow("img1",img)
cv2.waitKey()
cv2.destroyAllWindows()

运行之后,我们得到其等效直径约为145:

OpenCV-Python实现轮廓的特征值

方向

在OpenCV中,函数cv2.fitEllipse()可以用来构建最优拟合椭圆,还可以在返回值内分别返回椭圆的中心点,轴长,旋转角度信息。使用这种形式,能够直观地获取椭圆的方向等信息。

函数cv2.fitEllipse()返回值为:

(x,y):椭圆的中心点

(MA,ma):椭圆水平方向轴与垂直方向轴的长度

angle:椭圆的旋转角度

import cv2

img = cv2.imread("26_1.jpg")
cv2.imshow("img", img)

# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

ellipsis=cv2.fitEllipse(contours[0])

(x, y), (MA, ma), angle = cv2.fitEllipse(contours[0])

print((x, y), (MA, ma), angle)

cv2.ellipse(img, ellipsis, (0, 255, 0), 2)
cv2.imshow("img1", img)
cv2.waitKey()
cv2.destroyAllWindows()

本来就是椭圆图,下面拟合后正好也是椭圆:

OpenCV-Python实现轮廓的特征值

掩摸和像素点

有时候,我们还像获取某对象的掩摸图像及其对应的点。在OpenCV中,它还提供了cv2.findNonZero()函数用于获取一个图像内的轮廓点位置,其完整定义如下:

def findNonZero(src, idx=None):

src:要查找非零元素的图像

idx:返回值,表示非0元素的索引位置。具体格式为(行号,列号)

下面,我们实测该函数,代码如下:

import cv2
import numpy as np

img = cv2.imread("26_1.jpg")

cv2.imshow("img", img)

# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

mask=np.zeros(gray.shape,np.uint8)
cv2.drawContours(mask,[contours[0]],0,255,2)
pixelpoints=cv2.findNonZero(mask)
print(pixelpoints)

cv2.imshow("img1", mask)
cv2.waitKey()
cv2.destroyAllWindows()

运行之后,我们会得到轮廓点位置:

OpenCV-Python实现轮廓的特征值

最大值,最小值以及它们的位置

在OpenCV中,它提供cv2.minMaxLoc()函数获取指定对象内最大值,最小值以及位置等信息,其完整定义如下:

def minMaxLoc(src, mask=None):

src:单通道图像

mask:掩摸,通过使用掩摸图像,得到掩膜指定区域内的最值信息

该函数返回4个值:最小值,最大值,最小值位置,最大值位置。

下面,我们来获取这些值,代码如下:

import cv2
import numpy as np

img = cv2.imread("26_1.jpg")

cv2.imshow("img", img)

# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

mask = np.zeros(gray.shape, np.uint8)
cv2.drawContours(mask, [contours[0]], 0, 255, 2)

min, max, min_loc, max_loc = cv2.minMaxLoc(gray, mask)
print(min, max, min_loc, max_loc)

运行之后,控制台输出4个值:

OpenCV-Python实现轮廓的特征值

平均颜色及平均灰度

在OpenCV中,它给我们提供cv2.mean()函数计算一个对象的平均颜色与平均灰度。其完整定义如下:

def mean(src, mask=None):

参数与上面两个小节一样,这里不在赘述。下面,我们来使用这个函数,代码如下:

import cv2
import numpy as np

img = cv2.imread("26_1.jpg")


cv2.imshow("img", img)

# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

mask=np.zeros(gray.shape,np.uint8)
cv2.drawContours(mask,[contours[0]],0,255,2)

mean=cv2.mean(img,mask)

运行之后,输出4个值:RGB以及A通道的均值:

OpenCV-Python实现轮廓的特征值

极点

有时候,我们希望获取某个对象内的极点,比如最左,最右,最上,最下等。在OpenCV中,它给我们提供了以下方法进行获取:

left=tuple(cnt[cnt[:,:,0].argmin()][0])
right=tuple(cnt[cnt[:,:,0].argmax()][0])
top=tuple(cnt[cnt[:,:,1].argmin()][0])
bottom=tuple(cnt[cnt[:,:,1].argmax()][0])

下面,我们来通过这些方法获取,代码如下:

import cv2
import numpy as np

img = cv2.imread("26_1.jpg")

cv2.imshow("img", img)

# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

mask = np.zeros(img.shape, np.uint8)
cnt = contours[0]
left = tuple(cnt[cnt[:, :, 0].argmin()][0])
right = tuple(cnt[cnt[:, :, 0].argmax()][0])
top = tuple(cnt[cnt[:, :, 1].argmin()][0])
bottom = tuple(cnt[cnt[:, :, 1].argmax()][0])

print(left, right, top, bottom)

font = cv2.FONT_HERSHEY_SIMPLEX

cv2.putText(img, "left", left, font, 1, (0, 255, 0), 2)
cv2.putText(img, "right", right, font, 1, (0, 255, 0), 2)
cv2.putText(img, "top", top, font, 1, (0, 255, 0), 2)
cv2.putText(img, "bottom", bottom, font, 1, (0, 255, 0), 2)

cv2.imshow("result",img)
cv2.waitKey()
cv2.destroyAllWindows()

运行之后,值与效果如下:

OpenCV-Python实现轮廓的特征值

到此这篇关于OpenCV-Python实现轮廓的特征值的文章就介绍到这了,更多相关OpenCV 轮廓的特征值内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
零基础写python爬虫之爬虫编写全记录
Nov 06 Python
详细解读Python中解析XML数据的方法
Oct 15 Python
Python模块WSGI使用详解
Feb 02 Python
Python 内置函数进制转换的用法(十进制转二进制、八进制、十六进制)
Apr 30 Python
用scikit-learn和pandas学习线性回归的方法
Jun 21 Python
Win10下Python3.7.3安装教程图解
Jul 08 Python
在pycharm中配置Anaconda以及pip源配置详解
Sep 09 Python
Python tensorflow实现mnist手写数字识别示例【非卷积与卷积实现】
Dec 19 Python
Python While循环语句实例演示及原理解析
Jan 03 Python
Python爬虫教程知识点总结
Oct 19 Python
python3实现Dijkstra算法最短路径的实现
May 12 Python
Python数据可视化之绘制柱状图和条形图
May 25 Python
再也不用花钱买漫画!Python爬取某漫画的脚本及源码
Jun 09 #Python
Python的这些库,你知道多少?
OpenCV-Python使用cv2实现傅里叶变换
Python合并多张图片成PDF
Jun 09 #Python
Python3 多线程(连接池)操作MySQL插入数据
jupyter notebook保存文件默认路径更改方法汇总(亲测可以)
Django rest framework如何自定义用户表
Jun 09 #Python
You might like
Cakephp 执行主要流程
2010/03/24 PHP
单点登录 Ucenter示例分析
2013/10/29 PHP
php实现复制移动文件的方法
2015/07/29 PHP
laravel5.1框架model类查询的实现方法
2019/10/08 PHP
清华大学出版的事半功倍系列 javascript全部源代码
2007/05/04 Javascript
javascript Array数组对象的扩展函数代码
2010/05/22 Javascript
JavaScript中几种常见排序算法小结
2011/02/22 Javascript
当鼠标滑过文本框自动选中输入框内容的JS代码分享
2013/11/26 Javascript
Active控件问题小结(附解决办法)
2016/06/09 Javascript
Node.js学习入门
2017/01/03 Javascript
jQuery中的一些小技巧
2017/01/18 Javascript
JavaScript常用正则验证函数实例小结【年龄,数字,Email,手机,URL,日期等】
2017/01/23 Javascript
vue-cli脚手架build目录下utils.js工具配置文件详解
2018/09/14 Javascript
浅谈 Webpack 如何处理图片(开发、打包、优化)
2019/05/15 Javascript
在layui中使用form表单监听ajax异步验证注册的实例
2019/09/03 Javascript
解决layer.msg 不居中 ifram中的问题
2019/09/05 Javascript
ES2020让代码更优美的运算符 (?.) (??)
2021/01/04 Javascript
k8s node节点重新加入master集群的实现
2021/02/22 Javascript
Python多进程编程技术实例分析
2014/09/16 Python
在Python中使用matplotlib模块绘制数据图的示例
2015/05/04 Python
python高效过滤出文件夹下指定文件名结尾的文件实例
2018/10/21 Python
python pandas消除空值和空格以及 Nan数据替换方法
2018/10/30 Python
python实现根据文件关键字进行切分为多个文件的示例
2018/12/10 Python
基于python实现高速视频传输程序
2019/05/05 Python
Python 3.8中实现functools.cached_property功能
2019/05/29 Python
十行代码使用Python写一个USB病毒
2019/06/21 Python
有趣的Python图片制作之如何用QQ好友头像拼接出里昂
2020/04/22 Python
python支持多继承吗
2020/06/19 Python
在对linux系统分区进行格式化时需要对磁盘簇(或i节点密度)的大小进行选择,请说明选择的原则
2012/11/24 面试题
论文指导教师评语
2014/04/28 职场文书
群众路线对照检查材料
2014/09/22 职场文书
教师对照四风自我剖析材料
2014/09/30 职场文书
学生检讨书如何写
2014/10/30 职场文书
男方婚前保证书
2015/02/28 职场文书
redis 存储对象的方法对比分析
2021/08/02 Redis
JavaScript小技巧带你提升你的代码技能
2021/09/15 Javascript