### Convert Myanmar Sentences to PNG Images Source: https://github.com/ye-kyaw-thu/myocr/blob/main/README.md This bash script, `mytext2pic.sh`, converts Myanmar sentences from an input text file into individual PNG image files. It relies on a LaTeX setup (`mytext.tex`) and requires the input file and script to be in the same directory. The script is intended for generating images for OCR training and evaluation. ```bash #!/bin/bash # make "png files" for each Myanmar sentence from the input file # written by Ye Kyaw Thu, Language Understanding Lab., Pyin Oo Lwin, Myanmar # Note: you need "mytext.tex" latex file and your file that contained Myanmar sentences # under the same folder with "mytext2pic.sh" # # Last updated: 19 June 2020 # How to run: bash ./mytext2pic.sh # e.g. bash ./mytext2pic.sh ./mytxt4png.txt # output files: line1.png, line2.png, line3.png ... # Ref: https://tex.stackexchange.com/questions/34054/tex-to-image-over-command-line/34058#34058 ``` -------------------------------- ### Load Validation Data with Pandas (Python) Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt This Python function loads the validation dataset from a specified file path into a Pandas DataFrame. It processes each line, splitting it into image path and text label, and calculates the word count for each line. The function returns a DataFrame containing image paths, text labels, and word counts, and the usage example prints the total number of samples and the average words per line. ```python import pandas as pd # Load validation dataset def load_myocr_data(file_path): data = [] with open(file_path, 'r', encoding='utf-8') as f: for line in f: parts = line.strip().split('\t') if len(parts) == 2: data.append({ 'image_path': parts[0], 'text': parts[1], 'word_count': len(parts[1].split('_')) }) return pd.DataFrame(data) # Usage valid_df = load_myocr_data('data/ver1.0/valid.txt') print(f"Validation samples: {len(valid_df)}") print(f"Average words per line: {valid_df['word_count'].mean():.2f}") # Example output: # Validation samples: 5803 # Average words per line: 8.45 ``` -------------------------------- ### Read Training Data (Python) Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt This Python code snippet demonstrates how to read the training data from a file. It parses each line to extract the image path and the corresponding text label, then splits the label into individual words. The output shows the image path, a list of words, and the reconstructed text with spaces. ```python # Reading training data with open('data/ver1.0/train.txt', 'r', encoding='utf-8') as f: for line in f: image_path, text_label = line.strip().split('\t') # image_path: Images/MasterpieceUniType_312.png # text_label: တပို့တွဲ_လ_တွင်_၂၉_ရက်_ရှိ_သည် words = text_label.split('_') print(f"Image: {image_path}") print(f"Words: {words}") print(f"Text: {text_label.replace('_', ' ')}") ``` -------------------------------- ### Create Multi-Volume 7z Archives with Bash Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt Compresses files into multi-volume 7z archives, useful for splitting large datasets. The `-v52m` flag specifies a volume size of 52MB. The command also includes timing and verification steps. ```bash # Compress images into 52MB volumes time 7z a -v52m Images.7z ./Images/ # Output details: # - Scanning: 1 folder, 25,790 files, 91,981,953 bytes (88 MiB) # - Archive size: 85,800,971 bytes (82 MiB) # - Volumes: 2 # - Compression time: ~4.25 seconds # Verify archive integrity 7z t Images.7z.001 # List archive contents without extracting 7z l Images.7z.001 | head -20 ``` -------------------------------- ### Generate Synthetic Images from Text (Bash) Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt This bash script, `mytext2pic.sh`, converts Myanmar sentences from an input file into PNG images. It utilizes `xelatex` to generate a PDF from a LaTeX template (`mytext.tex`) and then uses `ImageMagick`'s `convert` command to transform the PDF into a high-quality PNG image. The script iterates through each line of the input file, creating a sequentially named PNG file for each sentence. ```bash #!/bin/bash # mytext2pic.sh - Convert Myanmar sentences to PNG images # Requires: xelatex, ImageMagick (convert), mytext.tex LaTeX template count=1 input_file="$1" cat "$input_file" | while read -r line do # Generate PDF using XeLaTeX with Myanmar font support xelatex "\def\mytext{${line}}\input{mytext.tex}" # Convert PDF to high-quality PNG convert -density 300 mytext.pdf -quality 90 line$count.png ((count++)) done # Usage example: # bash mytext2pic.sh myanmar_sentences.txt # Output: line1.png, line2.png, line3.png, ... ``` -------------------------------- ### Convert Text Lines to Images using LaTeX and ImageMagick (Shell) Source: https://github.com/ye-kyaw-thu/myocr/blob/main/README.md This script iterates through lines of an input text file, converts each line into a PDF using xelatex with a defined LaTeX template, and then converts the PDF to a PNG image using ImageMagick. It requires xelatex, convert (ImageMagick), and a 'mytext.tex' template file. ```shell count=1; cat $1 | while read -r line do xelatex "\def\mytext{${line}}\input{mytext.tex}" convert -density 300 mytext.pdf -quality 90 line$count.png ((count++)) done ``` -------------------------------- ### Extract Multi-Volume 7z Archive Source: https://github.com/ye-kyaw-thu/myocr/blob/main/README.md This command shows how to extract a multi-volume 7z archive. By specifying the first volume file (e.g., Images.7z.001), the 7z utility automatically handles the extraction of all subsequent volumes in the sequence. ```bash 7z x Images.7z.001 ``` -------------------------------- ### Archive Myanmar OCR Images using 7z Source: https://github.com/ye-kyaw-thu/myocr/blob/main/README.md This command demonstrates how to archive a directory of Myanmar OCR images into multi-volume 7z archives. The `-v52m` option splits the archive into 52MB volumes, useful for overcoming file size limitations. The output includes the compression process details and the resulting split archive files. ```bash #!/bin/bash time 7z a -v52m Images.7z ./Images/ # Example output: # 7-Zip 23.01 (x64) : Copyright (c) 1999-2023 Igor Pavlov : 2023-06-20 # 64-bit locale=en_US.UTF-8 Threads:24 OPEN_MAX:1024 # # Scanning the drive: # 1 folder, 25790 files, 91981953 bytes (88 MiB) # # Creating archive: Images.7z # # Add new data to archive: 1 folder, 25790 files, 91981953 bytes (88 MiB) # # # Files read from disk: 25790 # Archive size: 85800971 bytes (82 MiB) # Volumes: 2 # Everything is Ok # # real 0m4.250s # user 0m8.873s # sys 0m0.260s ``` -------------------------------- ### Programmatic Random Sample Selection with Python Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt Selects random image samples per font using Python. It groups images by font name extracted from filenames and uses the `random.sample` function. The selected samples are then copied to a specified output directory. Dependencies include `random`, `shutil`, `pathlib`, and `collections.defaultdict`. ```python import random import shutil from pathlib import Path from collections import defaultdict def select_random_samples(image_dir, samples_per_font=2): """ Select random samples for each font type """ # Group images by font name font_images = defaultdict(list) for img_path in Path(image_dir).glob('*.png'): font_name = img_path.stem.rsplit('_', 1)[0] font_images[font_name].append(img_path) # Select random samples samples = {} for font, images in font_images.items(): selected = random.sample(images, min(samples_per_font, len(images))) samples[font] = selected print(f"{font}: {len(images)} images, selected {len(selected)}") return samples # Usage output_dir = Path('random_samples') output_dir.mkdir(exist_ok=True) samples = select_random_samples('Images/', samples_per_font=2) # Copy selected samples for font, image_paths in samples.items(): for img_path in image_paths: dest = output_dir / img_path.name shutil.copy(img_path, dest) print(f"Copied: {img_path.name}") print(f"\nTotal fonts: {len(samples)}") print(f"Total samples: {sum(len(imgs) for imgs in samples.values())}") ``` -------------------------------- ### Generate OCR Images with Python Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt Generates synthetic OCR images for Myanmar text using a Python script. It takes a list of texts, an output directory, and a font name to create PNG images. Dependencies include `subprocess` and `os` modules, and an external script `mytext2pic.sh`. ```python import subprocess import os def generate_ocr_images(text_list, output_dir, font_name): """ Generate synthetic OCR images for Myanmar text """ os.makedirs(output_dir, exist_ok=True) for idx, text in enumerate(text_list): output_file = f"{output_dir}/{font_name}_{idx}.png" # Create temporary text file with open('temp_text.txt', 'w', encoding='utf-8') as f: f.write(text) # Generate image using mytext2pic.sh try: subprocess.run( ['bash', 'mytext2pic.sh', 'temp_text.txt'], check=True, timeout=30 ) # Rename generated image os.rename(f'line{idx+1}.png', output_file) print(f"Generated: {output_file}") except subprocess.TimeoutExpired: print(f"Timeout generating image for text: {text[:50]}...") except Exception as e: print(f"Error: {e}") # Cleanup if os.path.exists('temp_text.txt'): os.remove('temp_text.txt') # Example usage myanmar_texts = [ "တပို့တွဲ_လ_တွင်_၂၉_ရက်_ရှိ_သည်", "အားနာ_စရာ_ကြီး_အကြာကြီး_ရှာ_နေ_ရ_တယ်" ] generate_ocr_images(myanmar_texts, 'output_images', 'MyanmarFont') ``` -------------------------------- ### Font-Based Random Sampling with Bash Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt Selects random sample image files based on their font names. This bash script iterates through PNG files, identifies fonts from filenames (e.g., 'FontName_123.png'), and copies 2 random samples per font into a 'random_samples' directory. ```bash #!/bin/bash # get_random_samples.sh - Extract random samples per font mkdir -p random_samples # Find all unique font names and select 2 random samples per font find . -maxdepth 1 -name "*.png" -type f \ | sed 's|^\./||' \ | cut -d'_' -f1 \ | sort -u \ | while read font; do echo "=== $font ===" find . -maxdepth 1 -name "${font}_*.png" -type f \ | sed 's|^\./||' \ | shuf \ | head -n 2 \ | while read file; do cp "$file" "random_samples/" echo "Copied: $file" done echo done echo "Done! Random samples are in random_samples/ folder" # Expected output: 28 images (2 per font × 14 fonts) ``` -------------------------------- ### Load Ground Truth Data (Python) Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt This Python function loads ground truth data from a file where words are separated by spaces, unlike the training/validation data which uses underscores. It parses each line to extract the image path and the space-separated text. The function returns a list of dictionaries, each containing the image path, the space-separated text, and a version of the text with spaces replaced by underscores, which is useful for evaluation and post-OCR correction models. ```python # Load ground truth with space-separated words def load_ground_truth(file_path): """ GT.shuf.txt contains space-separated words instead of underscores Useful for evaluation and post-OCR correction models """ samples = [] with open(file_path, 'r', encoding='utf-8') as f: for line in f: image_path, text = line.strip().split('\t') samples.append({ 'image': image_path, 'text': text, 'underscore_format': text.replace(' ', '_') }) return samples gt_data = load_ground_truth('data/ver1.0/GT.shuf.txt') print(f"Total ground truth samples: {len(gt_data)}") # Output: Total ground truth samples: 25790 ``` -------------------------------- ### Extract Multi-Volume 7z Archives with Bash Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt Extracts images from multi-volume 7z archives. This command automatically processes all split volumes (e.g., Images.7z.001, Images.7z.002) to reconstruct the original archive. It's useful for downloading datasets split due to file size limits. ```bash # The dataset images are compressed in multi-volume 7z format # Due to GitHub file size limits, archives are split into 52MB volumes # Extract all images from multi-volume archive 7z x Images.7z.001 # This automatically processes all volumes: # - Images.7z.001 (52MB) # - Images.7z.002 (30MB) # Total extracted: 25,790 images (88 MiB) # Verify extraction find Images/ -name "*.png" | wc -l # Expected output: 25790 ``` -------------------------------- ### N-gram Statistical Correction for Myanmar Text Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt Implements an N-gram model to correct OCR errors in Myanmar text by leveraging word and character probabilities. It builds an n-gram model from a corpus and then uses it to predict more probable character sequences. Dependencies include `collections` and `math`. ```python from collections import Counter, defaultdict import math class NgramCorrector: """ N-gram based post-OCR correction for Myanmar text """ def __init__(self, corpus_file, n=3): self.n = n self.ngrams = defaultdict(Counter) self._build_ngram_model(corpus_file) def _build_ngram_model(self, corpus_file): with open(corpus_file, 'r', encoding='utf-8') as f: for line in f: _, text = line.strip().split('\t') text = text.replace('_', ' ') # Build n-grams for i in range(len(text) - self.n + 1): context = text[i:i+self.n-1] next_char = text[i+self.n-1] self.ngrams[context][next_char] += 1 def correct(self, text, threshold=0.1): """ Correct text using n-gram probabilities """ corrected = [] text_clean = text.replace('_', ' ') for i, char in enumerate(text_clean): if i < self.n - 1: corrected.append(char) continue context = text_clean[i-self.n+1:i] if context in self.ngrams: char_probs = self.ngrams[context] total = sum(char_probs.values()) current_prob = char_probs.get(char, 0) / total best_char, best_prob = max(char_probs.items(), key=lambda x: x[1]) best_prob = best_prob / total if best_prob - current_prob > threshold: corrected.append(best_char) else: corrected.append(char) else: corrected.append(char) return ''.join(corrected) # Usage corrector = NgramCorrector('data/ver1.0/GT.shuf.txt', n=4)\nocr_output = "စိတ်မပူ_ပါ_နဲ့_ရှာ_တွေ့_အောင်_ကြိုးစား_ပါ_မယ်" corrected = corrector.correct(ocr_output) print(f"Original: {ocr_output}") print(f"Corrected: {corrected}") ``` -------------------------------- ### Data Generator for Training (Python) Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt Implements a custom data generator class `MyOCRDataGenerator` that inherits from `tf.keras.utils.Sequence`. This generator is designed for OCR tasks, compatible with CNN-BiLSTM-CTC architectures. It handles loading images and text labels from files, preprocessing images to a fixed size, and encoding text labels into character indices based on a provided or generated character set. It supports batching and is suitable for training deep learning models. ```python import numpy as np from PIL import Image import tensorflow as tf class MyOCRDataGenerator(tf.keras.utils.Sequence): """ Data generator for myOCR dataset Compatible with CNN-BiLSTM-CTC architecture """ def __init__(self, data_file, image_dir, batch_size=32, img_width=800, img_height=64, charset=None): self.batch_size = batch_size self.img_width = img_width self.img_height = img_height # Load data self.samples = [] with open(data_file, 'r', encoding='utf-8') as f: for line in f: img_path, text = line.strip().split('\t') full_path = f"{image_dir}/{img_path}" self.samples.append((full_path, text)) # Build character set if charset is None: chars = set() for _, text in self.samples: chars.update(text) self.charset = sorted(list(chars)) else: self.charset = charset self.char_to_idx = {ch: idx for idx, ch in enumerate(self.charset)} self.idx_to_char = {idx: ch for ch, idx in self.char_to_idx.items()} def __len__(self): return int(np.ceil(len(self.samples) / self.batch_size)) def __getitem__(self, idx): batch_samples = self.samples[idx * self.batch_size:(idx + 1) * self.batch_size] images = [] labels = [] for img_path, text in batch_samples: # Load and preprocess image img = Image.open(img_path).convert('L') img = img.resize((self.img_width, self.img_height)) img_array = np.array(img) / 255.0 images.append(img_array) # Encode label label = [self.char_to_idx.get(ch, 0) for ch in text] labels.append(label) return np.array(images), labels # Usage train_gen = MyOCRDataGenerator( 'data/ver1.0/train.txt', 'data/ver1.0', batch_size=32 ) print(f"Total batches: {len(train_gen)}") print(f"Character set size: {len(train_gen.charset)}") print(f"Sample characters: {train_gen.charset[:20]}") ``` -------------------------------- ### Analyze Font Distribution Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt Analyzes the distribution of fonts present in a dataset file. It reads image paths from a specified file, extracts font names from the paths, counts their occurrences, and prints a formatted report of font counts and percentages. Dependencies include `collections.Counter` and `matplotlib.pyplot`. ```python from collections import Counter import matplotlib.pyplot as plt def analyze_font_distribution(data_file): """ Analyze the distribution of fonts in the dataset """ font_counts = Counter() with open(data_file, 'r', encoding='utf-8') as f: for line in f: image_path = line.split('\t')[0] # Extract font name from path: Images/FontName_number.png font_name = image_path.split('/')[1].split('_')[0] font_counts[font_name] += 1 # Display statistics print(f"Total samples: {sum(font_counts.values())}") print(f"Number of fonts: {len(font_counts)}") print(f"\nFont distribution:") for font, count in font_counts.most_common(): percentage = (count / sum(font_counts.values())) * 100 print(f"{font:30s}: {count:5d} ({percentage:5.2f}%)") return font_counts # Analyze training set train_fonts = analyze_font_distribution('data/ver1.0/train.txt') ``` -------------------------------- ### Transformer-Based OCR Correction with mT5 Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt Utilizes a fine-tuned mT5 Transformer model for advanced post-OCR correction. This method achieves high accuracy metrics (CHRF++ 99.31%, WER 0.66%). It requires PyTorch and the Transformers library. The function loads the model and tokenizer, then processes the input OCR text for correction. ```python import torch from transformers import MT5ForConditionalGeneration, MT5Tokenizer def load_correction_model(model_path='correction_transformer'): """ Load fine-tuned mT5 model for post-OCR correction Achieves CHRF++ 99.31% and WER 0.66% """ tokenizer = MT5Tokenizer.from_pretrained(model_path) model = MT5ForConditionalGeneration.from_pretrained(model_path) return tokenizer, model def correct_ocr_output(ocr_text, tokenizer, model, device='cuda'): """ Correct OCR errors using Transformer model """ # Prepare input input_text = f"correct: {ocr_text}" inputs = tokenizer(input_text, return_tensors='pt', max_length=512, truncation=True) inputs = {k: v.to(device) for k, v in inputs.items()} # Generate correction model.to(device) with torch.no_grad(): outputs = model.generate( **inputs, max_length=512, num_beams=5, early_stopping=True ) corrected = tokenizer.decode(outputs[0], skip_special_tokens=True) return corrected # Usage tokenizer, model = load_correction_model() ocr_errors = "စိတ်မပူ_ပါ_နဲ့_ရှာ_တွေ့_အောင်_ကြိုးစား_ပါ_မယ်" corrected = correct_ocr_output(ocr_errors, tokenizer, model) print(f"OCR output: {ocr_errors}") print(f"Corrected: {corrected}") # WER reduced from 9.18% to 0.66% # CHRF++ improved from 97.90% to 99.31% ``` -------------------------------- ### OCR Model Prediction Decoding (Python) Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt Provides a function `decode_predictions` to convert raw CTC model outputs into human-readable text. This function uses greedy decoding by selecting the most probable character at each time step and then removes duplicate characters and blanks. It requires the model's predictions, a mapping from character indices to characters (`idx_to_char`), and optionally the index of the blank character. ```python def decode_predictions(predictions, idx_to_char, blank_index=0): """ Decode CTC predictions to text """ decoded_texts = [] for pred in predictions: # Greedy decoding pred_indices = np.argmax(pred, axis=-1) # Remove consecutive duplicates previous = blank_index decoded_chars = [] for idx in pred_indices: if idx != previous and idx != blank_index: decoded_chars.append(idx_to_char.get(idx, '')) previous = idx decoded_texts.append(''.join(decoded_chars)) return decoded_texts # Example prediction # Assuming load_trained_model, load_test_images are defined elsewhere # model = load_trained_model('myocr_model_9000iter.h5') # test_images = load_test_images(['Images/MyanmarAyar3_664.png']) # predictions = model.predict(test_images) # decoded = decode_predictions(predictions, train_gen.idx_to_char) # print(f"Predicted text: {decoded[0]}") # Expected: စိတ်မပူ_ပါ_နဲ့_ရှာ_တွေ့_အောင်_ကြိုးစား_ပါ_မယ် ``` -------------------------------- ### Validate Dataset Integrity Source: https://context7.com/ye-kyaw-thu/myocr/llms.txt Validates the integrity of a dataset by checking for missing images, encoding issues, empty labels, and duplicate image entries. It iterates through a data file, verifies image existence, and reports any identified issues. Dependencies include `os` and `pathlib.Path`. ```python import os from pathlib import Path def validate_dataset(data_file, image_base_dir): """ Validate dataset integrity: check missing images, encoding issues """ issues = { 'missing_images': [], 'invalid_encoding': [], 'empty_labels': [], 'duplicate_images': [] } seen_images = set() total_lines = 0 with open(data_file, 'r', encoding='utf-8') as f: for line_num, line in enumerate(f, 1): total_lines += 1 try: parts = line.strip().split('\t') if len(parts) != 2: issues['invalid_encoding'].append(line_num) continue image_path, label = parts # Check for empty labels if not label.strip(): issues['empty_labels'].append(line_num) # Check for duplicate images if image_path in seen_images: issues['duplicate_images'].append(image_path) seen_images.add(image_path) # Check if image exists full_path = Path(image_base_dir) / image_path if not full_path.exists(): issues['missing_images'].append(image_path) except Exception as e: print(f"Error at line {line_num}: {e}") # Print report print(f"Dataset Validation Report") print(f"=" * 50) print(f"Total entries: {total_lines}") print(f"Unique images: {len(seen_images)}") print(f"Missing images: {len(issues['missing_images'])}") print(f"Invalid encoding: {len(issues['invalid_encoding'])}") print(f"Empty labels: {len(issues['empty_labels'])}") print(f"Duplicate images: {len(issues['duplicate_images'])}") return issues # Validate datasets train_issues = validate_dataset('data/ver1.0/train.txt', 'data/ver1.0') valid_issues = validate_dataset('data/ver1.0/valid.txt', 'data/ver1.0') ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.