从 ASUS Xtion Live Pro 红外图像中检测矩形 table

Detect rectangular table from ASUS Xtion Live Pro IR image

我有一张红外图像,分辨率为 (240 x 320),数据类型:float32,如您在此处所见: 原始 npy 图像是 here

我的 objective 是检测 table(棕色轮廓)以便将此区域裁剪为 ROI。

到目前为止我尝试过的是:

  1. 直方图均衡增加对比度,
  2. 高斯模糊降低噪点,
  3. 轮廓检测找到图像中间的矩形table。

请注意,我的 table 安装在轮子上,因此它可能会轻微移动,所以我想动态检测它,而不是使用它在图像中的固定位置。

我用过的代码是:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
import cv2
import random as rng

path = ""
# Read the numpy array
ir_raw = np.load(path+"ir.npy") # (240, 320) float32

ir = np.uint8((ir_raw/ir_raw.max()) * 255)
# Histogram equalization (Contrast Adjustment)
heq_ir = cv2.equalizeHist(ir)
# Gaussian smoothing (Noise Removal)
g_blur_ir = cv2.GaussianBlur(heq_ir, (5,5), 0)

# Otsu Thresholding
_, thresh_ir = cv2.threshold(g_blur_ir, 120, 255, cv2.THRESH_BINARY + 
                                            cv2.THRESH_OTSU)
# Find contours
contours, hierarchy = cv2.findContours(thresh_ir, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# Draw contours
rng.seed(12345)

drawing = np.zeros((thresh_ir.shape[0], thresh_ir.shape[1], 3), dtype=np.uint8)

for i in range(len(contours)):
    color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
    cv2.drawContours(drawing, contours, i, color, 2, cv2.LINE_8, hierarchy, 0)


plt.subplot(121)
plt.imshow(heq_ir)
plt.title("IR")

plt.subplot(122)
plt.imshow(drawing)
plt.title("IR contours")

plt.show()

能否请您告诉我如何检测矩形 table 以便将其裁剪为 ROI?提前致谢。

假设如下,table 总是有相同的区域(嗯嗯)但在下面的情况下它总是检测到最大的对象(虽然代码应该很容易修改以过滤掉不同区域的对象).

我过滤掉了所有与 table 轮廓具有不同面积的轮廓(消除过程直到我找到 table 然后相应地设置面积阈值)然后拟合一个矩形到那个轮廓。也可以在 OpenCV 中拟合倾斜的矩形,但在这种情况下我没有。 (编辑:添加了倾斜矩形的代码)

您的 ROI 边界在 boundRect

for i in range(len(contours)):
    
    if cv2.contourArea(contours[i]) > 10000:
        
        color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
        cv2.drawContours(drawing, contours, i, color, 2, cv2.LINE_8, hierarchy, 0)

        # For unrotated bounding rectangle
        boundRect = cv2.boundingRect(contours[i])
        cv2.rectangle(drawing, (int(boundRect[0]), int(boundRect[1])), (int(boundRect[0]+boundRect[2]), int(boundRect[1]+boundRect[3])), (255, 255, 255), 2)

        # For minimal bounding rectangle that will rotate with table rotation
        rect = cv2.minAreaRect(contours[i])
        box = cv2.boxPoints(rect) 
        box = np.int0(box)
        cv2.drawContours(drawing, [box], 0, (255, 0, 255), 2)

        print(cv2.contourArea(contours[i]))

输出,