label-studio-converter 1.3.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,28 +22,28 @@
22
22
  - [Library Usage](#library-usage)
23
23
  - [CLI Usage](#cli-usage)
24
24
  - [Available Commands](#available-commands)
25
- - [Command Options Reference](#command-options-reference)
26
- - [Common Options (All Commands)](#common-options-all-commands)
27
- - [Enhancement Options (All Commands)](#enhancement-options-all-commands)
28
- - [toLabelStudio Specific Options](#tolabelstudio-specific-options)
29
- - [toPPOCR Specific Options](#toppocr-specific-options)
30
- - [enhance-labelstudio Specific Options](#enhance-labelstudio-specific-options)
31
- - [Error Handling](#error-handling)
25
+ - [Command Flags Reference](#command-flags-reference)
26
+ - [Flags Available for All Commands](#flags-available-for-all-commands)
27
+ - [Flags Specific to toLabelStudio Command](#flags-specific-to-tolabelstudio-command)
28
+ - [Flags Specific to toPPOCR Command](#flags-specific-to-toppocr-command)
29
+ - [Flags Specific to enhance-labelstudio Command](#flags-specific-to-enhance-labelstudio-command)
30
+ - [Image Path Resolution Logic](#image-path-resolution-logic)
31
+ - [Image Path Resolution Logic](#image-path-resolution-logic)
32
+ - [toLabelStudio: PPOCRLabel → Label Studio](#tolabelstudio-ppocrlabel--label-studio)
33
+ - [toPPOCR: Label Studio → PPOCRLabel](#toppocr-label-studio--ppocrlabel)
34
+ - [enhance-labelstudio: Label Studio Enhancement](#enhance-labelstudio-label-studio--label-studio-enhanced)
35
+ - [enhance-ppocr: PPOCRLabel Enhancement](#enhance-ppocr-ppocrlabel--ppocrlabel-enhanced)
36
+ - [Adaptive Resize Feature](#adaptive-resize-feature)
32
37
  - [Detailed Command Help](#detailed-command-help)
33
38
  - [toLabelStudio Command](#tolabelstudio-command)
34
39
  - [toPPOCR Command](#toppocr-command)
35
40
  - [enhance-labelstudio Command](#enhance-labelstudio-command)
36
41
  - [enhance-ppocr Command](#enhance-ppocr-command)
37
42
  - [Examples](#examples)
38
- - [Basic Conversion Examples](#basic-conversion-examples)
39
- - [toLabelStudio Examples](#tolabelstudio-examples)
40
- - [toPPOCR Examples](#toppocr-examples)
41
- - [Recursive Search and Pattern Matching Examples](#recursive-search-and-pattern-matching-examples)
42
- - [Enhancement Examples](#enhancement-examples)
43
- - [Shape Normalization Examples](#shape-normalization-examples)
44
- - [Bounding Box Resizing Examples](#bounding-box-resizing-examples)
45
- - [Combined Enhancement Examples](#combined-enhancement-examples)
46
- - [Special Format Examples](#special-format-examples)
43
+ - [Basic Conversion](#basic-conversion)
44
+ - [Enhancement Pipeline](#enhancement-pipeline)
45
+ - [File Organization](#file-organization)
46
+ - [Shape Normalization](#shape-normalization)
47
47
  - [Using generated files with Label Studio](#using-generated-files-with-label-studio)
48
48
  - [Interface setup](#interface-setup)
49
49
  - [Serving annotation files locally](#serving-annotation-files-locally)
@@ -145,14 +145,14 @@ pnpm install
145
145
 
146
146
  ```ts
147
147
  import {
148
- labelStudioToPPOCR,
149
- minLabelStudioToPPOCR,
148
+ fullLabelStudioToPPOCRConverters,
149
+ minLabelStudioToPPOCRConverters,
150
150
  ppocrToLabelStudio
151
151
  } from 'label-studio-converter';
152
152
 
153
153
  // Convert Label Studio Full Format to PPOCRLabel
154
154
  const fullData = [...]; // FullOCRLabelStudio type
155
- const ppocrMap = await labelStudioToPPOCR(fullData, {
155
+ const ppocrMap = await fullLabelStudioToPPOCRConverters(fullData, {
156
156
  baseImageDir: 'images/ch',
157
157
  normalizeShape: 'rectangle',
158
158
  widthIncrement: 5,
@@ -162,7 +162,7 @@ const ppocrMap = await labelStudioToPPOCR(fullData, {
162
162
 
163
163
  // Convert Label Studio Min Format to PPOCRLabel
164
164
  const minData = [...]; // MinOCRLabelStudio type
165
- const ppocrMap2 = await minLabelStudioToPPOCR(minData, {
165
+ const ppocrMap2 = await minLabelStudioToPPOCRConverters(minData, {
166
166
  baseImageDir: 'images/ch',
167
167
  precision: 0
168
168
  });
@@ -268,108 +268,564 @@ COMMANDS
268
268
  enhance-ppocr Enhance PPOCRLabel files with sorting, normalization, and resizing
269
269
  ```
270
270
 
271
- #### Command Options Reference
272
-
273
- ##### Common Options (All Commands)
274
-
275
- These options are available for all commands:
276
-
277
- - **`--outDir <path>`**: Output directory. If not specified, files are saved in
278
- the same directory as the source files
279
- - **`--fileName <name>`**: Custom output filename. If not specified, uses source
280
- filename with format suffix
281
- - **`--backup` / `--noBackup`**: Create backup of existing files before
282
- overwriting. Default: `false`
283
- - **`--recursive` / `--noRecursive`**: Recursively search directories for files.
284
- Default: `false`
285
- - **`--filePattern <regex>`**: Regex pattern to match files. Default: `.*\.txt$`
286
- (PPOCR) or `.*\.json$` (Label Studio)
287
- - **`-h` / `--help`**: Print help information and exit
288
-
289
- ##### Enhancement Options (All Commands)
290
-
291
- These options control bounding box transformations:
292
-
293
- - **`--sortVertical <order>`**: Sort bounding boxes vertically
294
- - Options: `none` (default), `top-bottom`, `bottom-top`
295
- - Useful for organizing annotations by reading order
296
-
297
- - **`--sortHorizontal <order>`**: Sort bounding boxes horizontally
298
- - Options: `none` (default), `ltr` (left-to-right), `rtl` (right-to-left)
299
- - `ltr`: For English, most European languages
300
- - `rtl`: For Arabic, Hebrew, and SinoNom (classical Vietnamese/Chinese
301
- vertical text)
302
-
303
- - **`--normalizeShape <shape>`**: Normalize shapes to standard forms
304
- - Options: `none` (default), `rectangle`
305
- - `rectangle`: Converts diamond-like or rotated quadrilaterals to axis-aligned
306
- rectangles
307
-
308
- - **`--widthIncrement <pixels>`**: Increase/decrease bounding box width (can be
309
- negative)
310
- - Default: `0`
311
- - Example: `10` adds 10px, `-5` removes 5px
312
-
313
- - **`--heightIncrement <pixels>`**: Increase/decrease bounding box height (can
314
- be negative)
315
- - Default: `0`
316
- - Example: `15` adds 15px, `-3` removes 3px
317
-
318
- - **`--precision <decimals>`**: Number of decimal places for coordinates
319
- - `-1`: Full precision, no rounding (default for Label Studio output)
320
- - `0`: Round to integers (default for PPOCR output)
321
- - `1+`: Round to specified decimal places
322
-
323
- ##### toLabelStudio Specific Options
324
-
325
- - **`--defaultLabelName <name>`**: Default label name for text annotations.
326
- Default: `"Text"`
327
- - **`--toFullJson` / `--noToFullJson`**: Convert to Full OCR Label Studio
328
- format. Default: `true`
329
- - **`--createFilePerImage` / `--noCreateFilePerImage`**: Create separate JSON
330
- file for each image. Default: `false`
331
- - **`--createFileListForServing` / `--noCreateFileListForServing`**: Create file
332
- list for serving in Label Studio. Default: `true`
333
- - **`--fileListName <name>`**: Name of the file list for serving. Default:
334
- `"files.txt"`
335
- - **`--baseServerUrl <url>`**: Base server URL for image URLs in file list.
336
- Default: `"http://localhost:8081"`
337
- - **`--outputMode <mode>`**: Output format mode
338
- - Options: `annotations` (default), `predictions`
339
- - `annotations`: Editable annotations (ground truth)
340
- - `predictions`: Read-only predictions (pre-annotations)
341
- - Only available with `--toFullJson`
342
-
343
- ##### toPPOCR Specific Options
344
-
345
- - **`--baseImageDir <path>`**: Base directory path to prepend to image filenames
346
- (e.g., `"ch"` or `"images/ch"`)
347
- - **`--fileName <name>`**: Output PPOCR file name. Default: `"Label.txt"`
348
-
349
- ##### enhance-labelstudio Specific Options
350
-
351
- - **`--outputMode <mode>`**: Output format mode
352
- - Options: `annotations` (default), `predictions`
353
- - Only available for Full JSON format files
271
+ #### Command Flags Reference
272
+
273
+ ##### Flags Available for All Commands
274
+
275
+ **File I/O Flags:**
276
+
277
+ - `--outDir <path>`: Output directory path
278
+ - **Behavior**: Saves converted/enhanced files to specified directory
279
+ - **Default**: Same directory as input files
280
+ - **Example**: `--outDir ./output` saves all files to `./output/`
281
+
282
+ - `--fileName <name>`: Custom output filename
283
+ - **Behavior**: Renames output file (without extension for JSON, with extension for txt)
284
+ - **Default**:
285
+ - toLabelStudio: `{source}_full.json` or `{source}_min.json`
286
+ - toPPOCR: `Label.txt`
287
+ - enhance commands: Same as input filename
288
+ - **Example**: `--fileName MyLabels.txt` creates `MyLabels.txt` instead of `Label.txt`
289
+
290
+ - `--backup` / `--noBackup`: Create backup before overwriting
291
+ - **Behavior**: Copies existing file to `{filename}.backup` before overwriting
292
+ - **Default**: `false` (no backup)
293
+ - **Example**: `--backup` creates `Label.txt.backup` if `Label.txt` exists
294
+
295
+ - `--recursive` / `--noRecursive`: Search subdirectories
296
+ - **Behavior**: Processes files in all subdirectories recursively
297
+ - **Default**: `false` (current directory only)
298
+ - **Example**: `--recursive` processes `./data/train/Label.txt` and `./data/test/Label.txt`
299
+
300
+ - `--filePattern <regex>`: Pattern to match input files
301
+ - **Behavior**: Only processes files matching regex pattern
302
+ - **Default**:
303
+ - PPOCRLabel commands: `.*\.txt$` (all .txt files)
304
+ - Label Studio commands: `.*\.json$` (all .json files)
305
+ - **Example**: `--filePattern "train_.*\.txt$"` only processes files starting with `train_`
306
+
307
+ - `--copyImages` / `--noCopyImages`: Copy images when using --outDir
308
+ - **Behavior**: When --outDir is specified, automatically copies/moves images to output directory alongside converted files
309
+ - **Default**: `true` (copy images)
310
+ - **Example**: `--noCopyImages` keeps images in original location, only copies task files
311
+ - **Note**: Only applies to toLabelStudio and toPPOCR converters when --outDir is used
312
+
313
+ **Enhancement Flags:**
314
+
315
+ - `--sortVertical <order>`: Vertical sorting order
316
+ - **Behavior**: Sorts bounding boxes by vertical position
317
+ - **Options**: `none`, `top-bottom`, `bottom-top`
318
+ - **Default**: `none` (no sorting)
319
+ - **Example**: `--sortVertical top-bottom` sorts boxes from top to bottom
320
+
321
+ - `--sortHorizontal <order>`: Horizontal sorting order
322
+ - **Behavior**: Sorts bounding boxes by horizontal position (applied after vertical sort)
323
+ - **Options**: `none`, `ltr` (left-to-right), `rtl` (right-to-left)
324
+ - **Default**: `none` (no sorting)
325
+ - **Example**: `--sortHorizontal rtl` sorts boxes right-to-left (for vertical text)
326
+
327
+ - `--normalizeShape <option>`: Shape normalization
328
+ - **Behavior**: Converts diamond/rotated shapes to axis-aligned rectangles
329
+ - **Options**: `none`, `rectangle`
330
+ - **Default**: `none` (preserve original shapes)
331
+ - **Example**: `--normalizeShape rectangle` converts all polygons to rectangles
332
+
333
+ - `--widthIncrement <pixels>`: Adjust box width
334
+ - **Behavior**: Adds pixels to box width (can be negative to shrink)
335
+ - **Default**: `0` (no change)
336
+ - **Example**: `--widthIncrement 5` expands boxes by 5px horizontally
337
+
338
+ - `--heightIncrement <pixels>`: Adjust box height
339
+ - **Behavior**: Adds pixels to box height (can be negative to shrink)
340
+ - **Default**: `0` (no change)
341
+ - **Example**: `--heightIncrement -3` shrinks boxes by 3px vertically
342
+
343
+ - `--precision <decimals>`: Coordinate precision
344
+ - **Behavior**: Number of decimal places for coordinates
345
+ - **Default**:
346
+ - toLabelStudio: `-1` (full precision, no rounding)
347
+ - toPPOCR: `0` (integers only)
348
+ - enhance-labelstudio: `-1` (full precision)
349
+ - enhance-ppocr: `0` (integers)
350
+ - **Example**: `--precision 2` rounds to 2 decimal places (e.g., 123.45)
351
+
352
+ **Adaptive Resize Flags (Advanced):**
353
+
354
+ - `--adaptResize` / `--noAdaptResize`: Enable intelligent box resizing
355
+ - **Behavior**: Uses image analysis to shrink oversized boxes to fit actual text
356
+ - **Default**: `false` (disabled)
357
+ - **Use Case**: Sino-Nom OCR datasets with excessive padding
358
+ - **Example**: `--adaptResize` enables feature with default parameters
359
+
360
+ - `--adaptResizeThreshold <0-255>`: Grayscale threshold
361
+ - **Behavior**: Pixels ≥ threshold are considered text (white), < threshold are background (black)
362
+ - **Default**: `128`
363
+ - **Example**: `--adaptResizeThreshold 140` for darker text on light background
364
+
365
+ - `--adaptResizeMargin <pixels>`: Padding around detected content
366
+ - **Behavior**: Additional pixels added on all sides after detection
367
+ - **Default**: `5`
368
+ - **Example**: `--adaptResizeMargin 8` adds 8px padding
369
+
370
+ - `--adaptResizeMinComponentSize <pixels>`: Noise filter
371
+ - **Behavior**: Regions smaller than this are ignored (filters dirt dots)
372
+ - **Default**: `10`
373
+ - **Example**: `--adaptResizeMinComponentSize 15` filters more aggressively
374
+
375
+ - `--adaptResizeMaxComponentSize <pixels>`: Artifact filter
376
+ - **Behavior**: Regions larger than this are ignored (filters huge artifacts)
377
+ - **Default**: `100000`
378
+ - **Example**: `--adaptResizeMaxComponentSize 50000` for smaller characters
379
+
380
+ - `--adaptResizeOutlierPercentile <%>`: Outlier removal
381
+ - **Behavior**: Ignores this % of smallest and largest pixels when calculating boundaries
382
+ - **Default**: `2` (ignore 2% on each end)
383
+ - **Example**: `--adaptResizeOutlierPercentile 3` for more aggressive outlier removal
384
+
385
+ - `--adaptResizeMorphologySize <pixels>`: Stroke connection
386
+ - **Behavior**: Kernel size for connecting broken character strokes
387
+ - **Default**: `2`
388
+ - **Example**: `--adaptResizeMorphologySize 3` connects larger gaps
389
+
390
+ - `--adaptResizeMaxHorizontalExpansion <pixels>`: Column overlap prevention
391
+ - **Behavior**: Maximum pixels boxes can expand horizontally (CRITICAL for vertical text)
392
+ - **Default**: `50`
393
+ - **Example**: `--adaptResizeMaxHorizontalExpansion 30` for closely-spaced columns
394
+
395
+ ##### Flags Specific to toLabelStudio Command
396
+
397
+ - `--defaultLabelName <name>`: Default label for annotations
398
+ - **Behavior**: Label assigned to all text regions
399
+ - **Default**: `"Text"`
400
+ - **Example**: `--defaultLabelName "Handwriting"` labels all regions as Handwriting
401
+
402
+ - `--toFullJson` / `--noToFullJson`: Output format
403
+ - **Behavior**: `true` = Full format (more metadata), `false` = Min format (compact)
404
+ - **Default**: `true` (Full format)
405
+ - **Example**: `--noToFullJson` creates minimal format files
406
+
407
+ - `--createFilePerImage` / `--noCreateFilePerImage`: File splitting
408
+ - **Behavior**: `true` = one JSON per image, `false` = all tasks in one file
409
+ - **Default**: `false` (single file)
410
+ - **Example**: `--createFilePerImage` creates `image1.json`, `image2.json`, etc.
411
+
412
+ - `--createFileListForServing` / `--noCreateFileListForServing`: Generate file list
413
+ - **Behavior**: Creates `files.txt` with image URLs for Label Studio import
414
+ - **Default**: `true` (create file list)
415
+ - **Example**: `--noCreateFileListForServing` skips file list creation
416
+
417
+ - `--fileListName <name>`: File list filename
418
+ - **Behavior**: Name of the file containing image URLs for serving
419
+ - **Default**: `"files.txt"`
420
+ - **Example**: `--fileListName "images.txt"` creates `images.txt` instead
421
+
422
+ - `--baseServerUrl <url>`: Base URL for images
423
+ - **Behavior**: Prepended to image paths in output JSON (e.g., for local HTTP server)
424
+ - **Default**: `"http://localhost:8081"`
425
+ - **Example**: `--baseServerUrl "http://192.168.1.100:8080"` for network access
354
426
 
355
- > [!NOTE]
356
- > **Output Mode Availability:**
357
- >
358
- > - `--outputMode` is only available for:
359
- > - `toLabelStudio` (when using `--toFullJson`)
360
- > - `enhance-labelstudio` (for Full JSON format only)
361
- > - Not available for `toPPOCR` or `enhance-ppocr` (PPOCR format doesn't
362
- > distinguish annotations/predictions)
363
- > - When using `--outputMode predictions`, the `dt_score` field from PPOCRLabel
364
- > is mapped to Label Studio's prediction `score` field
427
+ - `--outputMode <mode>`: Annotation mode
428
+ - **Behavior**:
429
+ - `annotations` = editable ground truth annotations
430
+ - `predictions` = read-only pre-annotations
431
+ - **Default**: `"annotations"`
432
+ - **Example**: `--outputMode predictions` for model predictions import
433
+
434
+ ##### Flags Specific to toPPOCR Command
435
+
436
+ - `--baseImageDir <path>`: Image directory prefix
437
+ - **Behavior**: Prepended to image filenames in output `Label.txt`
438
+ - **Default**: Empty string (no prefix)
439
+ - **Example**: `--baseImageDir "images/ch"` writes `images/ch/example.jpg` in Label.txt
440
+
441
+ ##### Flags Specific to enhance-labelstudio Command
442
+
443
+ - `--outputMode <mode>`: Same as toLabelStudio command
444
+ - See toLabelStudio flags section above
445
+
446
+ #### Image Path Resolution Logic
447
+
448
+ Understanding how image paths are resolved is critical for organizing your files before conversion. The key is knowing **where you run the command** and **what input parameter you provide**.
449
+
450
+ ##### toLabelStudio: PPOCRLabel → Label Studio
451
+
452
+ **INPUT Resolution (Reading PPOCRLabel files):**
453
+
454
+ **Command Execution Context:**
455
+
456
+ - You run: `cd project && label-studio-converter toLabelStudio data/`
457
+ - Current working directory (CWD): `project/`
458
+ - Input parameter: `data/` (directory to search for Label.txt files)
459
+ - Converter finds: `project/data/Label.txt` (and other Label.txt files in subdirectories if --recursive)
460
+ - Task file being processed: `project/data/Label.txt`
461
+
462
+ **How Resolvers Work:**
463
+
464
+ 1. **What's in the Label.txt file**:
465
+ - Path format: `data/example.jpg` (PPOCRLabel standard: folder/filename)
466
+ - PPOCRLabel was opened on `data/` folder, so paths use `data/` prefix
467
+
468
+ 2. **How input resolver finds images**:
469
+ - Reads path from Label.txt: `data/example.jpg`
470
+ - Task file is at: `project/data/Label.txt`
471
+ - Task directory: `project/data/`
472
+ - Check if path starts with task folder name (`data/`):
473
+ - YES → resolve from parent: `dirname(project/data/) + data/example.jpg` = `project/data/example.jpg`
474
+ - NO → resolve from task dir: `project/data/ + example.jpg` = `project/data/example.jpg`
475
+
476
+ 3. **What the processor receives**:
477
+ - Path relative to CWD: `data/example.jpg`
478
+ - (This is `relative(project/, project/data/example.jpg)` = `data/example.jpg`)
479
+
480
+ **OUTPUT Resolution (Writing Label Studio JSON):**
481
+
482
+ **Command Execution Context:**
483
+
484
+ - Output location: Same as task file location (no --outDir specified)
485
+ - Output file: `project/data/Label_full.json`
486
+
487
+ **How Resolvers Work:**
488
+
489
+ 1. **What the processor has**:
490
+ - Path relative to CWD: `data/example.jpg`
491
+ - (From input resolution step)
492
+
493
+ 2. **How output resolver formats paths**:
494
+ - No --outDir: Compute relative path from output JSON to image
495
+ - Output JSON at: `project/data/Label_full.json`
496
+ - Image at: `project/data/example.jpg`
497
+ - Relative path: `relative(project/data/, project/data/example.jpg)` = `example.jpg`
498
+ - Apply baseServerUrl: `http://localhost:8081/example.jpg`
499
+
500
+ 3. **What goes in the output file**:
501
+ - Label Studio JSON: `"ocr": "http://localhost:8081/example.jpg"`
502
+
503
+ **File Organization Examples:**
504
+
505
+ <details>
506
+ <summary><b>Example 1: Default Location (No --outDir)</b></summary>
507
+
508
+ **Setup**: Images and output in same place as task file
509
+
510
+ ```
511
+ project/
512
+ └── data/
513
+ ├── Label.txt # Contains: data/example.jpg [...]
514
+ └── example.jpg
515
+ ```
516
+
517
+ **Command:**
518
+
519
+ ```bash
520
+ cd project
521
+ label-studio-converter toLabelStudio data/
522
+ ```
523
+
524
+ **Result:**
525
+
526
+ ```
527
+ project/
528
+ └── data/
529
+ ├── Label.txt # Original task file
530
+ ├── Label_full.json # NEW: Generated output
531
+ ├── files.txt # NEW: File list for serving
532
+ └── example.jpg # Original image (unchanged)
533
+ ```
534
+
535
+ **Generated Label_full.json contains:**
536
+
537
+ ```json
538
+ {
539
+ "data": {
540
+ "ocr": "http://localhost:8081/example.jpg"
541
+ }
542
+ }
543
+ ```
544
+
545
+ **Image Path Flow:**
546
+
547
+ - Input path in Label.txt: `data/example.jpg`
548
+ - Resolved path: `data/example.jpg` (relative to CWD)
549
+ - Output saved in: `data/` (same as task)
550
+ - Relative to output: `example.jpg`
551
+ - Final URL: `http://localhost:8081/example.jpg`
552
+
553
+ </details>
554
+
555
+ <details>
556
+ <summary><b>Example 2: With --outDir Configuration</b></summary>
557
+
558
+ **Setup**: Separate output directory for organized export
559
+
560
+ ```
561
+ project/
562
+ ├── data/
563
+ │ ├── Label.txt # Contains: data/example.jpg [...]
564
+ │ └── example.jpg
565
+ └── output/ # Target output directory
566
+ ```
567
+
568
+ **Command:**
569
+
570
+ ```bash
571
+ cd project
572
+ label-studio-converter toLabelStudio data/ \
573
+ --outDir output \
574
+ --baseServerUrl http://localhost:8081
575
+ ```
576
+
577
+ **Result:**
578
+
579
+ ```
580
+ project/
581
+ ├── data/
582
+ │ ├── Label.txt # Original (unchanged)
583
+ │ └── example.jpg # Original (unchanged)
584
+ └── output/ # NEW: All outputs here
585
+ ├── Label_full.json # NEW: Generated tasks
586
+ ├── files.txt # NEW: File list
587
+ └── example.jpg # NEW: Copied from source
588
+ ```
589
+
590
+ **Generated Label_full.json contains:**
591
+
592
+ ```json
593
+ {
594
+ "data": {
595
+ "ocr": "http://localhost:8081/example.jpg"
596
+ }
597
+ }
598
+ ```
599
+
600
+ **Image Path Flow:**
601
+
602
+ - Input path in Label.txt: `data/example.jpg`
603
+ - Resolved path: `data/example.jpg` (relative to CWD)
604
+ - Copied to: `output/example.jpg`
605
+ - Relative to output: `example.jpg`
606
+ - Final URL: `http://localhost:8081/example.jpg`
607
+
608
+ </details>
609
+
610
+ ##### toPPOCR: Label Studio → PPOCRLabel
611
+
612
+ **INPUT Resolution (Reading Label Studio JSON):**
613
+
614
+ **Command Execution Context:**
615
+
616
+ - You run: `cd project && label-studio-converter toPPOCR data/`
617
+ - Current working directory (CWD): `project/`
618
+ - Input parameter: `data/` (directory to search for JSON files)
619
+ - Converter finds: `project/data/export.json` (and other JSON files in subdirectories if --recursive)
620
+ - Task file being processed: `project/data/export.json`
621
+
622
+ **How Resolvers Work:**
623
+
624
+ 1. **What's in the JSON file**:
625
+ - Local path: `"ocr": "/example.jpg"` or `"ocr": "example.jpg"`
626
+ - OR Remote URL: `"ocr": "http://localhost:8081/example.jpg"`
627
+
628
+ 2. **How input resolver finds/downloads images**:
629
+ - **Local path** (`/example.jpg` or `example.jpg`):
630
+ - Strip leading slashes: `/example.jpg` → `example.jpg`
631
+ - Task directory: `project/data/`
632
+ - Resolve: `project/data/ + example.jpg` = `project/data/example.jpg`
633
+ - **Remote URL** (`http://localhost:8081/example.jpg`):
634
+ - Extract filename: `basename(URL)` = `example.jpg`
635
+ - Download to task directory: `project/data/example.jpg`
636
+
637
+ 3. **What the processor receives**:
638
+ - Path relative to CWD: `data/example.jpg`
639
+ - (This is `relative(project/, project/data/example.jpg)` = `data/example.jpg`)
640
+
641
+ **OUTPUT Resolution (Writing PPOCRLabel Label.txt):**
642
+
643
+ **Command Execution Context:**
644
+
645
+ - No --outDir specified: Output at task file location
646
+ - Output file: `project/data/Label.txt`
647
+
648
+ **How Resolvers Work:**
649
+
650
+ 1. **What the processor has**:
651
+ - Path relative to CWD: `data/example.jpg`
652
+ - (From input resolution step)
653
+
654
+ 2. **How output resolver formats paths**:
655
+ - Extract filename: `basename(data/example.jpg)` = `example.jpg`
656
+ - Determine folder prefix:
657
+ - No --baseImageDir: Use output directory basename
658
+ - Output at: `project/data/Label.txt` → folder is `data`
659
+ - Result: `data/example.jpg`
660
+ - With --baseImageDir="images": Result would be `images/example.jpg`
661
+
662
+ 3. **What goes in the output file**:
663
+ - PPOCRLabel Label.txt: `data/example.jpg [{"transcription":"Text",...}]`
664
+ - **Important**: Path in Label.txt is a reference format, NOT the physical location
665
+ - Physical images stay in task directory (`data/`), but Label.txt uses folder prefix
666
+
667
+ **File Organization Examples:**
668
+
669
+ <details>
670
+ <summary><b>Example 1: Default Location (No --outDir)</b></summary>
671
+
672
+ **Setup**: Export Label.txt to same directory as task
673
+
674
+ ```
675
+ project/
676
+ └── data/
677
+ └── export.json # Contains: "ocr": "http://localhost:8081/example.jpg"
678
+ ```
679
+
680
+ **Command:**
681
+
682
+ ```bash
683
+ cd project
684
+ label-studio-converter toPPOCR data/ \
685
+ --baseImageDir data
686
+ ```
687
+
688
+ **Result:**
689
+
690
+ ```
691
+ project/
692
+ └── data/
693
+ ├── export.json # Original (unchanged)
694
+ ├── Label.txt # NEW: Generated PPOCR file
695
+ └── example.jpg # NEW: Downloaded from server
696
+ ```
697
+
698
+ **Generated Label.txt contains:**
699
+
700
+ ```
701
+ data/example.jpg [{"transcription":"Text","points":[[...]],"dt_score":1}]
702
+ ```
703
+
704
+ **Image Path Flow:**
705
+
706
+ - Input URL in JSON: `http://localhost:8081/example.jpg`
707
+ - **Downloaded to**: `data/example.jpg` (task file directory)
708
+ - Resolved path: `data/example.jpg` (relative to CWD)
709
+ - Extracted filename: `example.jpg`
710
+ - baseImageDir: `data`
711
+ - Output in Label.txt: `data/example.jpg`
712
+
713
+ </details>
714
+
715
+ <details>
716
+ <summary><b>Example 2: With --outDir Configuration</b></summary>
717
+
718
+ **Setup**: Organize output in separate directory
719
+
720
+ ```
721
+ project/
722
+ ├── data/
723
+ │ └── export.json # Contains: "ocr": "http://localhost:8081/example.jpg"
724
+ └── output/ # Target output directory
725
+ ```
726
+
727
+ **Command:**
728
+
729
+ ```bash
730
+ cd project
731
+ label-studio-converter toPPOCR data/ \
732
+ --outDir output
733
+ ```
734
+
735
+ **Result:**
736
+
737
+ ```
738
+ project/
739
+ ├── data/
740
+ │ ├── export.json # Original (unchanged)
741
+ │ └── example.jpg # Downloaded, then copied to output
742
+ └── output/
743
+ ├── Label.txt # NEW: Generated PPOCR file
744
+ └── example.jpg # NEW: Copied from data/
745
+ ```
746
+
747
+ **Generated Label.txt contains:**
748
+
749
+ ```
750
+ output/example.jpg [{"transcription":"Text","points":[[...]],"dt_score":1}]
751
+ ```
752
+
753
+ **Image Path Flow:**
754
+
755
+ - Input URL in JSON: `http://localhost:8081/example.jpg`
756
+ - **Downloaded to**: `data/example.jpg` (task file directory)
757
+ - **Copied to**: `output/example.jpg` (because --outDir specified)
758
+ - Resolved path: `data/example.jpg` (relative to CWD)
759
+ - Output dir: `output/`
760
+ - Extracted filename: `example.jpg`
761
+ - Output folder name: `output`
762
+ - Output in Label.txt: `output/example.jpg`
763
+
764
+ **Note**: Images are automatically copied to output directory. Use `--noCopyImages` to skip copying.
765
+
766
+ </details>
767
+
768
+ ##### enhance-labelstudio: Label Studio → Label Studio (Enhanced)
769
+
770
+ **INPUT Resolution**: Same as `toPPOCR` converter
771
+
772
+ - Reads Label Studio JSON files
773
+ - Resolves local paths relative to task file
774
+ - Downloads remote URLs to task file directory
365
775
 
366
- ##### Error Handling
776
+ **OUTPUT Resolution**: Same as `toLabelStudio` converter
367
777
 
368
- The `toLabelStudio` command handles missing or unreadable image files gracefully:
778
+ - Generates Label Studio JSON with `data.ocr` URLs
779
+ - Applies `baseServerUrl` formatting
780
+ - Computes relative paths from output location to images
369
781
 
370
- - If an image file cannot be found or read, a warning is logged
371
- - Default dimensions of **1920×1080** are used as fallback
372
- - Conversion continues for remaining images without interruption
782
+ ##### enhance-ppocr: PPOCRLabel PPOCRLabel (Enhanced)
783
+
784
+ **INPUT Resolution**: Same as `toLabelStudio` converter
785
+
786
+ - Reads PPOCRLabel Label.txt files
787
+ - Resolves paths with folder pattern (`folder/file.jpg`)
788
+ - Detects folder name and resolves from parent directory
789
+
790
+ **OUTPUT Resolution**: Same as `toPPOCR` converter
791
+
792
+ - Generates PPOCRLabel Label.txt with `folder/filename.jpg` format
793
+ - Uses `baseImageDir` or output directory basename as folder prefix
794
+ - Extracts filename from resolved path, prepends folder name
795
+
796
+ ---
797
+
798
+ **Key Concepts:**
799
+
800
+ 1. **Path Resolution Flow**:
801
+ - Input converters resolve paths to **task-relative paths** (relative to task file location)
802
+ - Processor receives and operates on these **task-relative paths**
803
+ - Output converters format these paths for the target system
804
+
805
+ 2. **Remote Image Handling**:
806
+ - URLs (`http://` or `https://`) are downloaded to **task file directory**
807
+ - Only filename is extracted from URL (path structure ignored)
808
+ - Example: `http://server.com/deep/path/example.jpg` → saved as `task-dir/example.jpg`
809
+
810
+ 3. **Image Organization** (toLabelStudio & toPPOCR):
811
+ - **No --outDir**: Output files created in task directory, images stay in place
812
+ - **With --outDir**: Output files go to outDir, **images automatically copied** to outDir (unless --noCopyImages)
813
+ - **--noCopyImages**: Skip image copying, only create task files in outDir
814
+ - **enhance commands**: Images always stay in original location
815
+
816
+ 4. **Output Path Format**:
817
+ - **toLabelStudio**: `${baseServerUrl}/${relativePath}` where relativePath is from output JSON to image
818
+ - **toPPOCR**: `${folder}/${filename}` where folder is `baseImageDir` or output directory name
819
+
820
+ #### Adaptive Resize Feature
821
+
822
+ For detailed algorithm documentation and tuning guide, see [ADAPTIVE_RESIZE.md](docs/ADAPTIVE_RESIZE.md).
823
+
824
+ **Quick Overview:**
825
+
826
+ - **Purpose**: Shrinks oversized boxes to fit actual text content (essential for Sino-Nom OCR with excessive padding)
827
+ - **Algorithm**: Morphological operations + connected component analysis + percentile-based outlier removal
828
+ - **Usage**: Enable with `--adaptResize` flag, tune with 7 parameters documented above
373
829
 
374
830
  #### Detailed Command Help
375
831
 
@@ -516,221 +972,101 @@ ARGUMENTS
516
972
 
517
973
  #### Examples
518
974
 
519
- ##### Basic Conversion Examples
520
-
521
- ```bash
522
- # Convert PPOCRLabel files to full Label Studio format
523
- label-studio-converter toLabelStudio ./input-ppocr --outDir ./output-label-studio
524
-
525
- # Convert Label Studio files to PPOCRLabel format
526
- label-studio-converter toPPOCR ./input-label-studio --outDir ./output-ppocr
527
-
528
- # Convert with custom output filename for PPOCR
529
- label-studio-converter toPPOCR ./input-label-studio --outDir ./output-ppocr --fileName MyLabels.txt
530
-
531
- # Convert with base image directory path
532
- label-studio-converter toPPOCR ./input-label-studio --baseImageDir images/ch
533
- ```
534
-
535
- > [!NOTE]
536
- > By default, all PPOCRLabel positions are treated as **polygons** in Label Studio.
537
-
538
- ##### toLabelStudio Examples
975
+ ##### Basic Conversion
539
976
 
540
977
  ```bash
541
- # Create separate JSON file for each image
542
- label-studio-converter toLabelStudio ./input-ppocr \
543
- --outDir ./output \
544
- --createFilePerImage
978
+ # PPOCRLabel Label Studio
979
+ label-studio-converter toLabelStudio ./input-ppocr --outDir ./output
545
980
 
546
- # Specify custom label name (default is "Text")
547
- label-studio-converter toLabelStudio ./input-ppocr \
548
- --outDir ./output \
549
- --defaultLabelName Handwriting
550
-
551
- # Convert to minimal format (without serving support)
552
- label-studio-converter toLabelStudio ./input-ppocr \
553
- --outDir ./output \
554
- --noToFullJson
981
+ # Label Studio PPOCRLabel
982
+ label-studio-converter toPPOCR ./input-label-studio --outDir ./output --baseImageDir images/ch
555
983
 
556
- # Disable file list creation for serving
984
+ # File-per-image + custom server URL
557
985
  label-studio-converter toLabelStudio ./input-ppocr \
558
986
  --outDir ./output \
559
- --noCreateFileListForServing
560
-
561
- # Custom file list name and server URL
562
- label-studio-converter toLabelStudio ./input-ppocr \
563
- --outDir ./output \
564
- --fileListName my-images.txt \
987
+ --createFilePerImage \
565
988
  --baseServerUrl http://192.168.1.100:8080
566
989
 
567
- # Convert to predictions format (pre-annotations) instead of annotations
568
- # Predictions are read-only and useful for pre-annotated data
569
- label-studio-converter toLabelStudio ./input-ppocr \
570
- --outDir ./output \
571
- --outputMode predictions
572
-
573
- # Convert to annotations format (default, editable ground truth)
574
- label-studio-converter toLabelStudio ./input-ppocr \
575
- --outDir ./output \
576
- --outputMode annotations
990
+ # Predictions format (read-only pre-annotations)
991
+ label-studio-converter toLabelStudio ./input-ppocr --outputMode predictions
577
992
  ```
578
993
 
579
- ##### toPPOCR Examples
994
+ ##### Enhancement Pipeline
580
995
 
581
996
  ```bash
582
- # Basic conversion with output directory
583
- label-studio-converter toPPOCR ./input-label-studio \
584
- --outDir ./output
585
-
586
- # Custom output filename
587
- label-studio-converter toPPOCR ./input-label-studio \
588
- --outDir ./output \
589
- --fileName CustomLabel.txt
590
-
591
- # Add base image directory to paths
592
- label-studio-converter toPPOCR ./input-label-studio \
593
- --outDir ./output \
594
- --baseImageDir dataset/images
595
- ```
596
-
597
- ##### Recursive Search and Pattern Matching Examples
598
-
599
- ```bash
600
- # Recursively search all subdirectories for .txt files
601
- label-studio-converter toLabelStudio ./data --recursive
602
-
603
- # Search with custom pattern (only files starting with "Label")
604
- label-studio-converter toLabelStudio ./data \
605
- --recursive \
606
- --filePattern "Label.*\.txt$"
607
-
608
- # Convert only specific JSON files (e.g., final annotations)
609
- label-studio-converter toPPOCR ./annotations \
610
- --recursive \
611
- --filePattern ".*_final\.json$"
612
-
613
- # Enhance only specific files matching pattern
614
- label-studio-converter enhance-ppocr ./dataset \
615
- --recursive \
616
- --filePattern "train_.*\.txt$"
617
- ```
618
-
619
- > [!NOTE]
620
- >
621
- > - `--recursive`: Searches all subdirectories for matching files
622
- > - `--filePattern`: Regex pattern to filter files (default: `.*\.txt$` for
623
- > PPOCR, `.*\.json$` for Label Studio)
624
- > - Patterns are flexible - use any regex, but ensure they match appropriate
625
- > file types (.txt for PPOCR, .json for Label Studio)
626
-
627
- ##### Enhancement Examples
628
-
629
- The tool provides powerful enhancement capabilities that can be used standalone
630
- or integrated with conversion.
631
-
632
- **Enhance PPOCRLabel files:**
633
-
634
- ```bash
635
- # Sort annotations from top to bottom, left to right
636
- label-studio-converter enhance-ppocr ./data --sortVertical top-bottom --sortHorizontal ltr
637
-
638
- # Normalize diamond shapes to rectangles and resize
639
- label-studio-converter enhance-ppocr ./data --normalizeShape rectangle --widthIncrement 10 --heightIncrement 5
640
-
641
- # Apply all enhancements
997
+ # Sort + normalize + resize
642
998
  label-studio-converter enhance-ppocr ./data \
643
999
  --sortVertical top-bottom \
644
1000
  --sortHorizontal ltr \
645
1001
  --normalizeShape rectangle \
646
1002
  --widthIncrement 5 \
647
- --heightIncrement 5 \
648
- --precision 0
649
- ```
1003
+ --heightIncrement 5
650
1004
 
651
- **Enhance Label Studio files:**
1005
+ # Adaptive resize for Sino-Nom OCR (shrinks oversized boxes)
1006
+ label-studio-converter enhance-ppocr ./sinonom-data \
1007
+ --adaptResize \
1008
+ --adaptResizeThreshold 128 \
1009
+ --adaptResizeMargin 8 \
1010
+ --adaptResizeMaxHorizontalExpansion 50 \
1011
+ --sortHorizontal rtl
652
1012
 
653
- ```bash
654
- # Sort and normalize Label Studio annotations
655
- label-studio-converter enhance-labelstudio ./data \
656
- --sortVertical top-bottom \
1013
+ # Convert with full enhancement pipeline
1014
+ label-studio-converter toLabelStudio ./input-ppocr \
1015
+ --outDir ./output \
657
1016
  --normalizeShape rectangle \
658
- --precision 2
659
-
660
- # Works with both Full and Min formats automatically
661
- label-studio-converter enhance-labelstudio ./label-studio-files --outDir ./enhanced
1017
+ --adaptResize \
1018
+ --sortVertical top-bottom
662
1019
  ```
663
1020
 
664
- **Conversion with enhancements:**
1021
+ ##### File Organization
665
1022
 
666
1023
  ```bash
667
- # Convert with enhancements applied during conversion
668
- label-studio-converter toLabelStudio ./input-ppocr \
669
- --outDir ./output \
670
- --sortVertical top-bottom \
671
- --normalizeShape rectangle \
672
- --widthIncrement 10
1024
+ # Recursive search with pattern matching
1025
+ label-studio-converter toLabelStudio ./dataset \
1026
+ --recursive \
1027
+ --filePattern "train_.*\.txt$"
673
1028
 
674
- label-studio-converter toPPOCR ./input-label-studio \
1029
+ # Custom output filenames
1030
+ label-studio-converter toPPOCR ./data \
675
1031
  --outDir ./output \
676
- --sortVertical top-bottom \
677
- --sortHorizontal ltr \
678
- --normalizeShape rectangle
1032
+ --fileName MyLabels.txt
679
1033
  ```
680
1034
 
681
- ##### Shape Normalization Examples
1035
+ ##### Shape Normalization
682
1036
 
683
- Convert diamond-like or irregular quadrilateral shapes to axis-aligned
684
- rectangles. This is useful when your annotations have irregular shapes that you
685
- want to normalize to clean, horizontal/vertical bounding boxes:
1037
+ Diamond/rotated shapes axis-aligned rectangles:
686
1038
 
687
1039
  ```bash
688
- # Convert to axis-aligned rectangles
689
- label-studio-converter toLabelStudio ./input-ppocr --outDir ./output --normalizeShape rectangle
690
-
691
- # For toPPOCR command
692
- label-studio-converter toPPOCR ./input-label-studio --outDir ./output --normalizeShape rectangle
1040
+ label-studio-converter enhance-ppocr ./data \
1041
+ --normalizeShape rectangle \
1042
+ --outDir ./normalized
693
1043
  ```
694
1044
 
695
1045
  <details>
696
- <summary>
697
- <b>Before normalization</b> (diamond-like shapes):
698
- </summary>
1046
+ <summary>Visual comparison</summary>
699
1047
 
700
- ![Before normalization](./docs/images/label-studio-original-diamond.png)
1048
+ **Before:** Diamond-like shapes
701
1049
 
702
- </details>
703
-
704
- <details>
705
- <summary>
706
- <b>After normalization</b> (axis-aligned rectangles):
707
- </summary>
708
-
709
- Command:
1050
+ ![Before normalization](./docs/images/label-studio-original-diamond.png)
710
1051
 
711
- ```bash
712
- ./dist/cli.js toPPOCR ./tmp --baseImageDir output --normalizeShape rectangle
713
- ```
1052
+ **After:** Axis-aligned rectangles
714
1053
 
715
1054
  ![After normalization](./docs/images/label-studio-converted-diamond.png)
716
1055
 
717
- </details>
718
-
719
- <details>
720
- <summary>
721
- <b>Before normalization</b> (diamond-like vertical shapes):
722
- </summary>
1056
+ **Vertical text example:**
723
1057
 
724
- ![Before normalization (vert)](./docs/images/label-studio-original-diamond-vert.png)
1058
+ ![Before (vertical)](./docs/images/label-studio-original-diamond-vert.png)
1059
+ ![After (vertical)](./docs/images/label-studio-converted-diamond-vert.png)
725
1060
 
726
1061
  </details>
727
1062
 
728
- <details>
729
- <summary>
730
- <b>After normalization</b> (axis-aligned vertical rectangles):
731
- </summary>
732
-
733
- Command:
1063
+ > [!NOTE]
1064
+ > **Key Behaviors:**
1065
+ >
1066
+ > - Remote images (`http://`, `https://`) are automatically downloaded
1067
+ > - Path resolution: `${baseServerUrl}/${relativeToOutDir}/image.jpg`
1068
+ > - All PPOCRLabel positions treated as polygons in Label Studio
1069
+ > - Missing images use fallback dimensions (1920×1080) and log warning
734
1070
 
735
1071
  ```bash
736
1072
  ./dist/cli.js toPPOCR ./tmp --baseImageDir output --normalizeShape rectangle
@@ -740,59 +1076,6 @@ Command:
740
1076
 
741
1077
  </details>
742
1078
 
743
- ##### Bounding Box Resizing Examples
744
-
745
- Increase or decrease bounding box dimensions while keeping them centered:
746
-
747
- ```bash
748
- # Increase width by 10 pixels and height by 20 pixels
749
- label-studio-converter toLabelStudio ./input-ppocr --outDir ./output --widthIncrement 10 --heightIncrement 20
750
-
751
- # Decrease width by 5 pixels (negative increment)
752
- label-studio-converter toLabelStudio ./input-ppocr --outDir ./output --widthIncrement -5
753
-
754
- # Works with toPPOCR as well
755
- label-studio-converter toPPOCR ./input-label-studio --outDir ./output --widthIncrement 10 --heightIncrement 10
756
- ```
757
-
758
- ##### Combined Enhancement Examples
759
-
760
- Combine multiple enhancements:
761
-
762
- ```bash
763
- # Normalize to rectangle and increase size
764
- label-studio-converter toLabelStudio ./input-ppocr --outDir ./output --normalizeShape rectangle --widthIncrement 5 --heightIncrement 5
765
-
766
- # Combine sorting with shape normalization
767
- label-studio-converter toLabelStudio ./input-ppocr --outDir ./output --normalizeShape rectangle --widthIncrement 10 --sortVertical top-bottom --sortHorizontal ltr
768
- ```
769
-
770
- ##### Special Format Examples
771
-
772
- **Convert with one file per image:**
773
-
774
- ```bash
775
- label-studio-converter toLabelStudio ./input-ppocr \
776
- --outDir ./output-label-studio \
777
- --defaultLabelName Text \
778
- --toFullJson \
779
- --createFilePerImage
780
- ```
781
-
782
- **Convert to minimal Label Studio format:**
783
-
784
- ```bash
785
- label-studio-converter toLabelStudio ./input-ppocr \
786
- --outDir ./output-label-studio \
787
- --defaultLabelName Text \
788
- --noToFullJson
789
- ```
790
-
791
- > [!IMPORTANT]
792
- > Minimal Label Studio format cannot be used for serving in Label Studio, as it
793
- > lacks necessary fields such as `id` and `data`. You can only use minimal
794
- > format for conversion back to PPOCRLabelv2 format or other purposes.
795
-
796
1079
  ### Using generated files with Label Studio
797
1080
 
798
1081
  #### Interface setup
@@ -1121,10 +1404,10 @@ Converted back to Label Studio annotation:
1121
1404
  "last_created_by": null
1122
1405
  }
1123
1406
  ],
1124
- "file_upload": "5b1e3483-example.jpg",
1407
+ "file_upload": "example.jpg",
1125
1408
  "drafts": [],
1126
1409
  "predictions": [],
1127
- "data": { "ocr": "\/data\/upload\/2\/5b1e3483-example.jpg" },
1410
+ "data": { "ocr": "\/example.jpg" },
1128
1411
  "meta": {},
1129
1412
  "created_at": "2026-01-07T03:13:41.175183Z",
1130
1413
  "updated_at": "2026-01-10T03:21:09.923449Z",
@@ -1159,7 +1442,7 @@ Command:
1159
1442
  Output:
1160
1443
 
1161
1444
  ```
1162
- output/example.jpg [{"transcription":"ACUTE CORONARY SYNDROME","points":[[246,302],[621,302],[621,330],[246,330]],"dt_score":1},{"transcription":"MILD CORONARY ARTERY DISEASE","points":[[245,366],[681,366],[681,391],[245,391]],"dt_score":1},{"transcription":"MEDICAL MANAGEMENT","points":[[246,426],[548,420],[551,446],[251,450]],"dt_score":1}]
1445
+ data/example.jpg [{"transcription":"ACUTE CORONARY SYNDROME","points":[[246,302],[621,302],[621,330],[246,330]],"dt_score":1},{"transcription":"MILD CORONARY ARTERY DISEASE","points":[[245,366],[681,366],[681,391],[245,391]],"dt_score":1},{"transcription":"MEDICAL MANAGEMENT","points":[[246,426],[548,420],[551,446],[251,450]],"dt_score":1}]
1163
1446
  ```
1164
1447
 
1165
1448
  </details>
@@ -1385,11 +1668,11 @@ Output:
1385
1668
  "last_created_by": null
1386
1669
  }
1387
1670
  ],
1388
- "file_upload": "5b1e3483-example.jpg",
1671
+ "file_upload": "example.jpg",
1389
1672
  "drafts": [],
1390
1673
  "predictions": [],
1391
1674
  "data": {
1392
- "ocr": "http://localhost:8081/output/5b1e3483-example.jpg"
1675
+ "ocr": "http://localhost:8081/output/example.jpg"
1393
1676
  },
1394
1677
  "meta": {},
1395
1678
  "created_at": "2026-01-10T03:25:05.530Z",
@@ -1441,7 +1724,8 @@ commands:
1441
1724
  rm -rf ./output-label-studio
1442
1725
  ```
1443
1726
 
1444
- - When you did not specify an output directory (default: files are saved in the same directory as the source files):
1727
+ - When you did not specify an output directory (default: files are saved in the
1728
+ same directory as the source files):
1445
1729
 
1446
1730
  **For default output file names:**
1447
1731
 
@@ -1474,7 +1758,8 @@ commands:
1474
1758
  Remove-Item -Path ".\output-label-studio" -Recurse -Force
1475
1759
  ```
1476
1760
 
1477
- - When you did not specify an output directory (default: files are saved in the same directory as the source files):
1761
+ - When you did not specify an output directory (default: files are saved in the
1762
+ same directory as the source files):
1478
1763
 
1479
1764
  **For default output file names:**
1480
1765