【问题标题】:Merging overlapping rectangle with OpenCV使用 OpenCV 合并重叠矩形
【发布时间】:2018-09-13 16:48:37
【问题描述】:

我在 OpenCV 中同时使用两种 Haar 级联算法(正面和侧面)来改进人脸检测。

很遗憾,检测无法正常工作,我不知道如何解决。返回值为2(在一张有5张脸的图片上,正常检测到),所有的矩形都消失了。

这是预期的结果(没有重叠的矩形):

This is the original picture (and also the result.jpg) if you want to make your own test.

这是代码:

import cv2
import numpy as np

image=cv2.imread("/home/pi/Downloads/test.jpg")
face_cascade=cv2.CascadeClassifier("/home/pi/opencv-3.4.0/data/haarcascades/haarcascade_frontalface_alt.xml")
profil_cascade=cv2.CascadeClassifier("/home/pi/opencv-3.4.0/data/haarcascades/haarcascade_profileface_alt.xml")

gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
face=face_cascade.detectMultiScale(gray, 1.06, 5)
profil=profil_cascade.detectMultiScale(gray, 1.1, 5)

combined_array=np.append(face, profil, axis=0)
combined_list=combined_array.tolist()
result=cv2.groupRectangles(combined_list,2)

print("I've found "+str(len(result))+ " face(s)")

for (x,y,w,h) in result[0]:
    cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),2)

cv2.imwrite("/home/pi/Download/result.jpg", image)

【问题讨论】:

  • 找到原始picture。请将其添加到问题中
  • 谢谢你的建议,我已经做到了:)
  • 代码仍然无法重现,因为CascadeClassifier('filepath') 正在尝试从 SO 用户无法使用的文件中加载分类器。此外,您可能需要上传执行后出现的result.jpg 图像,以显示与您想要的图像的比较。无论如何,很可能您使用的预训练模型并没有您想象的那么有效。
  • 你说得对,我已经做出了改变。我没有考虑过这一点,因为我使用的是与 OpenCV 集成的经典 haarcascade 算法,但添加此信息是一个好点
  • 我的意思是,您收到的意外输出很可能取决于您正在加载的模型。我们无权访问"/home/pi/opencv-3.4.0/data/haarcascades/haarcascade_frontalface_alt.xml",因此我们无法测试/调试您的代码。您要么必须发布它,让我们以这种方式加载它,要么找到一个可用的网站,让我们从那里加载它。否则无法重现该问题。

标签: python opencv machine-learning computer-vision


【解决方案1】:

Non Maximum Suppression算法用于解决检测结果重叠的问题。 pyimagesearch 有一篇非常好的文章和代码,可以让你朝着正确的方向前进。

【讨论】:

    【解决方案2】:

    经过大量研究,我已经部分解决了问题

    我已经更改了result=cv2.groupRectanglesThresholdEPS,并且我还在print 函数中对检测到的人脸总数进行了减法 (在combined_list中)和重叠检测的数量(由result返回)

    这是新代码:

    import cv2
    import numpy as np
    
    image=cv2.imread("/home/pi/Downloads/test.jpg")
    face_cascade=cv2.CascadeClassifier("/home/pi/opencv-3.4.0/data/haarcascades/haarcascade_frontalface_alt.xml")
    profil_cascade=cv2.CascadeClassifier("/home/pi/opencv-3.4.0/data/haarcascades/haarcascade_profileface_alt.xml")
    
    gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
    face=face_cascade.detectMultiScale(gray, 1.06, 5)
    profil=profil_cascade.detectMultiScale(gray, 1.1, 5)
    
    combined_array=np.append(face, profil, axis=0)
    combined_list=combined_array.tolist()
    result=cv2.groupRectangles(combined_list,1,0.85)
    
    print("I've found "+str(len(combined_list)-str(len(result[1]))+ " face(s)")
    
    for (x,y,w,h) in result[0]:
        cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),2)
    
    cv2.imwrite("/home/pi/Download/result.jpg", image)
    

    The overlapping rectangles have disappear... but also the other rectangles !

    最后,程序给了我正确的面数(5)并重绘了重叠的矩形(这是个好消息),但是非重叠的矩形已经消失了......

    我尝试通过在 combined_listresult 的坐标之间使用 np.subtract 来解决这个问题,然后使用 for (x,y,w,h) in np.subtract[0] 绘制缺失的矩形,但它没有不行。 原因是重叠矩形的坐标点是直接重新计算的,所以不能和原来的坐标点做减法

    如果有人有解决这个问题的想法,请不要犹豫:)

    【讨论】:

      【解决方案3】:

      openCV 函数 groupRectangles 需要 3 个输入。

      1) rectList : 矩形向量

      2) groupthreshold : 最小可能的矩形数减1

      3) eps : 矩形边之间的相对差异将它们合并成一个组

      您的代码:

         result=cv2.groupRectangles(combined_list,1,0.85)
      

      从您的代码中,您已将 groupthreshold 参数设置为 1,它拒绝所有具有一个矩形的集群。将此参数设置为0,您应该会得到您想要的结果。

      解决方案:

         result=cv2.groupRectangles(combined_list,0,0.85)
      

      下面给出详细解释: (https://docs.opencv.org/3.4/d5/d54/group__objdetect.html#ga3dba897ade8aa8227edda66508e16ab9)

      【讨论】:

      • 感谢您的建议,这是有道理的,但不幸的是它不起作用:o 当我进行更改时,我得到了所有的矩形(还有重叠的矩形)
      • 这可能是因为您的 eps 值不够高。 groupRectangles 是一个用于聚类矩形的函数。如果结果没有返回您想要的值,您可能需要考虑更改输入参数值。
      猜你喜欢
      • 2015-06-13
      • 2016-06-27
      • 2016-10-17
      • 1970-01-01
      • 1970-01-01
      • 2019-12-07
      • 2018-11-02
      • 1970-01-01
      • 2023-04-01
      相关资源
      最近更新 更多