用矩形比较形状是一种高效的方法。从OpenCV3开始,专有模块shape中的形状场景算法能够更高效地比较形状。

计算形状场景距离

OpenCV提供了函数cv2.createShapeContextDistanceExtractor()用于计算形状场景距离。

语法:

retval = cv2.createShapeContextDistanceExtractor(
                                                  [,nAnglarBins
                                                  [,nRadiaBins
                                                  [,innerRadius
                                                  [,outerRadius
                                                  [,iterations
                                                  [,comparaer
                                                  [,transformer]]]]]]]  )
  • retval为返回值
  • 参数都是可选参数

参数含义

retval结果可以通过cv2.ShapeDistanceExtractor.computeDistance(contours1,contours2)来计算,contours1,contours2是不同的轮廓。

看着有点懵逼,后面的例子里会具体体会如何使用。

例:使用函数cv2.createShapeContextDistanceExtractor()计算形状场景距离。

import cv2

# =====原始图o1的边缘=====
o1 = cv2.imread(r'E:\Blog\OpenCV\Process\C1.png')
cv2.imshow('ORIGINAL1',o1)
gray1 = cv2.cvtColor(o1,cv2.COLOR_BGR2GRAY)
ret,binary1 = cv2.threshold(gray1,127,255,cv2.THRESH_BINARY)
contours1,hierarchy =  cv2.findContours(binary1, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnt1 = contours1[0]

# =====原始图o2的边缘=====
o2 = cv2.imread(r'E:\Blog\OpenCV\Process\C2.png')
cv2.imshow('ORIGINAL2',o2)
gray2 = cv2.cvtColor(o2,cv2.COLOR_BGR2GRAY)
ret,binary2 = cv2.threshold(gray2,127,255,cv2.THRESH_BINARY)
contours2,hierarchy =  cv2.findContours(binary2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnt2 = contours2[0]

# =====原始图o3的边缘=====
o3 = cv2.imread(r'E:\Blog\OpenCV\Process\hand.png')
cv2.imshow('ORIGINAL3',o3)
gray3 = cv2.cvtColor(o3,cv2.COLOR_BGR2GRAY)
ret,binary3 = cv2.threshold(gray3,127,255,cv2.THRESH_BINARY)
contours3,hierarchy =  cv2.findContours(binary3, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnt3 = contours3[0]

# =====构造距离提取算子=====
sd = cv2.createShapeContextDistanceExtractor()

# =====计算距离========
d1 = sd.computeDistance(cnt1,cnt1) #自身与自身距离
print('自身与自身的距离:',d1)
d2 = sd.computeDistance(cnt1,cnt2) #与相似图形(旋转及放缩)距离
print('自身与相似图像的距离:',d2)
d3 = sd.computeDistance(cnt2,cnt3) #与不相似图像距离
print('与不相似图形的距离:',d3)


cv2.waitKey()

运行结果:

自身与自身的距离: 0.0
自身与相似图像的距离: 0.24594146013259888
与不相似图形的距离: 5.083536148071289

Python运行结果

计算Hausdroff距离

Hausdroff距离的计算是:

(1)计算图形A内的每一个点,寻找其距离图像B的最短距离,将这个最短距离作为Hausdroff直接距离D1

(2)计算图形B内的每一个点,寻找其距离图像A的最短距离,将这个最短距离作为Hausdroff直接距离D2

(3)将上述D1、D2中的较大者作为Hausdroff距离

OpenCV提供了函数cv2.createHausdorffDistanceExtractor()来计算Hausdroff距离。语法:

retval = cv2.createHausdorffDistanceExtractor([,distanceFlag[,rankProp]])
  • distanceFlag是距离标记
  • rankProp是一个比例值,是可选参数,范围在[0,1]

例:使用cv2.createHausdorffDistanceExtractor()计算不同图像的Hausdorff距离。

import cv2
from cv2 import contourArea
# =====读取原始图像=====
o1 = cv2.imread(r'E:\Blog\OpenCV\Process\C1.png')
o2 = cv2.imread(r'E:\Blog\OpenCV\Process\C2.png')
o3 = cv2.imread(r'E:\Blog\OpenCV\Process\A6.png')
cv2.imshow('ORIG1',o1)
cv2.imshow('ORIG2',o2)
cv2.imshow('ORIG3',o3)

# =====色彩转换=====
gray1 = cv2.cvtColor(o1,cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(o2,cv2.COLOR_BGR2GRAY)
gray3 = cv2.cvtColor(o3,cv2.COLOR_BGR2GRAY)

# =====阈值处理=====
ret, binary1 = cv2.threshold(gray1,127,255,cv2.THRESH_BINARY)
ret, binary2 = cv2.threshold(gray2,127,255,cv2.THRESH_BINARY)
ret, binary3 = cv2.threshold(gray3,127,255,cv2.THRESH_BINARY)

# =====提取轮廓=====
contour1,hierarchy = cv2.findContours(binary1, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
contour2,hierarchy = cv2.findContours(binary2, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
contour3,hierarchy = cv2.findContours(binary3, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnt1 = contour1[0]
cnt2 = contour2[0]
cnt3 = contour3[0]

# =====构造距离提取算子=====
hd = cv2.createHausdorffDistanceExtractor()

# =====计算距离=====
d1 = hd.computeDistance(cnt1,cnt1) #自身与自身距离
print('自身与自身的距离:',d1)
d2 = hd.computeDistance(cnt1,cnt2) #与相似图形(旋转及放缩)距离
print('自身与相似图像的距离:',d2)
d3 = hd.computeDistance(cnt2,cnt3) #与不相似图像距离
print('与不相似图形的距离:',d3)

cv2.waitKey()

运行结果:

自身与自身的距离: 0.0
自身与相似图像的距离: 40.804412841796875
与不相似图形的距离: 114.38968658447266

运行结果


为什么opencv中没有cv2.createsShapeContextDistanceExtractor()cv2.createHausdorffDistanceExtractor()等函数?

用命令安装contrib这个扩展库:

pip install opencv-contrib-python

示例



博主个人公众号
版权声明 ▶ 本网站名称:陶小桃Blog
▶ 本文链接:https://www.52txr.cn/2022/OpenCV39.html
▶ 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行核实删除。
▶ 转载本站文章需要遵守:商业转载请联系站长,非商业转载请注明出处!!

最后修改:2022 年 05 月 24 日
如果觉得我的文章对你有用,请随意赞赏