OpenCV-Python实现轮廓的特征值

 更新时间:2021年06月09日 15:34:36   作者:一天一篇Python库  
轮廓自身的一些属性特征及轮廓所包围对象的特征对于描述图像具有重要意义。本篇博文将介绍几个轮廓自身的属性特征及轮廓包围对象的特征,感兴趣的可以了解一下

前言

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

宽高比

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

宽高比=宽度/高度

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

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:

宽高比

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:

0.7

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

等效直径

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

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中,函数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中,它还提供了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中,它提供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中,它给我们提供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中,它给我们提供了以下方法进行获取:

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 轮廓的特征值内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • pytorch搭建模型的五大层次级别解读(由浅入深)

    pytorch搭建模型的五大层次级别解读(由浅入深)

    这篇文章主要介绍了pytorch搭建模型的五大层次级别(由浅入深),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • 跟老齐学Python之私有函数和专有方法

    跟老齐学Python之私有函数和专有方法

    这篇文章是老齐学Python系列文章的一篇,主要介绍了跟私有函数和专有方法,需要的朋友可以参考下
    2014-10-10
  • 浅析Python的命名空间与作用域

    浅析Python的命名空间与作用域

    这篇文章主要介绍了Python的命名空间与作用域的相关资料,帮助大家更好的理解和学习python,感兴趣的朋友可以了解下
    2020-11-11
  • python中bytes和str类型的区别

    python中bytes和str类型的区别

    这篇文章主要介绍了python中bytes和str类型的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Python Pandas知识点之缺失值处理详解

    Python Pandas知识点之缺失值处理详解

    这篇文章主要给大家介绍了关于Pandas知识点之缺失值处理的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • python django model联合主键的例子

    python django model联合主键的例子

    今天小编就为大家分享一篇python django model联合主键的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-08-08
  • python中使用pyhook实现键盘监控的例子

    python中使用pyhook实现键盘监控的例子

    这篇文章主要介绍了python中使用pyhook实现键盘监控的例子,包含pyhook的下载地址和手册地址及一个Windows下的监控实例,需要的朋友可以参考下
    2014-07-07
  • 用Python selenium实现淘宝抢单机器人

    用Python selenium实现淘宝抢单机器人

    今天给大家带来的是关于Python实战的相关知识,文章围绕着用Python selenium实现淘宝抢单机器人展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • Python+Pygame编写一个Pong游戏

    Python+Pygame编写一个Pong游戏

    Pong游戏模拟了两个打乒乓球的人,就是在两条线中间有一个点在动,操纵器就是一个摇杆上有一个按钮的那种。本文就来用Python中的Pygame库编写一个Pong小游戏
    2023-01-01
  • 利用python修改json文件的value方法

    利用python修改json文件的value方法

    今天小编就为大家分享一篇利用python修改json文件的value方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12

最新评论