通過OCR識別文字方向判斷圖片旋轉角度,然后糾正。
一、 安裝OCR文字識別工具tesseract
從官網下載源碼安裝(因為pip install pytesseract報錯pytesseract.pytesseract.TesseractNotFoundError: tesseract is not installed or it's not in your PATH)
下載對應系統(tǒng)版本的tesseract
官網地址:tesseract-ocr/tessdoc: Tesseract documentation


下載完后安裝Tesseract-OCR
安裝時將最后一個額外語言包的選項(好像是Additional language packs)展開,一定要勾選所需識別的語言,如中文

記住安裝的路徑(如C:\Program Files\Tesseract-OCR),待會要設置系統(tǒng)環(huán)境
二、Tesseract-OCR設置系統(tǒng)環(huán)境
右鍵我的電腦屬性--高級系統(tǒng)設置下
在系統(tǒng)屬性框點擊【高級】欄下的【環(huán)境變量】或搜索環(huán)境變量
1、在系統(tǒng)變量下的Path下點擊【新建】添加Tesseract-OCR的安裝地址,如C:\Program Files\Tesseract-OCR

2、增加一個TESSDATA_PREFIX變量名,變量值還是我的安裝路徑C:\Program Files\Tesseract-OCR\tessdata這是將語言字庫文件夾添加到變量中;

3、驗證,ctrl+r輸入cmd打開終端,輸入:tesseract -v,可以看到版本信息

4、如果運行時還報錯(可選,先不管)
ctrl點擊報錯的pytesseract.py文件跳轉到在pytesseract庫下的pytesseract.py文件中找到tesseract_cmd = 'tesseract',修改成tesseract_cmd =r'C:\Program Files\Tesseract-OCR\tesseract.exe',(安裝目錄下的tesseract.exe),也可以直接去到python安裝目錄下打開修改,如D:\python3.6\python\Lib\site-packages\pytesseract。
三、代碼
1、
輸入目錄結構如下:
input_images /
├── folder1 /
│ ├── img1.jpg
│ ├── img2.jpg
├── folder2 /
│ ├── subfolder /
│ │ ├── img3.jpg
│ ├── img4.jpg
運行后生成的輸出目錄:
output_pdfs /
├── folder1.pdf
├── folder2 /
│ ├── subfolder.pdf
├── folder2.pdf
2、查看CPU核心個數
1.右鍵我的電腦點管理--點進設備管理器--點進處理器即可

如圖核心個數為12核,代碼下的workers改成12,12個線程多線程同時處理加快速度。
如果分辨率過小導致旋轉方向判斷有誤,加大圖像最大分辨率max_size,但會變慢。
import os
from PIL import Image
import pytesseract
import tempfile
from concurrent.futures import ThreadPoolExecutor
def resize_image(image_path, max_size=(2048, 2048)):
"""調整圖像大小以加快處理速度。"""
image = Image.open(image_path)
image.thumbnail(max_size, Image.ANTIALIAS) # 保持長寬比調整大小
return image
def detect_orientation(temp_image_path):
"""檢測圖片文字的方向并返回所需的旋轉角度。"""
try:
osd = pytesseract.image_to_osd(temp_image_path)
rotation_angle = int(osd.split("Rotate:")[1].split("\n")[0].strip())
except Exception:
return 0 # 如果檢測失敗,默認不旋轉
return rotation_angle
def process_images_to_pdf(images, pdf_output_path):
"""處理圖片列表并合成為PDF。"""
processed_images = []
for image_path in images:
try:
image = Image.open(image_path)
resized_image = resize_image(image_path)
# 保存調整大小的圖像到臨時文件以檢測方向
with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as temp_file:
temp_path = temp_file.name
resized_image.save(temp_path)
# 檢測方向
rotation_angle = detect_orientation(temp_path)
os.remove(temp_path) # 刪除臨時文件
# 根據方向調整原始圖片
if rotation_angle != 0:
corrected_image = image.rotate(-rotation_angle, expand=True).convert("RGB")
else:
corrected_image = image.convert("RGB")
processed_images.append(corrected_image)
except Exception as e:
print(f"Error processing {image_path}: {e}")
# 合成PDF
if processed_images:
first_image, *rest_images = processed_images
first_image.save(pdf_output_path, save_all=True, append_images=rest_images, optimize=False)
print(f"PDF created: {pdf_output_path}")
else:
print(f"No valid images found for PDF creation: {pdf_output_path}")
def process_folder_recursive(input_folder, output_folder, max_size=(2048, 2048), workers=4):
"""
遞歸處理主文件夾中的所有子文件夾,每個子文件夾生成一個PDF文件。
使用多線程提高處理速度。
"""
if not os.path.exists(output_folder):
os.makedirs(output_folder)
tasks = []
# 使用多線程處理每個子文件夾
with ThreadPoolExecutor(max_workers=workers) as executor:
for root, dirs, files in os.walk(input_folder):
image_files = [
os.path.join(root, file_name)
for file_name in files
if file_name.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tiff'))
]
if image_files:
relative_path = os.path.relpath(root, input_folder)
pdf_output_path = os.path.join(output_folder, f"{relative_path}.pdf")
# 確保輸出文件夾存在
os.makedirs(os.path.dirname(pdf_output_path), exist_ok=True)
# 將任務提交到線程池
tasks.append(executor.submit(process_images_to_pdf, image_files, pdf_output_path))
# 等待所有任務完成
for task in tasks:
task.result()
# 示例調用
if __name__ == "__main__":
# 目錄結構如下:
# input_images /
# ├── folder1 /
# │ ├── img1.jpg
# │ ├── img2.jpg
# ├── folder2 /
# │ ├── subfolder /
# │ │ ├── img3.jpg
# │ ├── img4.jpg
# 運行后生成的輸出目錄:
# output_pdfs /
# ├── folder1.pdf
# ├── folder2 /
# │ ├── subfolder.pdf
# ├── folder2.pdf
input_folder = r"C:\Users\Administrator\Desktop\example" # 輸入文件夾路徑
output_folder = r"C:\Users\Administrator\Desktop\example\outputPDF" # 輸出PDF路徑
# 如果分辨率過小導致旋轉方向判斷有誤,加大圖像最大分辨率max_size,但會變慢。workers設置為CPU最大核心數以提高處理速度
process_folder_recursive(input_folder, output_folder, max_size=(2048, 2048), workers=12)
其它報錯,已修改:
pytesseract image_to_osd Invalid resolution 0 dpi. Using 70 instead. Too few characters報錯及解決
報錯:tesseract升級的bug
解決:直接傳遞照片文件路徑如D:\1.jpg而不是cv2.imread或PIL.Image.open讀取的圖像,或者切回低版本的tesseract:5.0.0-alpha-20201224 ok。詳情可參考
參考:超詳細解決pytesseract.pytesseract.TesseractNotFoundError: tesseract is not installed or it‘s not in yo...-CSDN博客
Windows pytesseract image_to_osd Invalid resolution 0 dpi. Using 70 instead. Too few characters報錯及解決_warning: invalid resolution 0 dpi. using 70 instea-CSDN博客
https://github.com/madmaze/pytesseract/issues/368