使用OpenCV进行矩形检测/跟踪

我需要的

我目前正在做一个增强现实游戏。 游戏使用的控制器(我在这里谈论物理输入设备)是一种单色,长方形纸张。 我必须在相机的捕捉流中检测矩形的位置,旋转和大小。 检测应该在规模上不变,并且沿X和Y轴旋转不变。

如果用户将纸张移开或朝向相机移动,则需要缩放比例不变。 我不需要知道矩形的距离,所以尺度不变性转化为尺寸不变性。

如果用户沿着其本地X轴和/或Y轴倾斜矩形,则需要旋转不变性。 这种旋转将纸张的形状从矩形改变成梯形。 在这种情况下,面向对象的边界框可用于测量纸张的大小。

我所做的

开始时有一个校准步骤。 一个窗口显示相机馈送,用户必须点击矩形。 单击时,鼠标指向的像素颜色将被视为参考颜色。 帧被转换成HSV颜色空间以改善颜色区分。 我有6个滑块可以调整每个通道的上限和下限。 这些阈值用于二值化图像(使用opencv的inRange函数)。
之后,我正在侵蚀和扩大二进制图像,以消除噪音并联合nerby块(使用opencv的erodedilate功能)。
下一步是在二进制图像中查找轮廓(使用opencv的findContours函数)。 这些轮廓用于检测最小方向的矩形(使用opencv的minAreaRect函数)。 作为最终结果,我正在使用面积最大的矩形。

程序的简短结论:

  • 抓住一个框架
  • 将该帧转换为HSV
  • 对其进行二值化(使用用户选择的颜色和滑块的阈值)
  • 应用变形操作(侵蚀和扩张)
  • 找到轮廓
  • 获取每个轮廓的最小取向布线框
  • 以这些边界框中最大的那个为结果
  • 正如您可能已经注意到的那样,我不会利用关于纸张实际形状的知识,只是因为我不知道如何正确使用这些信息。

    我也想过使用opencv的跟踪算法。 但有三个原因阻止我使用它们:

  • 规模不变性:就我所了解的一些算法而言,有些不支持不同比例的对象。
  • 运动预测:一些算法使用运动预测来获得更好的性能,但是我跟踪的对象完全是随机的,因此无法预测。
  • 简单:我只是在图像中寻找一个单色的矩形,没有什么像汽车或人的追踪。
  • 这是一个相对好的捕获(腐蚀和扩张之后的二值图像) 好

    这是一个糟糕的 坏

    问题

    我怎样才能提高检测的总体性,特别是要更好地抵抗照明变化?

    更新

    这里有一些用于测试的原始图像。

    你不能只使用较厚的材料吗?
    是的,我可以和我已经做到了(不幸的是,我目前无法访问这些作品)。 但是,问题依然存在。 即使我使用像cartboard的材料。 它不像纸一样容易弯曲,但仍然可以弯曲。

    你如何获得矩形的大小,旋转和位置?
    opencv的minAreaRect函数返回一个RotatedRect对象。 这个对象包含我需要的所有数据。

    注意
    由于矩形是单色的,所以不可能区分顶部和底部或左右。 这意味着旋转总是处于[0, 180]范围内[0, 180]这对我的目的来说非常合适。 矩形两边的比例总是w:h > 2:1 。 如果矩形是正方形,则roation的范围将变为[0, 90] 0,90 [0, 90] ,但在这里可以认为是不相关的。

    正如评论中所建议的,我会尝试使用直方图均衡来减少亮度问题,并查看ORB,SURF和SIFT。

    我会更新进展情况。


    HSV空间中的H通道是色调,对光线变化不敏感。 红色范围在[150,180]左右。

    基于上述信息,我做了以下工作。

  • 切换到HSV空间,拆分H通道,阈值并对其进行归一化。
  • 应用变形操作(打开)
  • 查找轮廓,根据一些属性(宽度,高度,面积,比率等)进行过滤。
  • PS。 由于NETWORK的原因,我无法在Dropbox上获取您上传的图像。 所以,我只是使用第二张图片的右侧作为输入。

    在这里输入图像描述

    imgname = "src.png"
    img = cv2.imread(imgname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    ## Split the H channel in HSV, and get the red range
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    h,s,v = cv2.split(hsv)
    h[h<150]=0
    h[h>180]=0
    
    ## normalize, do the open-morp-op
    normed = cv2.normalize(h, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8UC1)
    kernel = cv2.getStructuringElement(shape=cv2.MORPH_ELLIPSE, ksize=(3,3))
    opened = cv2.morphologyEx(normed, cv2.MORPH_OPEN, kernel)
    res = np.hstack((h, normed, opened))
    cv2.imwrite("tmp1.png", res)
    

    现在,我们得到这个结果(h,normed,打开):

    在这里输入图像描述

    然后找到轮廓并过滤它们。

    _, contours, _ = cv2.findContours(opened, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    print(len(contours))
    
    bboxes = []
    rboxes = []
    cnts = []
    dst = img.copy()
    for cnt in contours:
        ## Get the stright bounding rect
        bbox = cv2.boundingRect(cnt)
        x,y,w,h = bbox
        if w<30 or h < 30 or w*h < 2000 or w > 500:
            continue
    
        ## Draw rect
        cv2.rectangle(dst, (x,y), (x+w,y+h), (255,0,0), 1, 16)
    
        ## Get the rotated rect
        rbox = cv2.minAreaRect(cnt)
        (cx,cy), (w,h), rot_angle = rbox
        print("rot_angle:", rot_angle)  
    
        ## backup 
        bboxes.append(bbox)
        rboxes.append(rbox)
        cnts.append(cnt)
    

    结果是这样的:

    rot_angle: -2.4540319442749023
    rot_angle: -1.8476102352142334
    

    在这里输入图像描述

    由于源图像中的蓝色矩形标签,卡被分成两面。 但一张干净的图像将没有问题。


    我知道我问这个问题已经有一段时间了。 我最近继续讨论这个话题,并解决了我的问题(尽管不是通过矩形检测)。

    变化

  • 用木头强化我的控制器(“矩形”),如下图。
  • 在每个控制器上放置2个ArUco标记。
  • 调节器

    怎么运行的

  • 将帧转换为灰度,
  • 对其进行降采样(以在检测期间提高性能),
  • 使用cv::equalizeHist直方图,
  • 使用cv::aruco::detectMarkers查找标记,
  • 关联标记(如果有多个控制器),
  • 分析标记(位置和旋转),
  • 计算结果并应用一些错误修正。
  • 事实证明,标记检测对照明变化和不同的视角非常稳健,这使我可以跳过任何校准步骤。

    我在每个控制器上放置了2个标记,以增加检测的鲁棒性。 这两个标记只能被检测一次(以测量它们之间的相关性)。 之后,每个控制器只能找到一个标记就足够了,因为另一个可以从先前计算的相关性中推断出来。

    这是一个明亮的环境中的检测结果:

    在明亮的环境中进行检测

    在黑暗的环境中:

    在黑暗环境中检测

    并且当隐藏其中一个标记时(蓝色点表示外推标记位置):

    缺失标记的检测

    故障

    我实施的初始形状检测效果不佳。 照明变化非常脆弱。 此外,它需要一个初始校准步骤。

    在形状检测方法之后,我尝试使用SIFT和ORB结合强力和knn匹配器来提取和定位帧中的特征。 事实证明,单色的物体没有提供太多的关键点(真是一个惊喜)。 无论如何,SIFT的表现都很糟糕(约10 fps @ 540p)。 我在控制器上绘制了一些线条和其他形状,这导致了更多关键点可用。 然而,这并没有带来巨大的改善。

    链接地址: http://www.djcxy.com/p/39511.html

    上一篇: Rectangle detection / tracking using OpenCV

    下一篇: Please advise me about this Computer Vision task