openCV

时间:2015-10-13 14:31:36

标签: python image opencv image-processing

我是openCV(使用Python)和图像处理的新手,并试图启动我自己的项目来学习如何工作。我试图从张开嘴的图像中选择牙齿。我能想到的最好的解决方案是将它与牙齿模板相匹配,并尝试根据我从口腔图像中获得的轮廓来匹配形状。这可能不是最好的解决方案,但看起来确实很容易。

到目前为止,我的代码看起来像这样:

img = cv2.imread('resources/1.jpg', cv2.IMREAD_COLOR)
compare = cv2.imread('resources/template.jpg', cv2.IMREAD_GRAYSCALE)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.bilateralFilter(gray, 11, 17, 17)
edges = cv2.Canny(gray, 20, 10)
compare = cv2.Canny(compare, 200, 200)

contours, _ = cv2.findContours(gray.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
compare_contours, _2 = cv2.findContours(compare.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

for c in contours:
    for c2 in compare_contours:
        ret = cv2.matchShapes(c, c2, 1, 0.0)
        if ret < 0.5:
            peri = cv2.arcLength(c, True)
            approx = cv2.approxPolyDP(c, 0.02 * peri, True)
            cv2.drawContours(img, [approx], -1, (0, 255, 0), 7)

img是嘴巴的图像,比较是我用photoshop选择的相同图像的牙齿,所以我希望至少匹配那个。我目前的问题是匹配的唯一轮廓似乎是图像的框架。

有人可以指出我做错了什么或建议我更好的方法吗?图像大小是否与图像大小有关,如果是这样,调整图像大小的最佳方法是什么?

感谢您的时间!

1 个答案:

答案 0 :(得分:2)

形状描述符是要走的路

为了匹配场景中的物体并且遮挡很少,我建议尝试keypoints extraction then matching,例如SIFT(及其朋友ORB,SURF ......)

我尝试使用this SO answer和您的数据进行SURF模板匹配和可视化的超快速复制/粘贴代码,这很有希望:

SURF matching

它已经显示了4个合理的比赛! =)

如何运作

你需要做一些深入研究才能掌握算法的基础知识,但基本理念仍然不变:

  1. 给定模板图像,根据数学巫术找到兴趣点(角落,具有特征的可识别兴趣点)。这些是{M}值的N列表。这些值表示感兴趣点周围的图像统计(例如局部形状直方图,边缘信息......)
  2. 给定一个场景(包含模板),计算该图像的所有兴趣点。
  3. 通过在M维度中进行距离计算,在场景中查找类似模板的关键点:每个关键点都像是3D中的一个点,匹配2个关键点是相似的只是计算点的距离3D并说“足够接近”!。
  4. 您现在有2组关键点,并且列出了合理的关键点匹配项。您现在正在尝试查看“给定2D矢量列表,找到最合理的位移”(旋转,缩放,平移)
  5. 您的代码

    我针对您的数据尝试了您的代码,这是我通过可视化edgescompare得到的:

     cv2.imshow("Edges",edges)
     cv2.waitKey(0)
    

    Edges

     cv2.imshow("compare",compare)
     cv2.waitKey(0)
    

    Compare

    含义

    正如您所看到的,edges图片中存在大量不相关的短边。 这通常是参数选择过低的精确参数选择的副作用。

    这可能会大大影响形状匹配,因为OpenCV会尝试匹配“edge for edge”,而开放边缘地图可能会给出compare图像的不同结果。

    请参阅此python recipe以查看阈值选择和自动阈值选择器的影响。在任何情况下都非常有用的阅读=)

    更一般地

    让我们围绕您正在进行的约束进行思考,看看是否出现了识别牙齿的解决方案:

    您正在查看包含多个感兴趣特征的图像(1口=数十颗牙齿),但正在尝试找到任何匹配项。没有“错误的答案”,没有狡猾的牙齿状物体可以辨别出来(与真正相关的SO question不同。)

    • 嘴唇由嘴唇划分,有点像。你可以用吗?好吧,对于嘴唇很少或没有嘴唇的人来说很棘手。
    • 牙齿通常位于任何脸部的相同位置(需要引用)。它是导入的,因为人脸检测是一个研究得很好的问题,并且在OpenCV中实现了几个可能对您有帮助的算法(this tutorial for instance)。一旦你有了嘴,就有一个盒子,你肯定会找到你的目标,大大减少问题的范围。

    牙齿:

    • 几乎没有纹理信息(没有来自局部直方图形状的直接帮助)
    • 光度应高于图片旁边的平均值
    • 很少甚至没有饱和度,与红色+高饱和度的嘴唇相反(除非发黄和其他有趣的东西)
    • 主要由其边缘与其他牙齿和背景(口腔/牙龈内部)划界

    您的图片:

    • 有颜色!
      • 表示您可以通过HSV色彩空间访问更多信息
    • 仅针对一面