OpenCV:检测黑色背景中的正方形

5

目前我正在尝试计算移动物体的光流。具体来说,是围绕圆形旋钮周围的正方形:

红色轮廓是您应该看到正方形的位置

这是我要处理的普通图像:正常图像。查看带红色正方形的图像,以查看我想检测的正方形的位置

我的担忧在于右下方最靠近边缘的部分。当我尝试使用Canny Edge检测或GoodFeaturesToTrack时,通常无法检测到两个正方形。我目前正在尝试锐化内核和阈值,然后进行形态学变换以找到轮廓区域。但是,当我进行阈值处理时,会得到以下结果:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt


filename = 'images/Test21_1.tif'


image = cv.imread(filename)

kernel = [ [0, -1, 0], [-1, 5, -1], [0, -1, 0] ] #sharpen kernel I got from wikipedia

kernel = np.array(kernel)
dst = cv.filter2D(image, -1, kernel)
ret, thresh = cv.threshold(dst, 80, 150, cv.THRESH_BINARY_INV)

plt.subplot(121),plt.imshow(image),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(thresh),plt.title('Threshold')
plt.xticks([]), plt.yticks([])
plt.show()

应用二值化的结果

我想知道如何在openCV中识别这个正方形。这些正方形是视频中移动的物体,我希望使用它们来计算光流。我目前正在考虑使用PyTorch CNN来检测特征。我会手动标注图像以进行训练/测试数据集,但我认为可能有点过度杀伤力。谢谢您的时间。


1
你不能直接计算密集光流吗,而不是先尝试找到方块吗? - dhanushka
1
如果正方形是唯一的移动对象,您也可以应用背景减法。 - David Salb
你们能否给我发送关于如何获取稠密光流和背景减除的链接?我认为在使用光流时通常会使用特定点。谢谢。 - Ammar Hoque
2个回答

2

问题是右下方的方块附近本地对比度不好。您能否尝试使用CLAHE(有限对比度自适应直方图均衡化)进行处理。

# improving local contrast
GRID_SIZE = 20
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(GRID_SIZE,GRID_SIZE))
image = clahe.apply(image)

然后尝试使用您的算法来检测正方形。

2

我不确定这是否更好,但你可以尝试在Python/OpenCV中使用除法归一化技术。

  • 读取输入
  • 转换为灰度图像
  • 应用形态学处理
  • 将输入除以形态学处理的结果
  • 自适应阈值处理
  • 保存结果


import cv2
import numpy as np

# read the image
img = cv2.imread('rods.png')

# convert to gray
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# apply morphology
kernel = cv2.getStructuringElement(cv2.MORPH_RECT , (5,5))
smooth = cv2.morphologyEx(gray, cv2.MORPH_DILATE, kernel)

# divide gray by morphology image
division = cv2.divide(gray, smooth, scale=255)

# threshold
thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 7, 4)

# save results
cv2.imwrite('rods.division.jpg',division)
cv2.imwrite('rods.thresh.jpg',thresh)

# show results
cv2.imshow('smooth', smooth)  
cv2.imshow('division', division)  
cv2.imshow('thresh', thresh)  
cv2.waitKey(0)
cv2.destroyAllWindows()


分割图像:

enter image description here

阈值图像:

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接