基于Python+OpenCV實(shí)現(xiàn)文檔掃描與OCR識(shí)別系統(tǒng)
一、項(xiàng)目簡介
今天分享一個(gè)基于 Python + OpenCV 的文檔掃描與OCR識(shí)別系統(tǒng)。這個(gè)項(xiàng)目可以自動(dòng)檢測文檔邊緣、進(jìn)行透視變換校正,并使用 Tesseract OCR 提取文檔中的文字內(nèi)容。
項(xiàng)目效果:
- 輸入:一張傾斜的文檔照片
- 輸出:校正后的正面文檔視圖 + 識(shí)別出的文字內(nèi)容
二、項(xiàng)目演示
2.1 掃描流程
- 原始圖像 → 讀取文檔照片
- 邊緣檢測 → 識(shí)別文檔輪廓
- 透視變換 → 校正為正面視圖
- 二值化處理 → 便于OCR識(shí)別
2.2 OCR識(shí)別流程
- 讀取掃描圖像 → 讀取處理后的文檔圖像
- 圖像預(yù)處理 → 二值化或中值模糊
- 文字識(shí)別 → 使用Tesseract提取文字
- 輸出結(jié)果 → 打印識(shí)別的文字內(nèi)容
三、技術(shù)棧
| 技術(shù) | 用途 |
|---|---|
| Python | 編程語言 |
| OpenCV | 圖像處理核心庫 |
| NumPy | 數(shù)值計(jì)算 |
| Tesseract OCR | 文字識(shí)別引擎 |
| pytesseract | Tesseract Python封裝 |
| Pillow | 圖像讀取 |
四、項(xiàng)目結(jié)構(gòu)
Scan/
├── scan.py # 文檔掃描核心模塊
├── test.py # OCR文字識(shí)別模塊
├── scan.jpg # 默認(rèn)輸入/輸出圖像
├── images/ # 示例圖像目錄
│ ├── page.jpg # 示例文檔圖像
│ └── receipt.jpg # 示例收據(jù)圖像
└── Tesseract-OCR/ # Tesseract OCR引擎(內(nèi)置)
五、核心代碼詳解
5.1 文檔掃描模塊 (scan.py)
5.1.1 角點(diǎn)排序函數(shù)
def order_points(pts):
# 初始化4個(gè)坐標(biāo)點(diǎn)
rect = np.zeros((4, 2), dtype = "float32")
# 按順序找到對應(yīng)坐標(biāo):左上、右上、右下、左下
s = pts.sum(axis = 1)
rect[0] = pts[np.argmin(s)] # 左上:x+y最小
rect[2] = pts[np.argmax(s)] # 右下:x+y最大
diff = np.diff(pts, axis = 1)
rect[1] = pts[np.argmin(diff)] # 右上:x-y最小
rect[3] = pts[np.argmax(diff)] # 左下:x-y最大
return rect原理:通過計(jì)算坐標(biāo)點(diǎn)的和與差來確定四個(gè)角點(diǎn)的位置,確保順序正確。
5.1.2 透視變換函數(shù)
def four_point_transform(image, pts):
rect = order_points(pts)
(tl, tr, br, bl) = rect
# 計(jì)算目標(biāo)寬度和高度
widthA = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
widthB = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
maxWidth = max(int(widthA), int(widthB))
heightA = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
heightB = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
maxHeight = max(int(heightA), int(heightB))
# 變換后對應(yīng)坐標(biāo)位置
dst = np.array([
[0, 0],
[maxWidth - 1, 0],
[maxWidth - 1, maxHeight - 1],
[0, maxHeight - 1]], dtype = "float32")
# 計(jì)算變換矩陣
M = cv2.getPerspectiveTransform(rect, dst)
warped = cv2.warpPerspective(image, M, (maxWidth, maxHeight))
return warped原理:根據(jù)原始四個(gè)角點(diǎn)和目標(biāo)矩形,計(jì)算透視變換矩陣,將傾斜的文檔校正為正面視圖。
5.1.3 主流程
# 1. 讀取圖像并縮放
image = cv2.imread(args["image"])
ratio = image.shape[0] / 500.0
orig = image.copy()
image = resize(orig, height = 500)
# 2. 邊緣檢測
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 75, 200)
# 3. 輪廓檢測
cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[0]
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:5]
# 4. 找到四邊形輪廓
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
if len(approx) == 4:
screenCnt = approx
break
# 5. 透視變換和二值化
warped = four_point_transform(orig, screenCnt.reshape(4, 2) * ratio)
warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
ref = cv2.threshold(warped, 100, 255, cv2.THRESH_BINARY)[1]
cv2.imwrite('scan.jpg', ref)步驟說明:
- 讀取圖像并按比例縮放
- 灰度化 → 高斯模糊 → Canny邊緣檢測
- 查找輪廓并按面積排序
- 通過輪廓逼近找到四邊形(文檔邊緣)
- 進(jìn)行透視變換和二值化處理
5.2 OCR識(shí)別模塊 (test.py)
from PIL import Image
import pytesseract
import cv2
import os
preprocess = 'blur' # thresh
image = cv2.imread('scan.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 預(yù)處理
if preprocess == "thresh":
gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
elif preprocess == "blur":
gray = cv2.medianBlur(gray, 3)
# 調(diào)用Tesseract OCR
filename = "{}.png".format(os.getpid())
cv2.imwrite(filename, gray)
pytesseract.pytesseract.tesseract_cmd = r'./Tesseract-OCR/tesseract.exe'
text = pytesseract.image_to_string(Image.open(filename))
print(text)
os.remove(filename)預(yù)處理方式:
thresh:二值化處理,適用于對比度較高的圖像blur:中值模糊處理,適用于有噪點(diǎn)的圖像
六、安裝與運(yùn)行
6.1 安裝依賴
pip install numpy opencv-python pytesseract pillow
6.2 運(yùn)行文檔掃描
# 使用默認(rèn)圖像 python scan.py ? # 指定輸入圖像 python scan.py -i images/page.jpg
6.3 運(yùn)行OCR識(shí)別
python test.py
七、使用技巧
7.1 圖像采集建議
- 光線充足:避免陰影和反光
- 對比度明顯:文檔與背景顏色差異大
- 邊緣清晰:文檔邊界完整可見
- 適度距離:不要太近或太遠(yuǎn)
7.2 參數(shù)調(diào)整
- Canny邊緣檢測閾值:
cv2.Canny(gray, 75, 200),根據(jù)圖像調(diào)整 - 輪廓逼近精度:
0.02 * peri,值越小輪廓越接近原始 - 二值化閾值:
cv2.threshold(warped, 100, 255, ...),根據(jù)圖像亮度調(diào)整
八、常見問題
Q1: OCR識(shí)別率低怎么辦?
A:嘗試以下方法:
- 確保圖像清晰,對比度高
- 調(diào)整預(yù)處理方式(
thresh或blur) - 檢查圖像是否傾斜或模糊
- 增加訓(xùn)練數(shù)據(jù)(添加中文訓(xùn)練數(shù)據(jù)支持中文識(shí)別)
Q2: 輪廓檢測不到文檔邊緣?
A:可能原因:
- 文檔與背景對比度不足
- 圖像質(zhì)量太差
- 調(diào)整Canny邊緣檢測閾值
- 嘗試調(diào)整輪廓逼近參數(shù)
Q3: 如何支持中文識(shí)別?
A:下載中文訓(xùn)練數(shù)據(jù) chi_sim.traineddata,放入 Tesseract-OCR/tessdata/ 目錄,然后修改代碼:
text = pytesseract.image_to_string(Image.open(filename), lang='chi_sim')
九、項(xiàng)目擴(kuò)展
批量處理:支持批量掃描多個(gè)文檔
圖形界面:添加PyQt或Tkinter界面
實(shí)時(shí)掃描:使用攝像頭實(shí)時(shí)掃描
多語言支持:添加多種語言的OCR訓(xùn)練數(shù)據(jù)
文檔分類:根據(jù)內(nèi)容自動(dòng)分類文檔
十、總結(jié)
本文介紹了一個(gè)基于 Python + OpenCV 的文檔掃描與OCR識(shí)別系統(tǒng),通過邊緣檢測、輪廓提取、透視變換和OCR識(shí)別等技術(shù),實(shí)現(xiàn)了從文檔照片到文字提取的完整流程。
核心知識(shí)點(diǎn):
- 圖像預(yù)處理(灰度化、高斯模糊、邊緣檢測)
- 輪廓檢測與篩選
- 透視變換校正
- Tesseract OCR文字識(shí)別
希望這個(gè)項(xiàng)目對大家有所幫助,如果有任何問題或建議,歡迎在評論區(qū)留言交流!
- Python Opencv實(shí)戰(zhàn)之文字檢測OCR
- 使用Python+OpenCV進(jìn)行卡類型及16位卡號(hào)數(shù)字的OCR功能
- Python實(shí)現(xiàn)圖片OCR文字識(shí)別的兩種方案及實(shí)戰(zhàn)對比
- Python使用Pillow + OCR實(shí)現(xiàn)圖片驗(yàn)證碼識(shí)別功能
- 身份證OCR識(shí)別API接入實(shí)例詳解(Python?/?Java?示例)
- 使用Python接入OCR文字識(shí)別API的全教程
- Python調(diào)用OCR API的避坑指南
- 從入門到驗(yàn)證碼識(shí)別詳解Python OCR技術(shù)實(shí)戰(zhàn)指南
相關(guān)文章
Python手拉手教你爬取貝殼房源數(shù)據(jù)的實(shí)戰(zhàn)教程
隨著人工智能的不斷發(fā)展,機(jī)器學(xué)習(xí)這門技術(shù)也越來越重要,很多人都開啟了學(xué)習(xí)機(jī)器學(xué)習(xí),本文就介紹了機(jī)器學(xué)習(xí)的基礎(chǔ)內(nèi)容,了解python爬蟲,本文給大家分享Python爬取貝殼房源數(shù)據(jù)的實(shí)戰(zhàn)教程,感興趣的朋友一起學(xué)習(xí)吧2021-05-05
分布式全文檢索引擎ElasticSearch原理及使用實(shí)例
這篇文章主要介紹了分布式全文檢索引擎ElasticSearch原理及使用實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11
python出現(xiàn)RuntimeError錯(cuò)誤問題及解決
這篇文章主要介紹了python出現(xiàn)RuntimeError錯(cuò)誤問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
anaconda?部署Jupyter?Notebook服務(wù)器過程詳解
這篇文章主要為大家介紹了anaconda?部署Jupyter?Notebook服務(wù)器過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09

