gpt4 book ai didi

python - 如何在 OpenCV 中实现二值化

转载 作者:太空宇宙 更新时间:2023-11-03 22:04:03 26 4
gpt4 key购买 nike

我在 Matlab 中开发了脚本,用于分析盗色上的雕刻文本。我正在使用一系列形态学技术来提取文本并使用 OCR 阅读。我需要在 Raspberry Pi 上实现它,因此我决定将我的 Matlab 代码传输到 OpenCV(在 python 中)。我尝试转移一些方法,它们的工作方式相似,但如何将 imreconstruct 和 imbinarize(如下所示)实现到 OpenCV? (这里的挑战是适当区分前景和背景)。

也许我应该尝试添加 grabCutgetStructuringElementmorphologyExdilate?我尝试了各种组合,但没有找到完美的解决方案。

如果有人可以就如何总体改进 OCR 过程的这种提取和准确性给我建议,我将把整个脚本放在一起,我将不胜感激。

Based on bin values of grey-scale image. I change some parameters in those functions:

Matlab:

se = strel('disk', 300);
img = imtophat(img, se);
maker = imerode(img, strel('line',100,0)); %for whiter ones
maker = imerode(img, strel('line',85,0)); %for medium
maker = imerode(img, strel('line',5,0));

imgClear = imreconstruct(maker, img);

imgBlur = imgaussfilt(imgClear,1); %less blur for whiter frames

BW = imbinarize(imgBlur,'adaptive','ForegroundPolarity','Bright',...
'Sensitivity',0.7); %process for medium

BW = imbinarize(imgBlur, 'adaptive', 'ForegroundPolarity',...
'Dark', 'Sensitivity', 0.4); % process for black and white

res = ocr(BW, 'CharacterSet', '0123456789', 'TextLayout', 'Block');
res.Text;

OpenCv

kernel = numpy.ones((5,5),numpy.uint8)

blur = cv2.GaussianBlur(img,(5,5),0)
erosion = cv2.erode(blur,kernel,iterations = 1)
opening = cv2.morphologyEx(erosion, cv2.MORPH_OPEN, kernel)

#bremove = cv2.grabCut(opening,mask,rect,bgdModelmode==GC_INIT_WITH_MASK)
#th3 = cv2.adaptiveThreshold(opening,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU,11,2)

ret, thresh= cv2.threshold(opening,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)

ocr = pytesseract.image_to_string(Image.open('image2.png'),config='stdout -c tessedit_char_whitelist=0123456789')

这是输入图像:

enter image description here

Matlab outcome (result 573702)

OpenCV outcome (result 573102

Light colour image

Matlab process full detection rate

最佳答案

当 matlab 和 opencv 似乎都使用相同的算法时,它们之间存在如此大的差异,这让我感到惊讶。为什么要运行 imbinarize 两次? sensitivity 关键字实际上做了什么(数学上,在后台)。因为他们显然比光秃秃的 OTSU 多了几个步骤。

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

def show(img):
plt.imshow(img, cmap="gray")
plt.show()

img = cv2.imread("letters.jpg", cv2.IMREAD_GRAYSCALE)

kernel = np.ones((3,3), np.uint8)

blur = cv2.GaussianBlur(img,(3,3), 0)
erosion = cv2.erode(blur, kernel, iterations=3)
opening = cv2.dilate(erosion, kernel)

th3 = cv2.adaptiveThreshold(opening, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 45, 2)
show(th3)

kernel2 = cv2.getGaussianKernel(6, 2) #np.ones((6,6))
kernel2 = np.outer(kernel2, kernel2)
th3 = cv2.dilate(th3, kernel2)
th3 = cv2.erode(th3, kernel)
show(th3)

显示的图像是:

First image, the immediate result of thresholding

经过一些清理:

A bit more cleaned up and lean. Not really as nice as matlab output.

总而言之,它与 matlab 不同,当然也不如 matlab 好。但基本原理似乎是一样的,只是需要玩弄数字。

更好的方法可能是通过图像的均值做一个阈值,然后使用它的输出作为掩码对原始图像进行自适应阈值处理。希望结果会比 opencv 和 matlab 都好。

试着用 ADAPTIVE_THRESH_MEAN_C 来做,你可以得到一些非常好的结果,但是周围有更多的垃圾。同样,如果您可以将它用作 mask 来隔离文本,然后再次进行阈值处理,结果可能会更好。腐 eclipse 和膨胀内核的形状也会在这里产生很大的不同。

关于python - 如何在 OpenCV 中实现二值化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42551574/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com