0

额外的轮廓被填充:
在此处输入图像描述

我正在使用以下代码对给定图像执行轮廓

image = cv.imread('/content/drive/My Drive/Colab Notebooks/digit-recognition/test-2.jfif')
grey = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
grey = cv.GaussianBlur(grey,(5,5),0)
thresh = cv.adaptiveThreshold(grey,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY_INV,11,2)
contours, hierarchy = cv.findContours(thresh, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)

preprocessed_digits = []
for c in contours:
    x,y,w,h = cv.boundingRect(c)
    
    cv.rectangle(image, (x,y), (x+w, y+h), color=(0, 255, 0), thickness=2)
    digit = thresh[y:y+h, x:x+w]
    resized_digit = cv.resize(digit, (18,18))
    padded_digit = np.pad(resized_digit, ((5,5),(5,5)), "constant", constant_values=0)
    plt.imshow(padded_digit, cmap="gray")
    plt.show()
    xdigit = padded_digit.reshape(1,784)
    prediction = neigh.predict(xdigit)
    print("prediction = ",prediction[0])
print("\n\n\n----------------Contoured Image--------------------")
plt.imshow(image, cmap="gray")
plt.show()

这是我正在使用的图像
在此处输入图像描述

如何跳过不必要的轮廓?
如果我不使用自适应阈值,则由于此图像中的光效应,轮廓根本无法正确检测到。尽管这种轮廓
很好,因为它可以正确检测到字母,但唯一的问题是它也检测到了噪声区域。

实验:
我将自适应阈值中的块大小更改为 3,轮廓看起来很完美:
在此处输入图像描述

现在我给出了一个不同的图像,它产生了以下轮廓
在此处输入图像描述

就像在轮廓内制作轮廓一样。这有点令人困惑
,因为我认为 RETR_EXTERNAL 会阻止这种情况。

另一个例子:
在此处输入图像描述

这个轮廓看起来很好。但是图像是这样的 在此处输入图像描述

我不确定是否由于图像的失真而导致
预测错误。 在此处输入图像描述

4

1 回答 1

0

最简单的方法是按大小过滤检测到的边界框,因为所有嘈杂的检测似乎都比您要查找的要小:

for c in contours:
    x,y,w,h = cv.boundingRect(c)    
    if w*h >= 200: 
        cv.rectangle(image, (x,y), (x+w, y+h), color=(0, 255, 0), thickness=2)
        digit = thresh[y:y+h, x:x+w]
        resized_digit = cv.resize(digit, (18,18))
        padded_digit = np.pad(resized_digit, ((5,5),(5,5)), "constant", constant_values=0)
        plt.imshow(padded_digit, cmap="gray")
        plt.show()
        xdigit = padded_digit.reshape(1,784)
        prediction = neigh.predict(xdigit)
        print("prediction = ",prediction[0])

或者,您可以使用不同的过滤方法,例如通过定义每个边界框(直方图)或对比度中应出现的暗像素数量的阈值等。

于 2021-08-22T12:18:05.963 回答