[英]How to implement imbinarize in OpenCV
我在Matlab中開發了腳本,該腳本正在分析顏色竊取上的雕刻文字。 我正在使用多種形態學技術來提取文本並使用OCR進行閱讀。 我需要在Raspberry Pi上實現它,因此我決定將Matlab代碼傳輸到OpenCV(在python中)。 我嘗試轉移一些方法,它們的工作方式相似,但是如何將imreconstruct和imbinarize(如下所示)實現到OpenCV? (這里的挑戰是適當區分前景和背景)。
也許我應該嘗試添加grabCut
或getStructuringElement
或morphologyEx
還是dilate
? 我嘗試了多種組合方式,但沒有找到理想的解決方案。
如果有人可以給我一些建議,以總體上提高OCR過程的提取率和准確性,我將把這兩個腳本放在一起,我將不勝感激。
基於灰度圖像的bin值。 我在這些函數中更改了一些參數:
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')
這是輸入圖像:
我根據您雕刻的文字樣本得出了代碼,得到了肯定的結果。
import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
def show(img):
plt.imshow(img, cmap="gray")
plt.show()
# load the input image
img = cv2.imread('./imagesStackoverflow/engraved_text.jpg',0);
show(img)
ret, mask = cv2.threshold(img, 60, 120, cv2.THRESH_BINARY) # turn 60, 120 for the best OCR results
kernel = np.ones((5,3),np.uint8)
mask = cv2.erode(mask,kernel,iterations = 1)
show(mask)
# I used a version of OpenCV with Tesseract, you may use your pytesseract and set the modes as:
# OCR Enginer Mode (OEM) = 3 (defualt = 3)
# Page Segmentation mode (PSmode) = 11 (defualt = 3)
tesser = cv2.text.OCRTesseract_create('C:/Program Files/Tesseract 4.0.0/tessdata/','eng','0123456789',11,3)
retval = tesser.run(mask, 0) # return string type
print 'OCR:' + retval
處理后的圖像和OCR輸出:
如果您可以提供更多示例圖像來反饋測試結果,那就太好了。
當matlab和opencv看起來都使用相同的算法時,它們之間有多少區別令我感到驚訝。 為什么要運行兩次imbinarize
? 敏感性關鍵字實際上是做什么的(在數學上是在背景之后)。 因為它們顯然比僅裸露的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)
顯示的圖像是:
經過一些清理:
所以總的來說不一樣,當然不如matlab好。 但是基本原理似乎相同,只是數字需要使用。
更好的方法可能是通過圖像的平均值進行閾值處理,然后將其輸出用作掩碼以對原始圖像進行自適應閾值處理。 希望那時的結果會比opencv和matlab都好。
嘗試使用ADAPTIVE_THRESH_MEAN_C進行操作,您可以獲得一些非常不錯的結果,但周圍還有更多的垃圾。 同樣,也許如果您可以將其用作遮罩來隔離文本,然后再次進行輸入,則可能會更好。 侵蝕和膨脹核的形狀也會在這里產生很大的變化。
從您的代碼中可以看到,第一步是您在Matlab代碼中使用了高帽過濾。 但是,在您的python OpenCV代碼中看不到相同的內容。 Python內置了tophat過濾器,嘗試應用該過濾器以獲得相似的結果
kernel = np.ones((5,5),np.uint8) tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
另外,嘗試使用CLAHE,它可以使您的圖像對比度更好,然后應用黑帽過濾掉小的細節。
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) cl1 = clahe.apply(img)
通過應用這些轉換,我得到了更好的結果。
經過以下嘗試,它可以識別較淺的雕刻文字樣本。 希望能幫助到你。
def show(img):
plt.imshow(img, cmap="gray")
plt.show()
# load the input image
img = cv2.imread('./imagesStackoverflow/engraved_text2.jpg',0);
show(img)
# apply CLAHE to adjust the contrast
clahe = cv2.createCLAHE(clipLimit=5.1, tileGridSize=(5,3))
cl1 = clahe.apply(img)
img = cl1.copy()
show(img)
img = cv2.GaussianBlur(img,(3,3), 1)
ret, mask = cv2.threshold(img, 125, 150, cv2.THRESH_BINARY) # turn 125, 150 for the best OCR results
kernel = np.ones((5,3),np.uint8)
mask = cv2.erode(mask,kernel,iterations = 1)
show(mask)
# I used a version of OpenCV with Tesseract, you may use your pytesseract and set the modes as:
# Page Segmentation mode (PSmode) = 11 (defualt = 3)
# OCR Enginer Mode (OEM) = 3 (defualt = 3)
tesser = cv2.text.OCRTesseract_create('C:/Program Files/Tesseract 4.0.0/tessdata/','eng','0123456789',11,3)
retval = tesser.run(mask, 0) # return string type
print 'OCR:' + retval
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.