Omarrran's picture
OCR Dataset Generator for HF Spaces
24a732c
/**
* CRNN/CTC Output Format Adapter
*
* Format:
* images/
* img_000000.png
* img_000001.png
* ...
* labels.txt (filename<TAB>label)
*/
import { mkdir, writeFile } from 'fs/promises';
import { join } from 'path';
export interface CRNNOptions {
delimiter?: string;
includeExtension?: boolean;
}
export interface CRNNOutput {
imageDir: string;
labelsFile: string;
count: number;
}
/**
* CRNN Adapter class
*/
export class CRNNAdapter {
private outputDir: string;
private options: CRNNOptions;
private labels: string[] = [];
constructor(outputDir: string, options: CRNNOptions = {}) {
this.outputDir = join(outputDir, 'crnn');
this.options = {
delimiter: options.delimiter || '\t',
includeExtension: options.includeExtension ?? true,
};
}
/**
* Initialize output directories
*/
async init(): Promise<void> {
await mkdir(join(this.outputDir, 'images'), { recursive: true });
this.labels = [];
}
/**
* Add a sample
*/
addSample(imageFilename: string, text: string): void {
const filename = this.options.includeExtension
? imageFilename
: imageFilename.replace(/\.[^.]+$/, '');
this.labels.push(`${filename}${this.options.delimiter}${text}`);
}
/**
* Get image output path for a sample
*/
getImagePath(index: number, prefix: string = 'img'): string {
const filename = `${prefix}_${String(index).padStart(6, '0')}.png`;
return join(this.outputDir, 'images', filename);
}
/**
* Finalize and write labels file
*/
async finalize(): Promise<CRNNOutput> {
const labelsPath = join(this.outputDir, 'labels.txt');
await writeFile(labelsPath, this.labels.join('\n'), 'utf-8');
return {
imageDir: join(this.outputDir, 'images'),
labelsFile: labelsPath,
count: this.labels.length,
};
}
/**
* Get statistics
*/
getStats(): { count: number } {
return { count: this.labels.length };
}
}
/**
* Create CRNN adapter
*/
export function createCRNNAdapter(outputDir: string, options?: CRNNOptions): CRNNAdapter {
return new CRNNAdapter(outputDir, options);
}