引言
在智能交通、地圖定位等應用場景中,經常會遇到需要從圖像中提取經緯度信息的需求。本篇文章將介紹如何利用 Python 的 pytesseract 庫結合 PIL 對圖像進行預處理,通過固定區域裁剪,來有效地識別出圖像上顯示的經緯度信息。
1. OCR 與 pytesseract 簡介
OCR(Optical Character Recognition,光學字符識別)技術能夠將圖片中的文字信息轉換成可編輯的文本。Tesseract 是一款開源的 OCR 引擎,功能強大且準確率較高;而 pytesseract 則是其 Python 封裝,可以方便地在 Python 項目中調用 Tesseract 進行識別。
在我們的示例中,我們主要針對圖像上固定位置的經緯度區域進行處理與識別。由于經緯度中只包含數字、小數點、°、N、S、E、W 等字符,我們可以通過設置 白名單 限制識別字符,從而提高識別準確率
2.示例代碼
下面給出完整示例代碼,并附帶詳細的注釋說明每一步的實現邏輯:
import time
import pytesseract
from PIL import Image, ImageFilter, ImageEnhanceclass OCRReader:def __init__(self, center_x, center_y, width, height, sharpness=2.0, contrast=2.0, blur_radius=1):"""初始化 OCRReader 類,使用中心點和寬高設置裁剪區域的參數,并配置圖像預處理的超參數。參數:center_x (int): 經度/緯度信息區域中心點的 x 坐標(從左向右)center_y (int): 經度/緯度信息區域中心點的 y 坐標(從上向下)width (int): 裁剪區域的寬度height (int): 裁剪區域的高度sharpness (float): 銳化處理的增強系數,數字越大效果越明顯contrast (float): 對比度增強系數,數字越大表示對比度越明顯blur_radius (float): 高斯模糊的半徑,主要用于圖像降噪"""self.center_x = center_xself.center_y = center_yself.width = widthself.height = heightself.sharpness = sharpnessself.contrast = contrastself.blur_radius = blur_radius# 對于經緯度,白名單中僅包含數字、°、小數點以及方向字符self.whitelist = "0123456789°.NSEW"def preprocess_image(self, img):"""對裁剪后的圖像進行預處理:包括圖像的銳化、對比度增強以及高斯模糊降噪。參數:img (Image): PIL 圖像對象返回:Image: 預處理后的圖像對象"""# 銳化處理,增強圖像細節sharpener = ImageEnhance.Sharpness(img)img = sharpener.enhance(self.sharpness)# 增強對比度,使文字更明顯enhancer = ImageEnhance.Contrast(img)img = enhancer.enhance(self.contrast)# 應用高斯模糊降噪if self.blur_radius > 0:img = img.filter(ImageFilter.GaussianBlur(self.blur_radius))return imgdef read_coordinates(self, image_path):"""從給定圖像文件中提取經緯度信息。參數:image_path (str): 圖像文件的路徑返回:str: OCR 識別出的文本"""# 加載圖像img = Image.open(image_path)# 如果圖像帶有透明度,則將其轉換為 RGB 模式(填充背景為白色)if img.mode == 'RGBA':background = Image.new('RGB', img.size, (255, 255, 255))background.paste(img, mask=img.split()[3])img = backgroundelif img.mode == 'LA':background = Image.new('L', img.size, 255)background.paste(img, mask=img.split()[1])img = background.convert('RGB')# 根據中心點坐標和寬高,計算出裁剪區域的左上角和右下角坐標left = self.center_x - self.width // 2top = self.center_y - self.height // 2right = self.center_x + self.width // 2bottom = self.center_y + self.height // 2# 裁剪圖像得到經緯度顯示區域cropped_img = img.crop((left, top, right, bottom))cropped_img.save('sub_img.jpg') # 保存裁剪后的圖像,便于調試# 對裁剪后的圖像進行預處理processed_img = self.preprocess_image(cropped_img)processed_img.save('processed_sub_img.jpg') # 保存預處理后的圖像,便于調試# 配置 Tesseract 的識別參數:# --psm 6 表示將圖像看作單一文本塊# tessedit_char_whitelist 限定識別的字符集custom_config = f'--psm 6 -c tessedit_char_whitelist={self.whitelist}'result = pytesseract.image_to_string(processed_img, config=custom_config, timeout=1)return result# 示例使用
if __name__ == '__main__':ocr_reader = OCRReader(center_x=1440, center_y=802, width=204, height=20)t1 = time.time()result = ocr_reader.read_coordinates('./ocr_test.png')print("\n識別結果:", result)print(f"Time: {time.time() - t1}")
2.1 類的初始化與參數設定
- center_x 與 center_y:代表圖像中經緯度展示區域的中心坐標。
- width 與 height:定義裁剪區域的尺寸。
- sharpness、contrast 和 blur_radius:預處理步驟中用于改善圖像質量的參數。
- whitelist:指定 OCR 識別時只允許出現的字符,本例中僅包含經緯度所必需的字符。
2.2 圖像預處理
預處理步驟主要有三個:
- 銳化:通過 ImageEnhance.Sharpness 增加圖像的細節,幫助提高文字的邊緣清晰度。
- 對比度增強:利用 ImageEnhance.Contrast 調整圖像的對比度,使目標文字更醒目。
- 高斯模糊:適當的模糊可以起到降噪的作用,有利于提高 OCR 的識別率。
2.3 裁剪與 OCR 識別
- 裁剪區域計算:通過中心點和尺寸參數計算出目標區域的四個邊界的坐標,然后使用 crop 方法裁剪圖像。
- 透明度處理:有的圖像可能帶有透明通道(如 PNG 圖片),通過轉換為 RGB 模式確保 OCR 引擎能夠正確處理。
- OCR 參數配置:設置 --psm 6 以適應單一文本塊的場景,并通過白名單限制識別字符范圍,進一步提高識別準確性。
- 超時設置:timeout=1 參數確保在識別超時時不會阻塞程序。
3. 總結與擴展
通過本文示例,我們展示了如何利用 pytesseract 進行專門的區域 OCR 識別,并結合圖像預處理技術提升識別率。在實際項目中,你可以根據圖像質量和識別場景進一步調整預處理參數,比如增加二值化處理、去背景等操作。
此外,若圖像中包含不同區域的文本信息,可擴展代碼實現批量處理和區域定位,從而用于更大規模的自動化識別任務。