注意:新版本的opencv 4 已经没有这个函数 cv2.createShapeContextDistanceExtractor()
形状场景算法是一种用于比较轮廓或形状的方法。这种算法通常用于计算两个形状之间的相似性或差异性,以及找到最佳的匹配方式。
下面是一种基本的比较轮廓的流程,使用了形状场景算法:
数据准备: 首先,你需要准备两个形状的轮廓数据。轮廓可以表示为一系列的点坐标,或者更高级的表示方法,比如参数化的曲线等。
特征提取: 对于每个形状,你可以使用形状描述符或特征提取算法,将轮廓数据转化为一组能够表征形状的数值特征。这些特征可以是形状的曲率、长度、角度等等。
相似性度量: 选择一个相似性度量方法来比较两个形状的特征。常见的方法包括欧氏距离、曼哈顿距离、余弦相似度等。这些度量方法将两个形状的特征转化为一个相似性分数,分数越高表示形状越相似。
匹配与优化: 如果你想要找到最佳的形状匹配,可以使用优化算法来调整一个形状以使其与另一个形状更加相似。这可能涉及到形状的缩放、旋转、平移等变换。
可视化与解释: 最后,你可以可视化两个形状,展示它们的相似性以及在匹配过程中发生的变化。这可以通过绘制形状、展示变换等方式来实现。
需要注意的是,形状场景算法的选择取决于你所处理的具体问题和数据。不同的算法可能在不同的场景下表现更佳。一些常用的形状比较算法包括基于轮廓匹配的方法(如Frechet距离、Hausdorff距离)、基于特征的方法(如傅里叶描述符、轮廓矢量化等)、基于统计的方法(如Procrustes分析)等。
最终,选择适合你问题需求的方法,并根据实际情况进行调整和优化,以得到准确的形状比较结果。
形状场景算法和Hu矩都是用于比较轮廓或形状的方法,但它们基于不同的原理和特征表示。
下面是它们之间的区别:
1. 原理和特征表示:
形状场景算法: 形状场景算法基于整个形状的轮廓信息,通常通过提取一系列特征点的坐标来表示轮廓,然后计算这些特征点之间的几何关系、曲率等信息。这些算法可以比较两个形状之间的形状变化、缩放、旋转等变换。
Hu矩: Hu矩是一组与形状相关的不变矩,用于描述对象的整体形状特征。它们通过对轮廓的几何矩进行变换和归一化得到。Hu矩是一种用于表示形状的紧凑形式,能够在一定程度上保持形状的平移、旋转和缩放不变性。
2. 不变性:
形状场景算法: 形状场景算法通常对形状的几何变换比较敏感,因此可能需要进行额外的处理来考虑形状的平移、旋转和缩放等变换。
Hu矩: Hu矩被设计用于保持一定的形状不变性,它们对于平移、旋转和缩放都具有一定程度的不变性。这使得Hu矩在某些形状匹配和识别任务中非常有用。
3. 适用领域:
形状场景算法: 形状场景算法适用于需要考虑形状变换以及局部特征的情况。例如,可以用于比较两个形状的整体结构和曲率变化。
Hu矩: Hu矩适用于需要保持形状不变性的场景,例如对象识别、图像检索等。它们能够在一定程度上解决形状的旋转、平移和缩放变化对比较造成的影响。
OpenCV 提供了使用“距离”作为形状比较的度量标准。这是因为形状之间的差异值和距离有相似之处,比如二者都只能是零或者正数,又比如当两个形状一模一样时距离值和差值都等于零。
OpenCV 提供了函数 cv2.createShapeContextDistanceExtractor()
,用于计算形状场景距离。
其使用的“形状上下文算法”在计算距离时,在每个点上附加一个“形状上下文”描述符,让每个点都能够捕获剩余点相对于它的分布特征,从而提供全局鉴别特征。
函数 cv2.createShapeContextDistanceExtractor()的语法格式为:
retval = cv2.createShapeContextDistanceExtractor( [, nAngularBins[,
nRadialBins[, innerRadius[, outerRadius[, iterations[, comparer[,
transformer]]]]]]] )
式中的返回值为 retval,返回结果。
该结果可以通过函数 cv2.ShapeDistanceExtractor.computeDistance()计算两个不同形状之间的距离。此函数的语法格式为:
retval=cv2.ShapeDistanceExtractor.computeDistance(contour1, contour2)
式中,coutour1 和 coutour2 是不同的轮廓。
函数 cv2.createShapeContextDistanceExtractor()的参数都是可选参数:
import cv2
#-----------原始图像 o1 的边缘--------------------
o1 = cv2.imread('cs.bmp')
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('cs3.bmp')
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('hand.bmp')
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.matchShapes(cnt1,cnt1)
print("与自身的距离 d1=", d1)
d2 = sd.matchShapes(cnt1,cnt2)
print("与旋转缩放后的自身图像的距离 d2=", d2)
d3 = sd.matchShapes(cnt1,cnt3)
print("与不相似对象的距离 d3=", d3)
cv2.waitKey()
cv2.destroyAllWindows()
运行后报错: