Python 如何通过合并形状描述符来提高检测精度?

Python 如何通过合并形状描述符来提高检测精度?,python,numpy,opencv,image-processing,object-detection,Python,Numpy,Opencv,Image Processing,Object Detection,在下面,您可以看到一组属于同一对象的二进制形状,这些形状在视频中根据颜色作为主要特征表示被检测到。 由于我在检测中依赖于对象的颜色,因此在二值遮罩图像中可能会出现其他不相关的对象,因为它们与感兴趣的目标对象具有相似的颜色分布(例如,要检测的对象是红色汽车或绿色汽车) 我试图根据面积和纵横比来区分对象。然而,它并没有有效地工作,因为有其他检测到的不相关对象,它们的面积和纵横比与待检测对象的边界有关,如下图所示 在目标对象上方的图像中,是顶部的白色斑点 如您所见,从视频的不同帧捕获的一组遮罩(参

在下面,您可以看到一组属于同一对象的二进制形状,这些形状在视频中根据颜色作为主要特征表示被检测到。

由于我在检测中依赖于对象的颜色,因此在二值遮罩图像中可能会出现其他不相关的对象,因为它们与感兴趣的目标对象具有相似的颜色分布(例如,要检测的对象是红色汽车或绿色汽车)

我试图根据面积和纵横比来区分对象。然而,它并没有有效地工作,因为有其他检测到的不相关对象,它们的面积和纵横比与待检测对象的边界有关,如下图所示

在目标对象上方的图像中,是顶部的白色斑点

如您所见,从视频的不同帧捕获的一组遮罩(参见第一幅图像)彼此略有不同,并且在一定范围内形成了一些类似的特性,如直肠狭窄

因此,我尝试使用其他功能,如直肠狭窄和Hu矩,因为Hu矩对于给定形状是尺度、位置和旋转不变的。我还使用了另一个属性,如面积、比率,以便使检测更加局限于仅检测目标对象

如您所知,前两个值随对象的轻微变化而略有变化。我计算了前两个Hu值的最小/最大值,并将其用作阈值

我对直肠狭窄度、面积和比率也做了同样的检查,阈值为:

Min-Hu0=0.20888468
Max-Hu0=0.25578612
Min-Hu1=0.01675855
Max-Hu1=0.03461491
#-----------------
Min-rect=0.5267567567567567 #min_rectengularity
Max-rect=0.9272727272727272
#-----------------
Min-area=705.5
Max-area=1048.0
#-----------------
Min-ratio=1.2777777777777777 
Max-ratio=3.0588235294117645
为了计算直肠狭窄度,我做了以下工作:

for cr1 in cnts_red:
 area=cv2.contourArea(cr1)
 x,y,w,h=cv2.boundingRect(cr1)
 rectengularity=area/(w*h)
 
我使用简单的if语句应用这些阈值,如:

if area>=min_area and area<=max_area and 
           aspect=min_aspect and aspect<=max_aspect:
  if rectengularity>= min_rec and rectengularity<= max_rec:

    if HuM[0]>=min_Hu0 and HuM[0]<=max_Hu0 and HuM[1]>=min_Hu1 and HuM[1] 
      <=max_Hu1: 
          
          target_contor =contour 

如果area>=min\u area和area而不是
cv2.boundingRect()
,则使用 ,它查找最小的边界矩形(即,它查找一个旋转的矩形,该矩形最适合您的形状)


通过使用轴对齐的边界矩形,可以在训练数据中找到非常小的矩形值。对于最小的边界矩形,您应该只看到矩形对象的大矩形度值,无论它们的方向如何。

而不是
cv2.boundingRect()
,它查找轴对齐的边界矩形,使用 ,它查找最小的边界矩形(即,它查找一个旋转的矩形,该矩形最适合您的形状)


通过使用轴对齐的边界矩形,可以在训练数据中找到非常小的矩形值。对于最小的边界矩形,无论矩形对象的方向如何,您应该只能看到矩形对象的大矩形度值。

您可以尝试以下方法:

  • 收集大量具有真阳性和假阳性的图像,并将每个斑点标记为真/假

  • 考虑您能够计算的形状特征(等周比、形状及其凸面外壳的周长/面积比、惯性椭圆的偏心率、与预期尺寸的偏差…)

  • 尝试使用单个特征进行分类(检查某些特征的值是否定义了两个单独的子集;如果有效,请在两者之间选择一个阈值)

  • 如果单个特征不够,您可以使用一个简单的分类器,例如具有少量特征的最近邻分类器。您可以只输入距离最近的真实采样数和阈值,也可以同时输入真采样数和假采样数,并指定最近采样数的类型


为了进行必要的测试,强烈建议自动化任务并编写一个输出分类分数的应用程序。无论如何,不要期望100%的准确率。

您可以尝试以下方法:

  • 收集大量具有真阳性和假阳性的图像,并将每个斑点标记为真/假

  • 考虑您能够计算的形状特征(等周比、形状及其凸面外壳的周长/面积比、惯性椭圆的偏心率、与预期尺寸的偏差…)

  • 尝试使用单个特征进行分类(检查某些特征的值是否定义了两个单独的子集;如果有效,请在两者之间选择一个阈值)

  • 如果单个特征不够,您可以使用一个简单的分类器,例如具有少量特征的最近邻分类器。您可以只输入距离最近的真实采样数和阈值,也可以同时输入真采样数和假采样数,并指定最近采样数的类型


为了进行必要的测试,强烈建议自动化任务并编写一个输出分类分数的应用程序。在任何情况下,都不要期望100%的准确度。

如果您已经为汽车旋转了矩形,则从cv2.minareact()的旋转矩形框中获取wh,而不是使用边界框中的wh。如果您需要,它还会告诉您角度或旋转。如果您已经为汽车旋转了矩形,则可以从cv2.minareact()中的旋转矩形框中获取wh,而不是使用边界框中的wh。如果需要,它还会告诉您角度或旋转。@k.jbaili:我还没有尝试过,但根据,该方法返回一个包含中心、大小和角度值的对象。在OpenCV 3.4和4.4(最新版本)中都是如此。我不知道您使用的是哪个版本,可能更旧?@k.jbaili:查看答案中链接的文档
minareact()
返回类型为
RotatedRect
的对象,我在注释中链接了该对象的文档。你说得对。现在我明白了。使用Minarearcht的新值最小为0.78363575554804,最大为1.0。信不信由你,椭圆形状有0.7988个矩形