如何使用opencv和python判断图像的形状是对称还是不对称?

5
我正在进行图像特征提取工作,试图识别某个图像是否对称。我使用opecv-python来开发此工作。
下面的代码用于识别感兴趣区域的中心和直径。如何知道这张图片是否对称?
import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.offsetbox import AnchoredText

IMG = '015'
thresh = cv2.imread(IMD+'.png',0)
_, contours,hierarchy = cv2.findContours(thresh,2,1)
print (len(contours))
cnt = contours

for i in range (len(cnt)):
    (x,y),radius = cv2.minEnclosingCircle(cnt[i])
    center = (int(x),int(y))
    radius = int(radius)
    cv2.circle(thresh,center,radius,(0,255,0),2)
    print ('Circle: ' + str(i) + ' - Center: ' + str(center) + ' - Radius: ' + str(radius))
plt.text(x-21, y+15, '+', fontsize=25, color = 'red')
plt.text(10, -10, 'Centro: '+str(center), fontsize=11, color = 'red')
plt.text(340, -10, 'Diametro: '+str((radius*2)/100)+'mm', fontsize=11,     color = 'red')
plt.Circle((10, -10), 7.2, color='blue')
plt.imshow(thresh, cmap='gray')
#plt.savefig(IMG+'-diam.png')
plt.show()

退出: 在此输入图像描述

在这种情况下,我想要对我正在分析的斑点进行分类,判断其是否对称。从下面的图像可以看出,它不对称,而上面绘图的第一幅图像是对称的。

enter image description here


既然你已经知道中心了,我不明白问题出在哪里。你是如何看待对称性的?将其分为两个“伪”半圆并进行右侧比较? 这个链接可能有所帮助:http://answers.opencv.org/question/877/how-to-match-2-hog-for-object-detection/#882 - Rick M.
我们在谈论像素级对称吗? - micycle
@micycle,我更新了问题,当说到完美像素时,那是什么意思?我在这个领域还是个门外汉,正在学习中。 - Carlos Diego
1
你能详细解释一下如何将斑点分类为对称或不对称吗?对我来说,也许对任何人来说,以上图片都不看起来对称...实际上它们看起来相似对称 - 如果你在第一张图片垂直切割成两半,两半会是“相似的”,如果你以45度角切割第二张图片,同样也是如此。但实际上它们都不是对称的。 - kavko
@kavko 我正在研究皮肤贴片,以确定它们是否致癌。皮肤科医生使用ABCD规则,A-不对称性;B-边界;C-颜色;D-直径,而我只想识别不对称性。就像这张图片中的一样:https://www.google.com.br/search?q=regras+abcd&source=lnms&tbm=isch&sa=X&ved=0ahUKEwid6qHXvtTeAhXKk5AKHSoSArsQ_AUIEygB&biw=1366&bih=600#imgrc=Kt0VYg3m80rAEM: - Carlos Diego
1
定义对象对称性的一种方法是计算对象内坐标所得到的两个特征值之间的比率。更多细节请参见以下链接:https://alyssaq.github.io/2015/computing-the-axes-or-orientation-of-a-blob - pangyuteng
2个回答

8
我假设变量thresh是一个二值图像。
为了找到非均匀物体的对称性,我建议我们比较X和Y轴上二进制像素的投影。 enter image description here 然后通过直方图比较方法(如相关性,卡方或Bhattacharyya距离)来比较这两个直方图。(在OpenCV中的示例:https://docs.opencv.org/2.4/doc/tutorials/imgproc/histograms/histogram_comparison/histogram_comparison.html
G_X = cv2.reduce(thresh_square, 0 ,cv2.REDUCE_SUM)
G_Y = cv2.reduce(thresh_square, 1 ,cv2.REDUCE_SUM)

compare_val = cv2.compareHist(G_X ,G_Y ,cv2.HISTCMP_CORREL)

其中thresh_square是以二进制斑点为中心的平方ROI。您需要对G_X和G_Y具有相等的箱子才能进行有意义的比较。

更高的相关值应该对应于对称对象,而更低的相关值将对应于非对称对象。

运行此代码以几个对称和非对称示例,并检查compare_val值。您应该能够找到一个阈值来分离这两个对象。


3
以下是我解决这个问题的步骤:
  1. 测量每个半径与中心点之间的距离
  2. 将测量结果分为两组(0到180度和180到360度)
  3. 获取两组数据的平均值,并比较它们是否在误差范围内相等。
  4. 将分组旋转1度并重复上面的步骤,直到达到179度
  5. 检查任何返回结果是否在误差范围内相等。
您可能需要稍微调整相等的误差范围,以找到可接受的准确范围。
此外,您可能需要进行提案检查以查看x次旋转是否在误差范围内相等,然后对称。您还可能需要将其分成四个象限而不是半个象限,这取决于您想要检查对称性的轴数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接