首页 > 解决方案 > 用于 OCR 的清洁图像

问题描述

我一直在尝试为 OCR 清理此图像,但结果好坏参半:

在此处输入图像描述

我取得的最好成绩:

在此处输入图像描述

def image_smoothening(img):
    ret1, th1 = cv2.threshold(img, 180, 255, cv2.THRESH_BINARY)
    ret2, th2 = cv2.threshold(th1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    blur = cv2.GaussianBlur(th2, (1, 1), 0)
    ret3, th3 = cv2.threshold(
        blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    return th3
    
def remove_noise_and_smooth(img):
    filtered = cv2.adaptiveThreshold(img.astype(
        np.uint8), 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 45, 3)
    kernel = np.ones((1, 1), np.uint8)
    opening = cv2.morphologyEx(filtered, cv2.MORPH_OPEN, kernel)
    closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel)
    img = image_smoothening(img)
    or_image = cv2.bitwise_or(img, closing)
    return or_image

关于我缺少什么的任何线索?

标签: pythonopencvimage-processingocrimage-segmentation

解决方案


我的 MATLAB 代码来解决它。我知道你是用 Python 写的,所以你必须翻译。

%Read in
im = imread('DuQy7.png');
%Convert to grayscale
img = rgb2gray(im);
img = rescale(img);
%Binarize with threshold of 0.7/1.0
imbw = imbinarize(img,0.7/1);
%Flip blacks/whites
imbw = imcomplement(imbw);
%Label, L is labelled image, n is # of labels
[L,n] = bwlabeln(imbw);

count = zeros(n,1);
[y,x] = size(L);

%Get count for each label
L = uint8(L);
for j=1:y
    for i=1:x
        if L(j,i) ~= 0
            count(L(j,i)) = count(L(j,i)) + 1;
        end
    end
end

%Find label with most values in image
max = 0;
maxi = 1;
for index=1:n
    if max < count(index)
        max = count(index);
        maxi = index;
    end
end

%Replace large region and color other labels to white
for j=1:y
    for i=1:x
        if L(j,i) == maxi
            L(j,i) = 0;
        elseif L(j,i) ~= 0
            L(j,i) = 256;
        end
    end
end

%view and save
imshow(L)
imwrite(L,'outputTXT.bmp');

输出-TXT.png

您可能可以更好地调整阈值以更好地去除包含的背景区域。您还可以查找非常小的标记区域并将其删除,因为它们可能被错误地包含在内。

背景的某些部分将无法摆脱,因为它们与实际符号无法区分。例如,在符号 x2,y1 和 x2,y2 之间有一个黑色背景区域,其轮廓为白色,与符号的值相同。因此很难解析出来。


推荐阅读