將文件夾中多個子文件夾中的帶旋轉的圖片糾正并合成PDF

通過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

image.png

image.png

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


image.png

記住安裝的路徑(如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

image.png

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


image.png

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


image.png

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.右鍵我的電腦點管理--點進設備管理器--點進處理器即可


image

如圖核心個數為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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容