使用 OpenCV 和 Tesseract 對(duì)圖像中的感興趣區(qū)域 (ROI) 進(jìn)行 OCR
點(diǎn)擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時(shí)間送達(dá)

在這篇文章中,我們將使用 OpenCV 在圖像的選定區(qū)域上應(yīng)用 OCR。在本篇文章結(jié)束時(shí),我們將能夠?qū)斎雸D像應(yīng)用自動(dòng)方向校正、選擇感興趣的區(qū)域并將OCR 應(yīng)用到所選區(qū)域。
這篇文章基于 Python 3.x,假設(shè)我們已經(jīng)安裝了 Pytesseract 和 OpenCV。Pytesseract 是一個(gè) Python 包裝庫,它使用 Tesseract 引擎進(jìn)行 OCR。因此,如果我們沒有安裝 tesseract 引擎,請(qǐng)從https://github.com/UB-Mannheim/tesseract/wiki下載并安裝它,并正確設(shè)置 TESSDATA_PREFIX 環(huán)境變量和路徑變量。
深入到代碼中,讓我們從導(dǎo)入所需的庫開始:
# Importing necessary librariesimport numpy as npimport cv2import mathfrom scipy import ndimageimport pytesseract
現(xiàn)在,使用 opencv 的 imread() 方法將圖像文件讀入 python。
IMAGE_FILE_LOCATION = "test_image.jpg" # Photo by Amanda Jones on Unsplashinput_img = cv2.imread(IMAGE_FILE_LOCATION) # image read

在直接提取感興趣區(qū)域之前,讓我們先檢查它的方向,因?yàn)楹芏鄷r(shí)候我們一定已經(jīng)注意到文檔或圖像的方向不正確,這會(huì)導(dǎo)致 OCR?較差,所以現(xiàn)在我們將調(diào)整輸入圖像的方向以確保更好的 OCR 結(jié)果。
在這里,我們應(yīng)用兩種算法來檢測(cè)輸入圖像的方向:Canny 算法(檢測(cè)圖像中的邊緣)和 HoughLines(檢測(cè)線)。
然后我們測(cè)量線的角度,并取出角度的中值來估計(jì)方向的角度。然后以這個(gè)中間角度旋轉(zhuǎn)圖像,將其轉(zhuǎn)換為完美的方向,以便進(jìn)一步步驟。
不用擔(dān)心,OpenCV 只需幾行代碼即可為我們完成這項(xiàng)工作!
###################################################################################################### ORIENTATION CORRECTION/ADJUSTMENTdef orientation_correction(img, save_image = False):# GrayScale Conversion for the Canny Algorithmimg_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Canny Algorithm for edge detection was developed by John F. Canny not Kennedy!! :)img_edges = cv2.Canny(img_gray, 100, 100, apertureSize=3)# Using Houghlines to detect lineslines = cv2.HoughLinesP(img_edges, 1, math.pi / 180.0, 100, minLineLength=100, maxLineGap=5)# Finding angle of lines in polar coordinatesangles = []for x1, y1, x2, y2 in lines[0]:angle = math.degrees(math.atan2(y2 - y1, x2 - x1))angles.append(angle)# Getting the median anglemedian_angle = np.median(angles)# Rotating the image with this median angleimg_rotated = ndimage.rotate(img, median_angle)if save_image:img_rotated)return img_rotated#####################################################################################################img_rotated = orientation_correction(input_img)

下一步是從圖像中提取感興趣的區(qū)域。
因此,首先我們?yōu)槭髽?biāo)設(shè)置一個(gè)事件偵聽器,使用戶能夠選擇感興趣的區(qū)域。在這里,我們?cè)O(shè)置了兩個(gè)條件,一個(gè)是鼠標(biāo)左鍵按下,第二個(gè)是鼠標(biāo)左鍵向上。
我們存儲(chǔ)按下鼠標(biāo)左鍵時(shí)的起始坐標(biāo)和釋放鼠標(biāo)左鍵時(shí)的結(jié)束坐標(biāo),然后在按下“enter”鍵時(shí),我們提取這些起始坐標(biāo)和結(jié)束坐標(biāo)之間的區(qū)域,如果按下“c”,則清除坐標(biāo)。
###################################################################################################### REGION OF INTEREST (ROI) SELECTION# initializing the list for storing the coordinatescoordinates = []# Defining the event listener (callback function)def shape_selection(event, x, y, flags, param):# making coordinates globalglobal coordinates# Storing the (x1,y1) coordinates when left mouse button is pressedif event == cv2.EVENT_LBUTTONDOWN:coordinates = [(x, y)]# Storing the (x2,y2) coordinates when the left mouse button is released and make a rectangle on the selected regionelif event == cv2.EVENT_LBUTTONUP:coordinates.append((x, y))# Drawing a rectangle around the region of interest (roi)cv2.rectangle(image, coordinates[0], coordinates[1], (0,0,255), 2)cv2.imshow("image", image)# load the image, clone it, and setup the mouse callback functionimage = img_rotatedimage_copy = image.copy()cv2.namedWindow("image")cv2.setMouseCallback("image", shape_selection)# keep looping until the 'q' key is pressedwhile True:# display the image and wait for a keypresscv2.imshow("image", image)key = cv2.waitKey(1) & 0xFFif key==13: # If 'enter' is pressed, apply OCRbreakif key == ord("c"): # Clear the selection when 'c' is pressedimage = image_copy.copy()if len(coordinates) == 2:image_roi = image_copy[coordinates[0][1]:coordinates[1][1],coordinates[0][0]:coordinates[1][0]]cv2.imshow("Selected Region of Interest - Press any key to proceed", image_roi)cv2.waitKey(0)# closing all open windowscv2.destroyAllWindows()#####################################################################################################

感興趣區(qū)域的邊界框
現(xiàn)在,使用 pytesseract 在 ROI 上應(yīng)用光學(xué)字符識(shí)別 (OCR)。(也可以使用Google Vision或Azure Vision代替 Tesseract 引擎)。
##################################################################### OPTICAL CHARACTER RECOGNITION (OCR) ON ROItext = pytesseract.image_to_string(image_roi)print("The text in the selected region is as follows:")print(text)
輸出是:
"Isn't it a greenhouse?”計(jì)算機(jī)視覺和光學(xué)字符識(shí)別可以解決法律領(lǐng)域(將舊的法院判決數(shù)字化)、金融領(lǐng)域(從貸款協(xié)議、土地登記中提取重要信息)等領(lǐng)域的許多問題。
Github代碼鏈接:
https://github.com/ChayanBansal/roi_selection_and_ocr_with_orientation_correction
交流群
歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動(dòng)駕駛、計(jì)算攝影、檢測(cè)、分割、識(shí)別、醫(yī)學(xué)影像、GAN、算法競(jìng)賽等微信群(以后會(huì)逐漸細(xì)分),請(qǐng)掃描下面微信號(hào)加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺SLAM“。請(qǐng)按照格式備注,否則不予通過。添加成功后會(huì)根據(jù)研究方向邀請(qǐng)進(jìn)入相關(guān)微信群。請(qǐng)勿在群內(nèi)發(fā)送廣告,否則會(huì)請(qǐng)出群,謝謝理解~

