纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

OpenCV 轮廓的特征值 OpenCV-Python实现轮廓的特征值

一天一篇Python库   2021-06-09 我要评论
想了解OpenCV-Python实现轮廓的特征值的相关内容吗一天一篇Python库在本文为您仔细讲解OpenCV 轮廓的特征值的相关知识和一些Code实例欢迎阅读和指正我们先划重点:OpenCV,轮廓的特征值,OpenCV,轮廓下面大家一起来学习吧

前言

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

宽高比

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

宽高比=宽度/高度

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

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()

运行之后值与效果如下:

上下左右


相关文章

猜您喜欢

  • 栈溢出和堆溢出 详解JVM栈溢出和堆溢出

    想了解详解JVM栈溢出和堆溢出的相关内容吗学而不思则忘在本文为您仔细讲解栈溢出和堆溢出的相关知识和一些Code实例欢迎阅读和指正我们先划重点:JVM栈溢出,JVM堆溢出下面大家一起来学习吧..
  • Java字节流复制图片音频 Java使用字节流实现图片音频的复制

    想了解Java使用字节流实现图片音频的复制的相关内容吗wasane在本文为您仔细讲解Java字节流复制图片音频的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Java字节流复制图片音频,Java字节流下面大家一起来学习吧..

网友评论

Copyright 2020 www.fresh-weather.com 【世纪下载站】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式