SkillAgentSearch skills...

NomNaOCR

Leverage Deep Learning to digitize old Vietnamese handwritten for historical document archiving (Made with national pride in every single line of code): https://www.kaggle.com/datasets/quandang/nomnaocr

Install / Use

/learn @ds4v/NomNaOCR

README

English | Tiếng Việt

Số hóa tài liệu lịch sử Việt Nam với Deep Learning

https://user-images.githubusercontent.com/50880271/195821293-367876c1-818d-40e9-b4b5-381d2fc831c3.mp4

I. Tổng quan

1. Giới thiệu

Tiếng Việt diệu kì với ngữ âm cực kỳ phong phú cùng hệ thống chữ viết giàu mạnh nhất vùng Đông Á đã trải qua hành trình từ chữ Nho, chữ Hán cho đến chữ Nôm và cuối cùng là chữ Quốc Ngữ. Đi cùng với mỗi loại chữ ấy là những trang sử vẻ vang của dân tộc.

Sau khi kết thúc Nghìn năm Bắc thuộc, ông cha ta với ý thức tự chủ ngôn ngữ, đã sáng tạo ra chữ Nôm dựa trên cơ sở chữ Hán được đọc theo âm Hán-Việt. Và song song với chữ Hán, đây cũng là công cụ được dùng để ghi lại phần lớn lịch sử văn hoá của dân tộc trong khoảng 10 thế kỷ. Tuy nhiên, di sản này hiện tại có nguy cơ tiêu vong.

<p align="center"><i>"Ngày nay, trên thế giới chưa có đến 100 người đọc được chữ Nôm. Một phần to tát<br/>của lịch sử Việt Nam như thế nằm ngoài tầm tay của 80 triệu người nói tiếng Việt."</i></p> <p align="right">(Hội Bảo tồn di sản chữ Nôm Việt Nam – <a href="http://www.nomfoundation.org">VNPF</a>)</p>

Để sử dụng nguồn tri thức khổng lồ này, chúng cần phải được số hóa và dịch sang Quốc Ngữ hiện đại. Do việc dịch thuật khó khăn và tốn nhiều thời gian cùng số lượng chuyên gia hạn chế nên các nổ lực này không thể thực hiện trong thời gian ngắn.

👉 Để có thể tăng tốc quá trình số hóa này, các kỹ thuật về OCR chính là chìa khóa giúp mọi công trình chính trong Hán-Nôm thành sẵn có trực tuyến.

2. Các công việc đã thực hiện

Mình cùng người đồng đội Nguyễn Đức Duy Anh đã thực hiện đề tài này trong gần 8 tháng dưới sự chỉ dẫn tận tình của TS. Đỗ Trọng Hợp (Khoa KH&KTTT - VNUHCM UIT) và đã thu được một số thành quả nhất định:

  • Xây dựng thành công bộ dữ liệu NomNaOCR:

    • Giải quyết 2 bài toán Text DetectionText Recognition cho các tài liệu lịch sử viết bằng Hán-Nôm.
    • Có kích thước lớn nhất Việt Nam hiện tại với tổng cộng 2953 Pages38318 Patches.
  • Xây dựng thành công Pipeline cho các tác vụ OCR trên văn bản Hán-Nôm bằng phương pháp Deep Learning.

  • Cài đặt và thử nghiệm các mô hình trên mức chuỗi (Sequence level). Điều này chẳng những giúp tiết kiệm được chi phí gán nhãn mà còn giúp giữ lại được ngữ nghĩa trong câu thay vì chỉ thực hiện cho từng ký tự riêng lẻ như đa phần các công trình trước. Các bạn có thể xem qua các project open-source này nếu cần triển khai theo mức kí tự (Character level):

    • https://github.com/trhgquan/OCR_chu_nom
    • https://www.kaggle.com/competitions/kuzushiji-recognition

👉 Mọi người có thể xem thêm bài viết của mình về OCR cũng như sơ lược các mô hình sử dụng trong project này hoặc có thể xem chi tiết hơn tại 2 file thesis_vi.pdfslide_vi.pptx.

II. Bộ dữ liệu NomNaOCR

  • Dataset: https://www.kaggle.com/datasets/quandang/nomnaocr
  • Paper: https://ieeexplore.ieee.org/document/10013842

Lưu ý: Các bạn nên sử dụng font NomNaTong để có thể đọc các nội dung Hán-Nôm 1 cách tốt nhất.

1. Quy trình thu thập dữ liệu

VNPF đã số hóa cho rất nhiều tác phẩm Hán-Nôm nổi tiếng có giá trị lịch sử cao. Để có thể sử dụng được khối tài nguyên vô giá trên, mình sử dụng Automa để tạo một luồng thu thập tự động gồm:

  • Các hình ảnh lẫn URL của chúng.
  • Các nội dung được phiên dịch gồm các ký tự Hán-Nôm kỹ thuật số và phần dịch Quốc Ngữ của chúng (nếu có).

https://user-images.githubusercontent.com/50880271/195821433-59c35cec-af04-4706-9aa9-a71b000e39a4.mp4

a. Hướng dẫn thu thập

Khâu này mình lười viết code nên có làm hơi thủ công tí 😅.

  • Import file workflow.json vào Automa.
  • Chọn thẻ New tab và chọn Edit => nhập URL của các tác phẩm Hán-Nôm cần thu thập.
  • Edit trường To number của thẻ Loop Data để chỉ định số trang cần thu thập.
  • Edit CSS Selector của các thẻ:
    • Element exists: kiểm tra trang rỗng.
    • Blocks group: lấy URL hình ảnh và nội dung của trang hiện tại.
  • Bấm Execute để bắt đầu thu thập.
  • Chạy file automa2txt.py để parse file automa.json vừa có được sau khi thu thập thành 3 file:
    • url.txt: chứa các URL hình ảnh của tác phẩm.
    • nom.txt: chứa các text chữ Hán-Nôm.
    • modern.txt: chứa các phiên âm tương ứng với file nom.txt.

[*] Còn về phần download hình ảnh, mình chỉ đơn giản sử dụng tính năng Tải xuống hàng loạt của Internet Download Manager. Xem thêm video hướng dẫn tại đây.

b. Các tác phẩm đã thu thập

| Tên tác phẩm | Số lượng page | | ------------------------------- |:------------------------:| | Lục Vân Tiên | 104 | | Truyện Kiều bản 1866 | 100 | | Truyện Kiều bản 1871 | 136 | | Truyện Kiều bản 1872 | 163 | | ĐVSKTT Quyển Thủ | 107 | | ĐVSKTT Ngoại kỷ toàn thư | 178 | | ĐVSKTT Bản kỷ toàn thư | 933 | | ĐVSKTT Bản kỷ thực lục | 787 | | ĐVSKTT Bản kỷ tục biên | 448 | | Tổng cộng | 2956 |

[*] ĐVSKTT: Đại Việt Sử Ký Toàn Thư

2. Quy trình gán nhãn

Nhóm mình sử dụng PPOCRLabel thuộc hệ sinh thái của PaddleOCR để gán tự động các bounding box. Tool này mặc định sử dụng DBNet để phát hiện văn bản, đây cũng là mô hình nhóm mình sẽ thử nghiệm cho bài toán Text Detection. Ở đây, mình có phân tool này ra thành 2 bản:

  • annotators.zip: dành cho người gán nhãn, mình đã bỏ đi các chức năng không cần thiết như Auto annotation, ... để tránh việc nhấn tùm lum có thể gây sai sót khi gán nhãn cũng như để việc cài đặt dễ dàng và ít lỗi hơn.
  • composer.zip: dành cho người xây dựng guideline (Mình sẽ gọi là Composer) dùng để chạy Auto annotation, khá đầy đủ chức năng so với bản gốc. Mình có bỏ đi thao tác Auto recognition khi chạy Auto annotation và sử dụng nhãn cho text là TEMPORARY. Ngoài ra, mình cũng đã thực hiện xoay ảnh lại để khớp với đầu vào các mô hình Recognition khi chạy chức năng Export Recognition Result.

👉 Các Annotator sẽ thay thế nhãn TEMPORARY theo hướng dẫn trong các guideline dành cho thơ và cho văn xuôi. Cuối cùng là thực hiện map nhãn thật được thu thập từ VNPF.

Tuy nhiên, với các ảnh trong NomNaOCR thì PPOCRLabel đa phần sẽ phát hiện các vùng ảnh chứa văn bản theo chiều ngang nên mình đã thực hiện quay ảnh theo các góc 90 độ để phù hợp với bài toán:

  • Tùy vào từng tác phẩm mà Composer sẽ chọn xoay +90 hay -90 độ hoặc cả 2 hướng.
  • Chạy file rotated_generator.py để sinh các ảnh tương ứng.
  • Sau đó đưa ảnh vào PPOCRLabel để dự đoán các bounding box.
  • Khi dự đoán xong, chạy file unrotated_convertor.py để xoay dọc các bounding box lại.

Sau khâu triển khai thực tế, bộ dữ liệu NomNaOCR được xử lý và thu được 2953 Pages (đã bỏ đi 1 Page scan lỗi và 2 Page trống). Bằng cách gán nhãn bán thủ công, nhóm mình đã thu được thêm 38318 Patches. Tiếp theo, nhóm mình sử dụng công thức từ bộ dữ liệu IHR-NomDB để có được phân phối tương đồng giữa tập TrainValidate để chia dữ liệu Recognition 1 cách hiệu quả nhất. Phần Synthetic Nom String thuộc bộ dữ liệu này cũng được dùng để thực hiện Pretraining cho các mô hình Recognition.

| Tập dữ liệu | Số điểm dữ liệu | Tỉ lệ ký tự giao nhau | |:-------------------:|:-------------------:|:-------------------------:| | Tập Train | 30654 | 93.24% | | Tập Validate | 7664 | 64.41% |

III. Triển khai mô hình

1. Quy trình huấn luyện

  • Với Detection, mình sử dụng PaddleOCR để huấn luyện với các file config tương ứng trong folder Text detection.
  • Với Recognition, trong quá trình PreTraining trên bộ Synthetic Nom String của IHR-NomDB, mình nhận thấy khi thực hiện Skip Connection (SC) cho feature map với 1 lớp X có cùng shape và nằm xa nó nhất sẽ cải thiện đáng kể hiệu suất mô hình. Vì vậy, mì

Related Skills

View on GitHub
GitHub Stars138
CategoryEducation
Updated3d ago
Forks28

Languages

Jupyter Notebook

Security Score

100/100

Audited on Apr 1, 2026

No findings