label-studio-converter 1.3.1 → 1.5.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
  });
@@ -248,10 +248,11 @@ label-studio-converter --help
248
248
 
249
249
  ```
250
250
  USAGE
251
- label-studio-converter toLabelStudio [--outDir value] [--fileName value] [--backup] [--defaultLabelName value] [--toFullJson] [--createFilePerImage] [--createFileListForServing] [--fileListName value] [--baseServerUrl value] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--widthIncrement value] [--heightIncrement value] [--precision value] [--recursive] [--filePattern value] [--outputMode value] <args>...
252
- label-studio-converter toPPOCR [--outDir value] [--fileName value] [--backup] [--baseImageDir value] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--widthIncrement value] [--heightIncrement value] [--precision value] [--recursive] [--filePattern value] <args>...
253
- label-studio-converter enhance-labelstudio [--outDir value] [--fileName value] [--backup] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--widthIncrement value] [--heightIncrement value] [--precision value] [--recursive] [--filePattern value] [--outputMode value] <args>...
254
- label-studio-converter enhance-ppocr [--outDir value] [--fileName value] [--backup] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--widthIncrement value] [--heightIncrement value] [--precision value] [--recursive] [--filePattern value] <args>...
251
+ label-studio-converter toLabelStudio [--outDir value] [--fileName value] [--backup] [--recursive] [--filePattern value] [--copyImages] [--imageBaseDir value] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--useOrientedBox] [--widthIncrement value] [--heightIncrement value] [--adaptResize] [--adaptResizeThreshold value] [--adaptResizeMargin value] [--adaptResizeMinComponentSize value] [--adaptResizeMaxComponentSize value] [--adaptResizeOutlierPercentile value] [--adaptResizeMorphologySize value] [--adaptResizeMaxHorizontalExpansion value] [--adaptResizePaddingCheckWidth value] [--adaptResizeMinPaddingBrightness value] [--adaptResizeMinPaddingRatio value] [--adaptResizeUseAdaptiveThreshold] [--adaptResizeAdaptiveBlockSize value] [--precision value] [--defaultLabelName value] [--toFullJson] [--createFilePerImage] [--createFileListForServing] [--fileListName value] [--baseServerUrl value] [--outputMode value] <args>...
252
+ label-studio-converter toPPOCR [--outDir value] [--fileName value] [--backup] [--recursive] [--filePattern value] [--copyImages] [--imageBaseDir value] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--useOrientedBox] [--widthIncrement value] [--heightIncrement value] [--adaptResize] [--adaptResizeThreshold value] [--adaptResizeMargin value] [--adaptResizeMinComponentSize value] [--adaptResizeMaxComponentSize value] [--adaptResizeOutlierPercentile value] [--adaptResizeMorphologySize value] [--adaptResizeMaxHorizontalExpansion value] [--adaptResizePaddingCheckWidth value] [--adaptResizeMinPaddingBrightness value] [--adaptResizeMinPaddingRatio value] [--adaptResizeUseAdaptiveThreshold] [--adaptResizeAdaptiveBlockSize value] [--precision value] [--baseImageDir value] <args>...
253
+ label-studio-converter enhance-labelstudio [--outDir value] [--fileName value] [--backup] [--recursive] [--filePattern value] [--copyImages] [--imageBaseDir value] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--useOrientedBox] [--widthIncrement value] [--heightIncrement value] [--adaptResize] [--adaptResizeThreshold value] [--adaptResizeMargin value] [--adaptResizeMinComponentSize value] [--adaptResizeMaxComponentSize value] [--adaptResizeOutlierPercentile value] [--adaptResizeMorphologySize value] [--adaptResizeMaxHorizontalExpansion value] [--adaptResizePaddingCheckWidth value] [--adaptResizeMinPaddingBrightness value] [--adaptResizeMinPaddingRatio value] [--adaptResizeUseAdaptiveThreshold] [--adaptResizeAdaptiveBlockSize value] [--precision value] [--outputMode value] <args>...
254
+ label-studio-converter enhance-ppocr [--outDir value] [--fileName value] [--backup] [--recursive] [--filePattern value] [--copyImages] [--imageBaseDir value] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--useOrientedBox] [--widthIncrement value] [--heightIncrement value] [--adaptResize] [--adaptResizeThreshold value] [--adaptResizeMargin value] [--adaptResizeMinComponentSize value] [--adaptResizeMaxComponentSize value] [--adaptResizeOutlierPercentile value] [--adaptResizeMorphologySize value] [--adaptResizeMaxHorizontalExpansion value] [--adaptResizePaddingCheckWidth value] [--adaptResizeMinPaddingBrightness value] [--adaptResizeMinPaddingRatio value] [--adaptResizeUseAdaptiveThreshold] [--adaptResizeAdaptiveBlockSize value] [--precision value] <args>...
255
+ label-studio-converter label-studio-output-to-ppocr [--recursive] (--outDir value) [--fileName value] [--removeBaseImageDir value] <args>...
255
256
  label-studio-converter --help
256
257
  label-studio-converter --version
257
258
 
@@ -262,114 +263,652 @@ FLAGS
262
263
  -v --version Print version information and exit
263
264
 
264
265
  COMMANDS
265
- toLabelStudio Convert PPOCRLabel files to Label Studio format
266
- toPPOCR Convert Label Studio files to PPOCRLabel format
267
- enhance-labelstudio Enhance Label Studio files with sorting, normalization, and resizing
268
- enhance-ppocr Enhance PPOCRLabel files with sorting, normalization, and resizing
266
+ toLabelStudio Convert PPOCRLabel files to Label Studio format
267
+ toPPOCR Convert Label Studio files to PPOCRLabel format
268
+ enhance-labelstudio Enhance Label Studio files with sorting, normalization, and resizing
269
+ enhance-ppocr Enhance PPOCRLabel files with sorting, normalization, and resizing
270
+ label-studio-output-to-ppocr Convert Label Studio output files to PPOCRLabel format Enhance PPOCRLabel files with sorting, normalization, and resizing
269
271
  ```
270
272
 
271
- #### Command Options Reference
273
+ #### Command Flags Reference
274
+
275
+ ##### Flags Available for All Commands
276
+
277
+ **File I/O Flags:**
278
+
279
+ - `--outDir <path>`: Output directory path
280
+ - **Behavior**: Saves converted/enhanced files to specified directory
281
+ - **Default**: Same directory as input files
282
+ - **Example**: `--outDir ./output` saves all files to `./output/`
283
+
284
+ - `--fileName <name>`: Custom output filename
285
+ - **Behavior**: Renames output file (without extension for JSON, with
286
+ extension for txt)
287
+ - **Default**:
288
+ - toLabelStudio: `{source}_full.json` or `{source}_min.json`
289
+ - toPPOCR: `Label.txt`
290
+ - enhance commands: Same as input filename
291
+ - **Example**: `--fileName MyLabels.txt` creates `MyLabels.txt` instead of
292
+ `Label.txt`
293
+
294
+ - `--backup` / `--noBackup`: Create backup before overwriting
295
+ - **Behavior**: Copies existing file to `{filename}.backup` before overwriting
296
+ - **Default**: `false` (no backup)
297
+ - **Example**: `--backup` creates `Label.txt.backup` if `Label.txt` exists
298
+
299
+ - `--recursive` / `--noRecursive`: Search subdirectories
300
+ - **Behavior**: Processes files in all subdirectories recursively
301
+ - **Default**: `false` (current directory only)
302
+ - **Example**: `--recursive` processes `./data/train/Label.txt` and
303
+ `./data/test/Label.txt`
304
+
305
+ - `--filePattern <regex>`: Pattern to match input files
306
+ - **Behavior**: Only processes files matching regex pattern
307
+ - **Default**:
308
+ - PPOCRLabel commands: `.*\.txt$` (all .txt files)
309
+ - Label Studio commands: `.*\.json$` (all .json files)
310
+ - **Example**: `--filePattern "train_.*\.txt$"` only processes files starting
311
+ with `train_`
312
+
313
+ - `--copyImages` / `--noCopyImages`: Copy images when using --outDir
314
+ - **Behavior**: When --outDir is specified, automatically copies/moves images
315
+ to output directory alongside converted files
316
+ - **Default**: `true` (copy images)
317
+ - **Example**: `--noCopyImages` keeps images in original location, only copies
318
+ task files
319
+ - **Note**: Only applies to toLabelStudio and toPPOCR converters when --outDir
320
+ is used
321
+ - **Note**: Not available for `label-studio-output-to-ppocr` command since it
322
+ only processes Label Studio output files which have no image paths
323
+
324
+ - `--imageBaseDir <dir>`: Controls output directory structure when copying images
325
+ - **Behavior**: Determines how the directory structure is preserved when
326
+ copying images to output directory
327
+ - **Options**: `task-file` (relative to task file), `input-dir` (relative to
328
+ input directory)
329
+ - **Default**: `task-file`
330
+ - **Example**: `--imageBaseDir input-dir --copyImages` preserves full path
331
+ structure from input directory
332
+ - **Use case**: Control whether copied images maintain full path from input
333
+ directory or relative to task file
334
+ - **Note**: Only affects output when --copyImages is used with --outDir
335
+ - **Note**: Not available for `label-studio-output-to-ppocr` command since it
336
+ only processes Label Studio output files which have no image paths
337
+
338
+ **Enhancement Flags:**
339
+
340
+ - `--sortVertical <order>`: Vertical sorting order
341
+ - **Behavior**: Sorts bounding boxes by vertical position
342
+ - **Options**: `none`, `top-bottom`, `bottom-top`
343
+ - **Default**: `none` (no sorting)
344
+ - **Example**: `--sortVertical top-bottom` sorts boxes from top to bottom
345
+
346
+ - `--sortHorizontal <order>`: Horizontal sorting order
347
+ - **Behavior**: Sorts bounding boxes by horizontal position (applied after
348
+ vertical sort)
349
+ - **Options**: `none`, `ltr` (left-to-right), `rtl` (right-to-left)
350
+ - **Default**: `none` (no sorting)
351
+ - **Example**: `--sortHorizontal rtl` sorts boxes right-to-left (for vertical
352
+ text)
353
+
354
+ - `--normalizeShape <option>`: Shape normalization
355
+ - **Behavior**: Converts diamond/rotated shapes to axis-aligned rectangles
356
+ - **Options**: `none`, `rectangle`
357
+ - **Default**: `none` (preserve original shapes)
358
+ - **Example**: `--normalizeShape rectangle` converts all polygons to
359
+ rectangles
272
360
 
273
- ##### Common Options (All Commands)
361
+ - `--widthIncrement <pixels>`: Adjust box width
362
+ - **Behavior**: Adds pixels to box width (can be negative to shrink)
363
+ - **Default**: `0` (no change)
364
+ - **Example**: `--widthIncrement 5` expands boxes by 5px horizontally
365
+
366
+ - `--heightIncrement <pixels>`: Adjust box height
367
+ - **Behavior**: Adds pixels to box height (can be negative to shrink)
368
+ - **Default**: `0` (no change)
369
+ - **Example**: `--heightIncrement -3` shrinks boxes by 3px vertically
370
+
371
+ - `--precision <decimals>`: Coordinate precision
372
+ - **Behavior**: Number of decimal places for coordinates
373
+ - **Default**:
374
+ - toLabelStudio: `-1` (full precision, no rounding)
375
+ - toPPOCR: `0` (integers only)
376
+ - enhance-labelstudio: `-1` (full precision)
377
+ - enhance-ppocr: `0` (integers)
378
+ - **Example**: `--precision 2` rounds to 2 decimal places (e.g., 123.45)
379
+
380
+ **Adaptive Resize Flags (Advanced):**
381
+
382
+ - `--adaptResize` / `--noAdaptResize`: Enable intelligent box resizing
383
+ - **Behavior**: Uses image analysis to shrink oversized boxes to fit actual
384
+ text
385
+ - **Default**: `false` (disabled)
386
+ - **Use Case**: Sino-Nom OCR datasets with excessive padding
387
+ - **Example**: `--adaptResize` enables feature with default parameters
388
+
389
+ - `--adaptResizeThreshold <0-255>`: Grayscale threshold
390
+ - **Behavior**: Pixels ≥ threshold are considered text (white), < threshold
391
+ are background (black)
392
+ - **Default**: `128`
393
+ - **Example**: `--adaptResizeThreshold 140` for darker text on light
394
+ background
395
+
396
+ - `--adaptResizeMargin <pixels>`: Padding around detected content
397
+ - **Behavior**: Additional pixels added on all sides after detection
398
+ - **Default**: `5`
399
+ - **Example**: `--adaptResizeMargin 8` adds 8px padding
400
+
401
+ - `--adaptResizeMinComponentSize <pixels>`: Noise filter
402
+ - **Behavior**: Regions smaller than this are ignored (filters dirt dots)
403
+ - **Default**: `10`
404
+ - **Example**: `--adaptResizeMinComponentSize 15` filters more aggressively
405
+
406
+ - `--adaptResizeMaxComponentSize <pixels>`: Artifact filter
407
+ - **Behavior**: Regions larger than this are ignored (filters huge artifacts)
408
+ - **Default**: `100000`
409
+ - **Example**: `--adaptResizeMaxComponentSize 50000` for smaller characters
410
+
411
+ - `--adaptResizeOutlierPercentile <%>`: Outlier removal
412
+ - **Behavior**: Ignores this % of smallest and largest pixels when calculating
413
+ boundaries
414
+ - **Default**: `2` (ignore 2% on each end)
415
+ - **Example**: `--adaptResizeOutlierPercentile 3` for more aggressive outlier
416
+ removal
417
+
418
+ - `--adaptResizeMorphologySize <pixels>`: Stroke connection
419
+ - **Behavior**: Kernel size for connecting broken character strokes
420
+ - **Default**: `2`
421
+ - **Example**: `--adaptResizeMorphologySize 3` connects larger gaps
422
+
423
+ - `--adaptResizeMaxHorizontalExpansion <pixels>`: Column overlap prevention
424
+ - **Behavior**: Maximum pixels boxes can expand horizontally (CRITICAL for
425
+ vertical text)
426
+ - **Default**: `50`
427
+ - **Example**: `--adaptResizeMaxHorizontalExpansion 30` for closely-spaced columns
274
428
 
275
- These options are available for all commands:
429
+ ##### Flags Specific to toLabelStudio Command
276
430
 
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
431
+ - `--defaultLabelName <name>`: Default label for annotations
432
+ - **Behavior**: Label assigned to all text regions
433
+ - **Default**: `"Text"`
434
+ - **Example**: `--defaultLabelName "Handwriting"` labels all regions as
435
+ Handwriting
288
436
 
289
- ##### Enhancement Options (All Commands)
437
+ - `--toFullJson` / `--noToFullJson`: Output format
438
+ - **Behavior**: `true` = Full format (more metadata), `false` = Min format
439
+ (compact)
440
+ - **Default**: `true` (Full format)
441
+ - **Example**: `--noToFullJson` creates minimal format files
290
442
 
291
- These options control bounding box transformations:
443
+ - `--createFilePerImage` / `--noCreateFilePerImage`: File splitting
444
+ - **Behavior**: `true` = one JSON per image, `false` = all tasks in one file
445
+ - **Default**: `false` (single file)
446
+ - **Example**: `--createFilePerImage` creates `image1.json`, `image2.json`, etc.
292
447
 
293
- - **`--sortVertical <order>`**: Sort bounding boxes vertically
294
- - Options: `none` (default), `top-bottom`, `bottom-top`
295
- - Useful for organizing annotations by reading order
448
+ - `--createFileListForServing` / `--noCreateFileListForServing`: Generate file
449
+ list
450
+ - **Behavior**: Creates `files.txt` with image URLs for Label Studio import
451
+ - **Default**: `true` (create file list)
452
+ - **Example**: `--noCreateFileListForServing` skips file list creation
296
453
 
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)
454
+ - `--fileListName <name>`: File list filename
455
+ - **Behavior**: Name of the file containing image URLs for serving
456
+ - **Default**: `"files.txt"`
457
+ - **Example**: `--fileListName "images.txt"` creates `images.txt` instead
302
458
 
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
459
+ - `--baseServerUrl <url>`: Base URL for images
460
+ - **Behavior**: Prepended to image paths in output JSON (e.g., for local HTTP
461
+ server)
462
+ - **Default**: `"http://localhost:8081"`
463
+ - **Example**: `--baseServerUrl "http://192.168.1.100:8080"` for network access
307
464
 
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
465
+ - `--outputMode <mode>`: Annotation mode
466
+ - **Behavior**:
467
+ - `annotations` = editable ground truth annotations
468
+ - `predictions` = read-only pre-annotations
469
+ - **Default**: `"annotations"`
470
+ - **Example**: `--outputMode predictions` for model predictions import
354
471
 
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
472
+ ##### Flags Specific to toPPOCR Command
473
+
474
+ - `--baseImageDir <path>`: Image directory prefix
475
+ - **Behavior**: Prepended to image filenames in output `Label.txt`
476
+ - **Default**: Empty string (no prefix)
477
+ - **Example**: `--baseImageDir "images/ch"` writes `images/ch/example.jpg` in
478
+ Label.txt
479
+
480
+ ##### Flags Specific to enhance-labelstudio Command
481
+
482
+ - `--outputMode <mode>`: Same as toLabelStudio command
483
+ - See toLabelStudio flags section above
484
+
485
+ ##### Flags Specific to label-studio-output-to-ppocr Command
486
+
487
+ - `--removeBaseImageDir <dir>`: Remove base directory from image paths
488
+ - **Behavior**: Strips specified base directory from image paths in output
489
+ `Label.txt`
490
+ - **Default**: `"/data/local-files/?d="` (removes Label Studio's default local
491
+ file prefix)
492
+ - **Example**: `--removeBaseImageDir "data/"` converts `data/example.jpg` to
493
+ `example.jpg` in Label.txt
494
+
495
+ #### Image Path Resolution Logic
496
+
497
+ 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**.
498
+
499
+ > **New in v1.5.0**: The `--imageBaseDir` flag controls the output directory structure when copying images. It determines whether copied images maintain their path relative to the task file (`task-file`, default) or the input directory (`input-dir`).
500
+
501
+ ##### toLabelStudio: PPOCRLabel → Label Studio
502
+
503
+ **INPUT Resolution (Reading PPOCRLabel files):**
504
+
505
+ **Command Execution Context:**
506
+
507
+ - You run: `cd project && label-studio-converter toLabelStudio data/`
508
+ - Current working directory (CWD): `project/`
509
+ - Input parameter: `data/` (directory to search for Label.txt files)
510
+ - Converter finds: `project/data/Label.txt` (and other Label.txt files in subdirectories if --recursive)
511
+ - Task file being processed: `project/data/Label.txt`
512
+
513
+ **How Image Paths Are Read:**
514
+
515
+ 1. **What's in the Label.txt file**:
516
+ - Path format: `data/example.jpg` (PPOCRLabel standard: folder/filename)
517
+ - PPOCRLabel was opened on `data/` folder, so paths use `data/` prefix
518
+
519
+ 2. **How input resolver finds images**:
520
+ - Reads path from Label.txt: `data/example.jpg`
521
+ - Task file is at: `project/data/Label.txt`
522
+ - Task directory: `project/data/`
523
+ - Check if path starts with task folder name (`data/`):
524
+ - YES → resolve from parent: `dirname(project/data/) + data/example.jpg` = `project/data/example.jpg`
525
+ - NO → resolve from task dir: `project/data/ + example.jpg` = `project/data/example.jpg`
526
+
527
+ **OUTPUT Resolution (Copying images with --copyImages --outDir):**
528
+
529
+ **With `--imageBaseDir task-file` (default):**
530
+
531
+ When copying images to output directory, paths are maintained **relative to the task file location**:
532
+
533
+ - Input directory: `project/data/` (provided to command)
534
+ - Source image: `project/data/foo/bar/baz/example.jpg`
535
+ - Task file: `project/data/Label.txt`
536
+ - Output dir: `project/output/`
537
+ - Relative from task: `relative(project/data/, project/data/foo/bar/baz/example.jpg)` = `foo/bar/baz/example.jpg`
538
+ - Destination: `project/output/data/foo/bar/baz/example.jpg` (maintains structure relative to task file)
539
+
540
+ **With `--imageBaseDir input-dir`:**
541
+
542
+ When copying images to output directory, paths are maintained **relative to input directory**:
543
+
544
+ - Input directory: `project/data/` (provided to command)
545
+ - Source image: `project/data/foo/bar/baz/example.jpg`
546
+ - Output dir: `project/output/`
547
+ - Relative from input: `relative(project/data/, project/data/foo/bar/baz/example.jpg)` = `foo/bar/baz/example.jpg`
548
+ - Destination: `project/output/foo/bar/baz/example.jpg` (maintains path from input directory)
549
+ - Path relative to CWD: `data/example.jpg`
550
+ - (From input resolution step)
551
+
552
+ 2. **How output resolver formats paths**:
553
+ - No --outDir: Compute relative path from output JSON to image
554
+ - Output JSON at: `project/data/Label_full.json`
555
+ - Image at: `project/data/example.jpg`
556
+ - Relative path: `relative(project/data/, project/data/example.jpg)` = `example.jpg`
557
+ - Apply baseServerUrl: `http://localhost:8081/example.jpg`
558
+
559
+ 3. **What goes in the output file**:
560
+ - Label Studio JSON: `"ocr": "http://localhost:8081/example.jpg"`
561
+
562
+ **File Organization Examples:**
563
+
564
+ <details>
565
+ <summary><b>Example 1: Default Location (No --outDir)</b></summary>
566
+
567
+ **Setup**: Images and output in same place as task file
568
+
569
+ ```
570
+ project/
571
+ └── data/
572
+ ├── Label.txt # Contains: data/example.jpg [...]
573
+ └── example.jpg
574
+ ```
575
+
576
+ **Command:**
577
+
578
+ ```bash
579
+ cd project
580
+ label-studio-converter toLabelStudio data/
581
+ ```
582
+
583
+ **Result:**
584
+
585
+ ```
586
+ project/
587
+ └── data/
588
+ ├── Label.txt # Original task file
589
+ ├── Label_full.json # NEW: Generated output
590
+ ├── files.txt # NEW: File list for serving
591
+ └── example.jpg # Original image (unchanged)
592
+ ```
593
+
594
+ **Generated Label_full.json contains:**
595
+
596
+ ```json
597
+ {
598
+ "data": {
599
+ "ocr": "http://localhost:8081/example.jpg"
600
+ }
601
+ }
602
+ ```
603
+
604
+ **Image Path Flow:**
605
+
606
+ - Input path in Label.txt: `data/example.jpg`
607
+ - Resolved path: `data/example.jpg` (relative to CWD)
608
+ - Output saved in: `data/` (same as task)
609
+ - Relative to output: `example.jpg`
610
+ - Final URL: `http://localhost:8081/example.jpg`
611
+
612
+ </details>
613
+
614
+ <details>
615
+ <summary><b>Example 2: With --outDir Configuration</b></summary>
616
+
617
+ **Setup**: Separate output directory for organized export
618
+
619
+ ```
620
+ project/
621
+ ├── data/
622
+ │ ├── Label.txt # Contains: data/example.jpg [...]
623
+ │ └── example.jpg
624
+ └── output/ # Target output directory
625
+ ```
626
+
627
+ **Command:**
628
+
629
+ ```bash
630
+ cd project
631
+ label-studio-converter toLabelStudio data/ \
632
+ --outDir output \
633
+ --baseServerUrl http://localhost:8081
634
+ ```
635
+
636
+ **Result:**
637
+
638
+ ```
639
+ project/
640
+ ├── data/
641
+ │ ├── Label.txt # Original (unchanged)
642
+ │ └── example.jpg # Original (unchanged)
643
+ └── output/ # NEW: All outputs here
644
+ ├── Label_full.json # NEW: Generated tasks
645
+ ├── files.txt # NEW: File list
646
+ └── example.jpg # NEW: Copied from source
647
+ ```
648
+
649
+ **Generated Label_full.json contains:**
650
+
651
+ ```json
652
+ {
653
+ "data": {
654
+ "ocr": "http://localhost:8081/example.jpg"
655
+ }
656
+ }
657
+ ```
658
+
659
+ **Image Path Flow:**
660
+
661
+ - Input path in Label.txt: `data/example.jpg`
662
+ - Resolved path: `data/example.jpg` (relative to CWD)
663
+ - Copied to: `output/example.jpg`
664
+ - Relative to output: `example.jpg`
665
+ - Final URL: `http://localhost:8081/example.jpg`
666
+
667
+ </details>
668
+
669
+ ##### toPPOCR: Label Studio → PPOCRLabel
670
+
671
+ **INPUT Resolution (Reading Label Studio JSON):**
672
+
673
+ **Command Execution Context:**
674
+
675
+ - You run: `cd project && label-studio-converter toPPOCR data/`
676
+ - Current working directory (CWD): `project/`
677
+ - Input parameter: `data/` (directory to search for JSON files)
678
+ - Converter finds: `project/data/export.json` (and other JSON files in subdirectories if --recursive)
679
+ - Task file being processed: `project/data/export.json`
680
+
681
+ **How Image Paths Are Read:**
682
+
683
+ 1. **What's in the JSON file**:
684
+ - Local path: `"ocr": "/example.jpg"` or `"ocr": "example.jpg"`
685
+ - OR Remote URL: `"ocr": "http://localhost:8081/example.jpg"`
686
+
687
+ 2. **How input resolver finds/downloads images**:
688
+ - **Local path** (`/example.jpg` or `example.jpg`):
689
+ - Strip leading slashes: `/example.jpg` → `example.jpg`
690
+ - Task directory: `project/data/`
691
+ - Resolve: `project/data/ + example.jpg` = `project/data/example.jpg`
692
+ - **Remote URL** (`http://localhost:8081/example.jpg`):
693
+ - Extract filename: `basename(URL)` = `example.jpg`
694
+ - Download to task directory: `project/data/example.jpg`
695
+
696
+ **OUTPUT Resolution (Copying images with --copyImages --outDir):**
697
+
698
+ **With `--imageBaseDir task-file` (default):**
699
+
700
+ When copying images to output directory, paths are maintained **relative to the task file location**:
701
+
702
+ - Input directory: `project/data/` (provided to command)
703
+ - Source image: `project/data/foo/bar/baz/example.jpg`
704
+ - Task file: `project/data/export.json`
705
+ - Output dir: `project/output/`
706
+ - Relative from task: `relative(project/data/, project/data/foo/bar/baz/example.jpg)` = `foo/bar/baz/example.jpg`
707
+ - Destination: `project/output/data/foo/bar/baz/example.jpg` (maintains structure relative to task file)
708
+
709
+ **With `--imageBaseDir input-dir`:**
710
+
711
+ When copying images to output directory, paths are maintained **relative to input directory**:
712
+
713
+ - Input directory: `project/data/` (provided to command)
714
+ - Source image: `project/data/foo/bar/baz/example.jpg`
715
+ - Output dir: `project/output/`
716
+ - Relative from input: `relative(project/data/, project/data/foo/bar/baz/example.jpg)` = `foo/bar/baz/example.jpg`
717
+ - Destination: `project/output/foo/bar/baz/example.jpg` (maintains path from input directory)
718
+
719
+ **How Resolvers Work:**
720
+
721
+ 1. **What the processor has**:
722
+ - Path relative to CWD: `data/example.jpg`
723
+ - (From input resolution step)
724
+
725
+ 2. **How output resolver formats paths**:
726
+ - Extract filename: `basename(data/example.jpg)` = `example.jpg`
727
+ - Determine folder prefix:
728
+ - No --baseImageDir: Use output directory basename
729
+ - Output at: `project/data/Label.txt` → folder is `data`
730
+ - Result: `data/example.jpg`
731
+ - With --baseImageDir="images": Result would be `images/example.jpg`
732
+
733
+ 3. **What goes in the output file**:
734
+ - PPOCRLabel Label.txt: `data/example.jpg [{"transcription":"Text",...}]`
735
+ - **Important**: Path in Label.txt is a reference format, NOT the physical location
736
+ - Physical images stay in task directory (`data/`), but Label.txt uses folder prefix
737
+
738
+ **File Organization Examples:**
739
+
740
+ <details>
741
+ <summary><b>Example 1: Default Location (No --outDir)</b></summary>
742
+
743
+ **Setup**: Export Label.txt to same directory as task
744
+
745
+ ```
746
+ project/
747
+ └── data/
748
+ └── export.json # Contains: "ocr": "http://localhost:8081/example.jpg"
749
+ ```
750
+
751
+ **Command:**
752
+
753
+ ```bash
754
+ cd project
755
+ label-studio-converter toPPOCR data/ \
756
+ --baseImageDir data
757
+ ```
758
+
759
+ **Result:**
760
+
761
+ ```
762
+ project/
763
+ └── data/
764
+ ├── export.json # Original (unchanged)
765
+ ├── Label.txt # NEW: Generated PPOCR file
766
+ └── example.jpg # NEW: Downloaded from server
767
+ ```
768
+
769
+ **Generated Label.txt contains:**
770
+
771
+ ```
772
+ data/example.jpg [{"transcription":"Text","points":[[...]],"dt_score":1}]
773
+ ```
774
+
775
+ **Image Path Flow:**
776
+
777
+ - Input URL in JSON: `http://localhost:8081/example.jpg`
778
+ - **Downloaded to**: `data/example.jpg` (task file directory)
779
+ - Resolved path: `data/example.jpg` (relative to CWD)
780
+ - Extracted filename: `example.jpg`
781
+ - baseImageDir: `data`
782
+ - Output in Label.txt: `data/example.jpg`
783
+
784
+ </details>
785
+
786
+ <details>
787
+ <summary><b>Example 2: With --outDir Configuration</b></summary>
788
+
789
+ **Setup**: Organize output in separate directory
790
+
791
+ ```
792
+ project/
793
+ ├── data/
794
+ │ └── export.json # Contains: "ocr": "http://localhost:8081/example.jpg"
795
+ └── output/ # Target output directory
796
+ ```
797
+
798
+ **Command:**
799
+
800
+ ```bash
801
+ cd project
802
+ label-studio-converter toPPOCR data/ \
803
+ --outDir output
804
+ ```
805
+
806
+ **Result:**
807
+
808
+ ```
809
+ project/
810
+ ├── data/
811
+ │ ├── export.json # Original (unchanged)
812
+ │ └── example.jpg # Downloaded, then copied to output
813
+ └── output/
814
+ ├── Label.txt # NEW: Generated PPOCR file
815
+ └── example.jpg # NEW: Copied from data/
816
+ ```
817
+
818
+ **Generated Label.txt contains:**
819
+
820
+ ```
821
+ output/example.jpg [{"transcription":"Text","points":[[...]],"dt_score":1}]
822
+ ```
823
+
824
+ **Image Path Flow:**
825
+
826
+ - Input URL in JSON: `http://localhost:8081/example.jpg`
827
+ - **Downloaded to**: `data/example.jpg` (task file directory)
828
+ - **Copied to**: `output/example.jpg` (because --outDir specified)
829
+ - Resolved path: `data/example.jpg` (relative to CWD)
830
+ - Output dir: `output/`
831
+ - Extracted filename: `example.jpg`
832
+ - Output folder name: `output`
833
+ - Output in Label.txt: `output/example.jpg`
834
+
835
+ **Note**: Images are automatically copied to output directory. Use `--noCopyImages` to skip copying.
836
+
837
+ </details>
838
+
839
+ ##### enhance-labelstudio: Label Studio → Label Studio (Enhanced)
840
+
841
+ **INPUT Resolution**: Same as `toPPOCR` converter
842
+
843
+ - Reads Label Studio JSON files
844
+ - Resolves local paths relative to task file
845
+ - Downloads remote URLs to task file directory
846
+
847
+ **OUTPUT Resolution**: Same as `toLabelStudio` converter
848
+
849
+ - Generates Label Studio JSON with `data.ocr` URLs
850
+ - Applies `baseServerUrl` formatting
851
+ - Computes relative paths from output location to images
852
+
853
+ ##### enhance-ppocr: PPOCRLabel → PPOCRLabel (Enhanced)
854
+
855
+ **INPUT Resolution**: Same as `toLabelStudio` converter
856
+
857
+ - Reads PPOCRLabel Label.txt files
858
+ - Resolves paths with folder pattern (`folder/file.jpg`)
859
+ - Detects folder name and resolves from parent directory
860
+
861
+ **OUTPUT Resolution**: Same as `toPPOCR` converter
862
+
863
+ - Generates PPOCRLabel Label.txt with `folder/filename.jpg` format
864
+ - Uses `baseImageDir` or output directory basename as folder prefix
865
+ - Extracts filename from resolved path, prepends folder name
866
+
867
+ ##### label-studio-output-to-ppocr: Label Studio Output → PPOCRLabel
365
868
 
366
- ##### Error Handling
869
+ **INPUT Resolution**:
367
870
 
368
- The `toLabelStudio` command handles missing or unreadable image files gracefully:
871
+ - Reads Label Studio output JSON files
872
+ - Strips `removeBaseImageDir` prefix from image paths (e.g.,
873
+ `data/local-files/?d=example.jpg` → `example.jpg`)
369
874
 
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
875
+ **OUTPUT Resolution**:
876
+
877
+ - Generates PPOCRLabel Label.txt with `folder/filename.jpg` format
878
+
879
+ ---
880
+
881
+ **Key Concepts:**
882
+
883
+ 1. **Path Resolution Flow**:
884
+ - Input converters resolve paths to **task-relative paths** (relative to task file location)
885
+ - Processor receives and operates on these **task-relative paths**
886
+ - Output converters format these paths for the target system
887
+
888
+ 2. **Remote Image Handling**:
889
+ - URLs (`http://` or `https://`) are downloaded to **task file directory**
890
+ - Only filename is extracted from URL (path structure ignored)
891
+ - Example: `http://server.com/deep/path/example.jpg` → saved as `task-dir/example.jpg`
892
+
893
+ 3. **Image Organization** (toLabelStudio & toPPOCR):
894
+ - **No --outDir**: Output files created in task directory, images stay in place
895
+ - **With --outDir**: Output files go to outDir, **images automatically copied** to outDir (unless --noCopyImages)
896
+ - **--noCopyImages**: Skip image copying, only create task files in outDir
897
+ - **enhance commands**: Images always stay in original location
898
+
899
+ 4. **Output Path Format**:
900
+ - **toLabelStudio**: `${baseServerUrl}/${relativePath}` where relativePath is from output JSON to image
901
+ - **toPPOCR**: `${folder}/${filename}` where folder is `baseImageDir` or output directory name
902
+
903
+ #### Adaptive Resize Feature
904
+
905
+ For detailed algorithm documentation and tuning guide, see [ADAPTIVE_RESIZE.md](docs/ADAPTIVE_RESIZE.md).
906
+
907
+ **Quick Overview:**
908
+
909
+ - **Purpose**: Shrinks oversized boxes to fit actual text content (essential for Sino-Nom OCR with excessive padding)
910
+ - **Algorithm**: Morphological operations + connected component analysis + percentile-based outlier removal
911
+ - **Usage**: Enable with `--adaptResize` flag, tune with 7 parameters documented above
373
912
 
374
913
  #### Detailed Command Help
375
914
 
@@ -383,31 +922,47 @@ label-studio-converter toLabelStudio --help
383
922
 
384
923
  ```
385
924
  USAGE
386
- label-studio-converter toLabelStudio [--outDir value] [--fileName value] [--backup] [--defaultLabelName value] [--toFullJson] [--createFilePerImage] [--createFileListForServing] [--fileListName value] [--baseServerUrl value] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--widthIncrement value] [--heightIncrement value] [--precision value] [--recursive] [--filePattern value] [--outputMode value] <args>...
925
+ label-studio-converter toLabelStudio [--outDir value] [--fileName value] [--backup] [--recursive] [--filePattern value] [--copyImages] [--imageBaseDir value] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--useOrientedBox] [--widthIncrement value] [--heightIncrement value] [--adaptResize] [--adaptResizeThreshold value] [--adaptResizeMargin value] [--adaptResizeMinComponentSize value] [--adaptResizeMaxComponentSize value] [--adaptResizeOutlierPercentile value] [--adaptResizeMorphologySize value] [--adaptResizeMaxHorizontalExpansion value] [--adaptResizePaddingCheckWidth value] [--adaptResizeMinPaddingBrightness value] [--adaptResizeMinPaddingRatio value] [--adaptResizeUseAdaptiveThreshold] [--adaptResizeAdaptiveBlockSize value] [--precision value] [--defaultLabelName value] [--toFullJson] [--createFilePerImage] [--createFileListForServing] [--fileListName value] [--baseServerUrl value] [--outputMode value] <args>...
387
926
  label-studio-converter toLabelStudio --help
388
927
 
389
928
  Convert PPOCRLabel files to Label Studio format
390
929
 
391
930
  FLAGS
392
- [--outDir] Output directory. If not specified, files are saved in the same directory as the source files
393
- [--fileName] Custom output filename (without extension). If not specified, uses source filename with format suffix
394
- [--backup/--noBackup] Create backup of existing files before overwriting. Default: false
395
- [--defaultLabelName] Default label name for text annotations. Default: "Text"
396
- [--toFullJson/--noToFullJson] Convert to Full OCR Label Studio format. Default: "true"
397
- [--createFilePerImage/--noCreateFilePerImage] Create a separate Label Studio JSON file for each image. Default: "false"
398
- [--createFileListForServing/--noCreateFileListForServing] Create a file list for serving in Label Studio. Default: "true"
399
- [--fileListName] Name of the file list for serving. Default: "files.txt"
400
- [--baseServerUrl] Base server URL for constructing image URLs in the file list. Default: "http://localhost:8081"
401
- [--sortVertical] Sort bounding boxes vertically. Options: "none", "top-bottom", "bottom-top". Default: "none"
402
- [--sortHorizontal] Sort bounding boxes horizontally. Options: "none", "ltr", "rtl". Default: "none"
403
- [--normalizeShape] Normalize diamond-like shapes to axis-aligned rectangles. Options: "none", "rectangle". Default: "none"
404
- [--widthIncrement] Increase bounding box width by this amount (in pixels). Can be negative to decrease. Default: 0
405
- [--heightIncrement] Increase bounding box height by this amount (in pixels). Can be negative to decrease. Default: 0
406
- [--precision] Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: -1
407
- [--recursive/--noRecursive] Recursively search directories for files. Default: false
408
- [--filePattern] Regex pattern to match PPOCRLabel files (should match .txt files). Default: ".*\.txt$"
409
- [--outputMode] Output mode: "annotations" for editable annotations (ground truth) or "predictions" for read-only predictions (pre-annotations). Default: "annotations"
410
- -h --help Print help information and exit
931
+ [--outDir] Output directory. If not specified, files are saved in the same directory as the source files
932
+ [--fileName] Custom output filename (without extension). If not specified, uses source filename with format suffix
933
+ [--backup/--noBackup] Create backup of existing files before overwriting. Default: false
934
+ [--recursive/--noRecursive] Recursively search directories for files. Default: false
935
+ [--filePattern] Regex pattern to match PPOCRLabel files (should match .txt files). Default: ".*\.txt$"
936
+ [--copyImages/--noCopyImages] Copy images to output directory when --outDir is specified. Only applies to toLabelStudio and toPPOCR commands. Default: true
937
+ [--imageBaseDir] Base directory for resolving image paths. Options: "task-file" (relative to task file location), "input-dir" (relative to command execution directory). Default: "task-file"
938
+ [--sortVertical] Sort bounding boxes vertically. Options: "none", "top-bottom", "bottom-top". Default: "none"
939
+ [--sortHorizontal] Sort bounding boxes horizontally. Options: "none", "ltr", "rtl". Default: "none"
940
+ [--normalizeShape] Normalize diamond-like shapes to axis-aligned rectangles. Options: "none", "rectangle". Default: "none"
941
+ [--useOrientedBox/--noUseOrientedBox] Use oriented (rotated) bounding box when normalizing shapes. Useful for skewed text. Default: false
942
+ [--widthIncrement] Increase bounding box width by this amount (in pixels). Can be negative to decrease. Default: 0
943
+ [--heightIncrement] Increase bounding box height by this amount (in pixels). Can be negative to decrease. Default: 0
944
+ [--adaptResize/--noAdaptResize] Apply adaptive resize to automatically adjust bounding boxes based on image content. Default: false
945
+ [--adaptResizeThreshold] Grayscale threshold for adaptive resize (0-255). Default: 128
946
+ [--adaptResizeMargin] Margin pixels around detected content for adaptive resize. Default: 5
947
+ [--adaptResizeMinComponentSize] Minimum component size in pixels (filters dirt/noise). Default: 10
948
+ [--adaptResizeMaxComponentSize] Maximum component size in pixels (filters large artifacts). Default: 100000
949
+ [--adaptResizeOutlierPercentile] Percentile for outlier removal (0-100). Default: 2
950
+ [--adaptResizeMorphologySize] Morphological operation kernel size. Default: 2
951
+ [--adaptResizeMaxHorizontalExpansion] Maximum horizontal expansion in pixels (prevents column overlap). Default: 50
952
+ [--adaptResizePaddingCheckWidth] Width of padding strip to validate (in pixels). Default: 3
953
+ [--adaptResizeMinPaddingBrightness] Minimum brightness for white padding pixels (0-255). Default: 200
954
+ [--adaptResizeMinPaddingRatio] Minimum ratio of white pixels in padding strip (0-1). Default: 0.85
955
+ [--adaptResizeUseAdaptiveThreshold/--noAdaptResizeUseAdaptiveThreshold] Use adaptive thresholding based on image histogram (recommended). Default: true
956
+ [--adaptResizeAdaptiveBlockSize] Block size for adaptive thresholding. Default: 50
957
+ [--precision] Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: 0 (integers)
958
+ [--defaultLabelName] Default label name for text annotations. Default: "Text"
959
+ [--toFullJson/--noToFullJson] Convert to Full OCR Label Studio format. Default: "true"
960
+ [--createFilePerImage/--noCreateFilePerImage] Create a separate Label Studio JSON file for each image. Default: "false"
961
+ [--createFileListForServing/--noCreateFileListForServing] Create a file list for serving in Label Studio. Default: "true"
962
+ [--fileListName] Name of the file list for serving. Default: "files.txt"
963
+ [--baseServerUrl] Base server URL for constructing image URLs in the file list. Default: "http://localhost:8081"
964
+ [--outputMode] Output mode: "annotations" for editable annotations (ground truth) or "predictions" for read-only predictions (pre-annotations). Default: "annotations"
965
+ -h --help Print help information and exit
411
966
 
412
967
  ARGUMENTS
413
968
  args... Input directories containing PPOCRLabel files
@@ -423,25 +978,41 @@ label-studio-converter toPPOCR --help
423
978
 
424
979
  ```
425
980
  USAGE
426
- label-studio-converter toPPOCR [--outDir value] [--fileName value] [--backup] [--baseImageDir value] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--widthIncrement value] [--heightIncrement value] [--precision value] [--recursive] [--filePattern value] <args>...
981
+ label-studio-converter toPPOCR [--outDir value] [--fileName value] [--backup] [--recursive] [--filePattern value] [--copyImages] [--imageBaseDir value] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--useOrientedBox] [--widthIncrement value] [--heightIncrement value] [--adaptResize] [--adaptResizeThreshold value] [--adaptResizeMargin value] [--adaptResizeMinComponentSize value] [--adaptResizeMaxComponentSize value] [--adaptResizeOutlierPercentile value] [--adaptResizeMorphologySize value] [--adaptResizeMaxHorizontalExpansion value] [--adaptResizePaddingCheckWidth value] [--adaptResizeMinPaddingBrightness value] [--adaptResizeMinPaddingRatio value] [--adaptResizeUseAdaptiveThreshold] [--adaptResizeAdaptiveBlockSize value] [--precision value] [--baseImageDir value] <args>...
427
982
  label-studio-converter toPPOCR --help
428
983
 
429
984
  Convert Label Studio files to PPOCRLabel format
430
985
 
431
986
  FLAGS
432
- [--outDir] Output directory. If not specified, files are saved in the same directory as the source files
433
- [--fileName] Output PPOCR file name. Default: "Label.txt"
434
- [--backup/--noBackup] Create backup of existing files before overwriting. Default: false
435
- [--baseImageDir] Base directory path to prepend to image filenames in output (e.g., "ch" or "images/ch")
436
- [--sortVertical] Sort bounding boxes vertically. Options: "none", "top-bottom", "bottom-top". Default: "none"
437
- [--sortHorizontal] Sort bounding boxes horizontally. Options: "none", "ltr", "rtl". Default: "none"
438
- [--normalizeShape] Normalize diamond-like shapes to axis-aligned rectangles. Options: "none", "rectangle". Default: "none"
439
- [--widthIncrement] Increase bounding box width by this amount (in pixels). Can be negative to decrease. Default: 0
440
- [--heightIncrement] Increase bounding box height by this amount (in pixels). Can be negative to decrease. Default: 0
441
- [--precision] Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: 0 (integers)
442
- [--recursive/--noRecursive] Recursively search directories for files. Default: false
443
- [--filePattern] Regex pattern to match Label Studio files (should match .json files). Default: ".*\.json$"
444
- -h --help Print help information and exit
987
+ [--outDir] Output directory. If not specified, files are saved in the same directory as the source files
988
+ [--fileName] Output PPOCR file name. Default: "Label.txt"
989
+ [--backup/--noBackup] Create backup of existing files before overwriting. Default: false
990
+ [--recursive/--noRecursive] Recursively search directories for files. Default: false
991
+ [--filePattern] Regex pattern to match Label Studio files (should match .json files). Default: ".*\.json$"
992
+ [--copyImages/--noCopyImages] Copy images to output directory when --outDir is specified. Only applies to toLabelStudio and toPPOCR commands. Default: true
993
+ [--imageBaseDir] Base directory for resolving image paths. Options: "task-file" (relative to task file location), "input-dir" (relative to command execution directory). Default: "task-file"
994
+ [--sortVertical] Sort bounding boxes vertically. Options: "none", "top-bottom", "bottom-top". Default: "none"
995
+ [--sortHorizontal] Sort bounding boxes horizontally. Options: "none", "ltr", "rtl". Default: "none"
996
+ [--normalizeShape] Normalize diamond-like shapes to axis-aligned rectangles. Options: "none", "rectangle". Default: "none"
997
+ [--useOrientedBox/--noUseOrientedBox] Use oriented (rotated) bounding box when normalizing shapes. Useful for skewed text. Default: false
998
+ [--widthIncrement] Increase bounding box width by this amount (in pixels). Can be negative to decrease. Default: 0
999
+ [--heightIncrement] Increase bounding box height by this amount (in pixels). Can be negative to decrease. Default: 0
1000
+ [--adaptResize/--noAdaptResize] Apply adaptive resize to automatically adjust bounding boxes based on image content. Default: false
1001
+ [--adaptResizeThreshold] Grayscale threshold for adaptive resize (0-255). Default: 128
1002
+ [--adaptResizeMargin] Margin pixels around detected content for adaptive resize. Default: 5
1003
+ [--adaptResizeMinComponentSize] Minimum component size in pixels (filters dirt/noise). Default: 10
1004
+ [--adaptResizeMaxComponentSize] Maximum component size in pixels (filters large artifacts). Default: 100000
1005
+ [--adaptResizeOutlierPercentile] Percentile for outlier removal (0-100). Default: 2
1006
+ [--adaptResizeMorphologySize] Morphological operation kernel size. Default: 2
1007
+ [--adaptResizeMaxHorizontalExpansion] Maximum horizontal expansion in pixels (prevents column overlap). Default: 50
1008
+ [--adaptResizePaddingCheckWidth] Width of padding strip to validate (in pixels). Default: 3
1009
+ [--adaptResizeMinPaddingBrightness] Minimum brightness for white padding pixels (0-255). Default: 200
1010
+ [--adaptResizeMinPaddingRatio] Minimum ratio of white pixels in padding strip (0-1). Default: 0.85
1011
+ [--adaptResizeUseAdaptiveThreshold/--noAdaptResizeUseAdaptiveThreshold] Use adaptive thresholding based on image histogram (recommended). Default: true
1012
+ [--adaptResizeAdaptiveBlockSize] Block size for adaptive thresholding. Default: 50
1013
+ [--precision] Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: 0 (integers)
1014
+ [--baseImageDir] Base directory path to prepend to image filenames in output (e.g., "ch" or "images/ch")
1015
+ -h --help Print help information and exit
445
1016
 
446
1017
  ARGUMENTS
447
1018
  args... Input directories containing Label Studio files
@@ -457,25 +1028,41 @@ label-studio-converter enhance-labelstudio --help
457
1028
 
458
1029
  ```
459
1030
  USAGE
460
- label-studio-converter enhance-labelstudio [--outDir value] [--fileName value] [--backup] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--widthIncrement value] [--heightIncrement value] [--precision value] [--recursive] [--filePattern value] [--outputMode value] <args>...
1031
+ label-studio-converter enhance-labelstudio [--outDir value] [--fileName value] [--backup] [--recursive] [--filePattern value] [--copyImages] [--imageBaseDir value] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--useOrientedBox] [--widthIncrement value] [--heightIncrement value] [--adaptResize] [--adaptResizeThreshold value] [--adaptResizeMargin value] [--adaptResizeMinComponentSize value] [--adaptResizeMaxComponentSize value] [--adaptResizeOutlierPercentile value] [--adaptResizeMorphologySize value] [--adaptResizeMaxHorizontalExpansion value] [--adaptResizePaddingCheckWidth value] [--adaptResizeMinPaddingBrightness value] [--adaptResizeMinPaddingRatio value] [--adaptResizeUseAdaptiveThreshold] [--adaptResizeAdaptiveBlockSize value] [--precision value] [--outputMode value] <args>...
461
1032
  label-studio-converter enhance-labelstudio --help
462
1033
 
463
1034
  Enhance Label Studio files with sorting, normalization, and resizing
464
1035
 
465
1036
  FLAGS
466
- [--outDir] Output directory. If not specified, files are saved in the same directory as the source files
467
- [--fileName] Custom output filename. If not specified, uses the same name as the source file
468
- [--backup/--noBackup] Create backup of existing files before overwriting. Default: false
469
- [--sortVertical] Sort bounding boxes vertically. Options: "none", "top-bottom", "bottom-top". Default: "none"
470
- [--sortHorizontal] Sort bounding boxes horizontally. Options: "none", "ltr", "rtl". Default: "none"
471
- [--normalizeShape] Normalize diamond-like shapes to axis-aligned rectangles. Options: "none", "rectangle". Default: "none"
472
- [--widthIncrement] Increase bounding box width by this amount (in pixels). Can be negative to decrease. Default: 0
473
- [--heightIncrement] Increase bounding box height by this amount (in pixels). Can be negative to decrease. Default: 0
474
- [--precision] Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: -1
475
- [--recursive/--noRecursive] Recursively search directories for files. Default: false
476
- [--filePattern] Regex pattern to match Label Studio files (should match .json files). Default: ".*\.json$"
477
- [--outputMode] Output mode: "annotations" for editable annotations (ground truth) or "predictions" for read-only predictions (pre-annotations). Default: "annotations"
478
- -h --help Print help information and exit
1037
+ [--outDir] Output directory. If not specified, files are saved in the same directory as the source files
1038
+ [--fileName] Custom output filename. If not specified, uses the same name as the source file
1039
+ [--backup/--noBackup] Create backup of existing files before overwriting. Default: false
1040
+ [--recursive/--noRecursive] Recursively search directories for files. Default: false
1041
+ [--filePattern] Regex pattern to match Label Studio files (should match .json files). Default: ".*\.json$"
1042
+ [--copyImages/--noCopyImages] Copy images to output directory when --outDir is specified. Only applies to toLabelStudio and toPPOCR commands. Default: true
1043
+ [--imageBaseDir] Base directory for resolving image paths. Options: "task-file" (relative to task file location), "input-dir" (relative to command execution directory). Default: "task-file"
1044
+ [--sortVertical] Sort bounding boxes vertically. Options: "none", "top-bottom", "bottom-top". Default: "none"
1045
+ [--sortHorizontal] Sort bounding boxes horizontally. Options: "none", "ltr", "rtl". Default: "none"
1046
+ [--normalizeShape] Normalize diamond-like shapes to axis-aligned rectangles. Options: "none", "rectangle". Default: "none"
1047
+ [--useOrientedBox/--noUseOrientedBox] Use oriented (rotated) bounding box when normalizing shapes. Useful for skewed text. Default: false
1048
+ [--widthIncrement] Increase bounding box width by this amount (in pixels). Can be negative to decrease. Default: 0
1049
+ [--heightIncrement] Increase bounding box height by this amount (in pixels). Can be negative to decrease. Default: 0
1050
+ [--adaptResize/--noAdaptResize] Apply adaptive resize to automatically adjust bounding boxes based on image content. Default: false
1051
+ [--adaptResizeThreshold] Grayscale threshold for adaptive resize (0-255). Default: 128
1052
+ [--adaptResizeMargin] Margin pixels around detected content for adaptive resize. Default: 5
1053
+ [--adaptResizeMinComponentSize] Minimum component size in pixels (filters dirt/noise). Default: 10
1054
+ [--adaptResizeMaxComponentSize] Maximum component size in pixels (filters large artifacts). Default: 100000
1055
+ [--adaptResizeOutlierPercentile] Percentile for outlier removal (0-100). Default: 2
1056
+ [--adaptResizeMorphologySize] Morphological operation kernel size. Default: 2
1057
+ [--adaptResizeMaxHorizontalExpansion] Maximum horizontal expansion in pixels (prevents column overlap). Default: 50
1058
+ [--adaptResizePaddingCheckWidth] Width of padding strip to validate (in pixels). Default: 3
1059
+ [--adaptResizeMinPaddingBrightness] Minimum brightness for white padding pixels (0-255). Default: 200
1060
+ [--adaptResizeMinPaddingRatio] Minimum ratio of white pixels in padding strip (0-1). Default: 0.85
1061
+ [--adaptResizeUseAdaptiveThreshold/--noAdaptResizeUseAdaptiveThreshold] Use adaptive thresholding based on image histogram (recommended). Default: true
1062
+ [--adaptResizeAdaptiveBlockSize] Block size for adaptive thresholding. Default: 50
1063
+ [--precision] Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: 0 (integers)
1064
+ [--outputMode] Output mode: "annotations" for editable annotations (ground truth) or "predictions" for read-only predictions (pre-annotations). Default: "annotations"
1065
+ -h --help Print help information and exit
479
1066
 
480
1067
  ARGUMENTS
481
1068
  args... Input directories containing Label Studio JSON files
@@ -491,246 +1078,180 @@ label-studio-converter enhance-ppocr --help
491
1078
 
492
1079
  ```
493
1080
  USAGE
494
- label-studio-converter enhance-ppocr [--outDir value] [--fileName value] [--backup] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--widthIncrement value] [--heightIncrement value] [--precision value] [--recursive] [--filePattern value] <args>...
1081
+ label-studio-converter enhance-ppocr [--outDir value] [--fileName value] [--backup] [--recursive] [--filePattern value] [--copyImages] [--imageBaseDir value] [--sortVertical value] [--sortHorizontal value] [--normalizeShape value] [--useOrientedBox] [--widthIncrement value] [--heightIncrement value] [--adaptResize] [--adaptResizeThreshold value] [--adaptResizeMargin value] [--adaptResizeMinComponentSize value] [--adaptResizeMaxComponentSize value] [--adaptResizeOutlierPercentile value] [--adaptResizeMorphologySize value] [--adaptResizeMaxHorizontalExpansion value] [--adaptResizePaddingCheckWidth value] [--adaptResizeMinPaddingBrightness value] [--adaptResizeMinPaddingRatio value] [--adaptResizeUseAdaptiveThreshold] [--adaptResizeAdaptiveBlockSize value] [--precision value] <args>...
495
1082
  label-studio-converter enhance-ppocr --help
496
1083
 
497
1084
  Enhance PPOCRLabel files with sorting, normalization, and resizing
498
1085
 
499
1086
  FLAGS
500
- [--outDir] Output directory. If not specified, files are saved in the same directory as the source files
501
- [--fileName] Custom output filename. If not specified, uses the same name as the source file
502
- [--backup/--noBackup] Create backup of existing files before overwriting. Default: false
503
- [--sortVertical] Sort bounding boxes vertically. Options: "none", "top-bottom", "bottom-top". Default: "none"
504
- [--sortHorizontal] Sort bounding boxes horizontally. Options: "none", "ltr", "rtl". Default: "none"
505
- [--normalizeShape] Normalize diamond-like shapes to axis-aligned rectangles. Options: "none", "rectangle". Default: "none"
506
- [--widthIncrement] Increase bounding box width by this amount (in pixels). Can be negative to decrease. Default: 0
507
- [--heightIncrement] Increase bounding box height by this amount (in pixels). Can be negative to decrease. Default: 0
508
- [--precision] Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: 0 (integers)
509
- [--recursive/--noRecursive] Recursively search directories for files. Default: false
510
- [--filePattern] Regex pattern to match PPOCRLabel files (should match .txt files). Default: ".*\.txt$"
511
- -h --help Print help information and exit
1087
+ [--outDir] Output directory. If not specified, files are saved in the same directory as the source files
1088
+ [--fileName] Custom output filename. If not specified, uses the same name as the source file
1089
+ [--backup/--noBackup] Create backup of existing files before overwriting. Default: false
1090
+ [--recursive/--noRecursive] Recursively search directories for files. Default: false
1091
+ [--filePattern] Regex pattern to match PPOCRLabel files (should match .txt files). Default: ".*\.txt$"
1092
+ [--copyImages/--noCopyImages] Copy images to output directory when --outDir is specified. Only applies to toLabelStudio and toPPOCR commands. Default: true
1093
+ [--imageBaseDir] Base directory for resolving image paths. Options: "task-file" (relative to task file location), "input-dir" (relative to command execution directory). Default: "task-file"
1094
+ [--sortVertical] Sort bounding boxes vertically. Options: "none", "top-bottom", "bottom-top". Default: "none"
1095
+ [--sortHorizontal] Sort bounding boxes horizontally. Options: "none", "ltr", "rtl". Default: "none"
1096
+ [--normalizeShape] Normalize diamond-like shapes to axis-aligned rectangles. Options: "none", "rectangle". Default: "none"
1097
+ [--useOrientedBox/--noUseOrientedBox] Use oriented (rotated) bounding box when normalizing shapes. Useful for skewed text. Default: false
1098
+ [--widthIncrement] Increase bounding box width by this amount (in pixels). Can be negative to decrease. Default: 0
1099
+ [--heightIncrement] Increase bounding box height by this amount (in pixels). Can be negative to decrease. Default: 0
1100
+ [--adaptResize/--noAdaptResize] Apply adaptive resize to automatically adjust bounding boxes based on image content. Default: false
1101
+ [--adaptResizeThreshold] Grayscale threshold for adaptive resize (0-255). Default: 128
1102
+ [--adaptResizeMargin] Margin pixels around detected content for adaptive resize. Default: 5
1103
+ [--adaptResizeMinComponentSize] Minimum component size in pixels (filters dirt/noise). Default: 10
1104
+ [--adaptResizeMaxComponentSize] Maximum component size in pixels (filters large artifacts). Default: 100000
1105
+ [--adaptResizeOutlierPercentile] Percentile for outlier removal (0-100). Default: 2
1106
+ [--adaptResizeMorphologySize] Morphological operation kernel size. Default: 2
1107
+ [--adaptResizeMaxHorizontalExpansion] Maximum horizontal expansion in pixels (prevents column overlap). Default: 50
1108
+ [--adaptResizePaddingCheckWidth] Width of padding strip to validate (in pixels). Default: 3
1109
+ [--adaptResizeMinPaddingBrightness] Minimum brightness for white padding pixels (0-255). Default: 200
1110
+ [--adaptResizeMinPaddingRatio] Minimum ratio of white pixels in padding strip (0-1). Default: 0.85
1111
+ [--adaptResizeUseAdaptiveThreshold/--noAdaptResizeUseAdaptiveThreshold] Use adaptive thresholding based on image histogram (recommended). Default: true
1112
+ [--adaptResizeAdaptiveBlockSize] Block size for adaptive thresholding. Default: 50
1113
+ [--precision] Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: 0 (integers)
1114
+ -h --help Print help information and exit
512
1115
 
513
1116
  ARGUMENTS
514
1117
  args... Input directories containing PPOCRLabel files
515
1118
  ```
516
1119
 
517
- #### Examples
518
-
519
- ##### Basic Conversion Examples
1120
+ ##### label-studio-output-to-ppocr Command
520
1121
 
521
1122
  ```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
1123
+ label-studio-converter label-studio-output-to-ppocr --help
533
1124
  ```
534
1125
 
535
- > [!NOTE]
536
- > By default, all PPOCRLabel positions are treated as **polygons** in Label Studio.
537
-
538
- ##### toLabelStudio Examples
539
-
540
- ```bash
541
- # Create separate JSON file for each image
542
- label-studio-converter toLabelStudio ./input-ppocr \
543
- --outDir ./output \
544
- --createFilePerImage
545
-
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
555
-
556
- # Disable file list creation for serving
557
- label-studio-converter toLabelStudio ./input-ppocr \
558
- --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 \
565
- --baseServerUrl http://192.168.1.100:8080
566
-
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
1126
+ **Output:**
572
1127
 
573
- # Convert to annotations format (default, editable ground truth)
574
- label-studio-converter toLabelStudio ./input-ppocr \
575
- --outDir ./output \
576
- --outputMode annotations
577
1128
  ```
1129
+ USAGE
1130
+ label-studio-converter label-studio-output-to-ppocr [--recursive] [--backup] [--filePattern value] (--outDir value) [--fileName value] [--removeBaseImageDir value] <args>...
1131
+ label-studio-converter label-studio-output-to-ppocr --help
578
1132
 
579
- ##### toPPOCR Examples
1133
+ Convert Label Studio output files to PPOCRLabel format
580
1134
 
581
- ```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
1135
+ FLAGS
1136
+ [--recursive/--noRecursive] Recursively search directories for files. Default: false
1137
+ [--backup/--noBackup] Create backup of existing files before overwriting. Default: false
1138
+ [--filePattern] Regex pattern to match input files
1139
+ --outDir Output directory.
1140
+ [--fileName] Output PPOCR file name. Default: "Label.txt"
1141
+ [--removeBaseImageDir] Remove base image directory from image paths in output. Default: "/data/local-files/?d="
1142
+ -h --help Print help information and exit
590
1143
 
591
- # Add base image directory to paths
592
- label-studio-converter toPPOCR ./input-label-studio \
593
- --outDir ./output \
594
- --baseImageDir dataset/images
1144
+ ARGUMENTS
1145
+ args... Input directories containing Label Studio files
595
1146
  ```
596
1147
 
597
- ##### Recursive Search and Pattern Matching Examples
1148
+ #### Examples
1149
+
1150
+ ##### Basic Conversion
598
1151
 
599
1152
  ```bash
600
- # Recursively search all subdirectories for .txt files
601
- label-studio-converter toLabelStudio ./data --recursive
1153
+ # PPOCRLabel Label Studio
1154
+ label-studio-converter toLabelStudio ./input-ppocr --outDir ./output
602
1155
 
603
- # Search with custom pattern (only files starting with "Label")
604
- label-studio-converter toLabelStudio ./data \
605
- --recursive \
606
- --filePattern "Label.*\.txt$"
1156
+ # Label Studio PPOCRLabel
1157
+ label-studio-converter toPPOCR ./input-label-studio --outDir ./output --baseImageDir images/ch
607
1158
 
608
- # Convert only specific JSON files (e.g., final annotations)
609
- label-studio-converter toPPOCR ./annotations \
610
- --recursive \
611
- --filePattern ".*_final\.json$"
1159
+ # File-per-image + custom server URL
1160
+ label-studio-converter toLabelStudio ./input-ppocr \
1161
+ --outDir ./output \
1162
+ --createFilePerImage \
1163
+ --baseServerUrl http://192.168.1.100:8080
612
1164
 
613
- # Enhance only specific files matching pattern
614
- label-studio-converter enhance-ppocr ./dataset \
615
- --recursive \
616
- --filePattern "train_.*\.txt$"
1165
+ # Predictions format (read-only pre-annotations)
1166
+ label-studio-converter toLabelStudio ./input-ppocr --outputMode predictions
617
1167
  ```
618
1168
 
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:**
1169
+ ##### Enhancement Pipeline
633
1170
 
634
1171
  ```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
1172
+ # Sort + normalize + resize
642
1173
  label-studio-converter enhance-ppocr ./data \
643
1174
  --sortVertical top-bottom \
644
1175
  --sortHorizontal ltr \
645
1176
  --normalizeShape rectangle \
646
1177
  --widthIncrement 5 \
647
- --heightIncrement 5 \
648
- --precision 0
649
- ```
1178
+ --heightIncrement 5
650
1179
 
651
- **Enhance Label Studio files:**
1180
+ # Adaptive resize for Sino-Nom OCR (shrinks oversized boxes)
1181
+ label-studio-converter enhance-ppocr ./sinonom-data \
1182
+ --adaptResize \
1183
+ --adaptResizeThreshold 128 \
1184
+ --adaptResizeMargin 8 \
1185
+ --adaptResizeMaxHorizontalExpansion 50 \
1186
+ --sortHorizontal rtl
652
1187
 
653
- ```bash
654
- # Sort and normalize Label Studio annotations
655
- label-studio-converter enhance-labelstudio ./data \
656
- --sortVertical top-bottom \
1188
+ # Convert with full enhancement pipeline
1189
+ label-studio-converter toLabelStudio ./input-ppocr \
1190
+ --outDir ./output \
657
1191
  --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
1192
+ --adaptResize \
1193
+ --sortVertical top-bottom
662
1194
  ```
663
1195
 
664
- **Conversion with enhancements:**
1196
+ ##### File Organization
665
1197
 
666
1198
  ```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
1199
+ # Recursive search with pattern matching
1200
+ label-studio-converter toLabelStudio ./dataset \
1201
+ --recursive \
1202
+ --filePattern "train_.*\.txt$"
673
1203
 
674
- label-studio-converter toPPOCR ./input-label-studio \
1204
+ # Custom output filenames
1205
+ label-studio-converter toPPOCR ./data \
675
1206
  --outDir ./output \
676
- --sortVertical top-bottom \
677
- --sortHorizontal ltr \
678
- --normalizeShape rectangle
1207
+ --fileName MyLabels.txt
1208
+
1209
+ # Using imageBaseDir for flexible path resolution
1210
+ # Default: resolve from task file location
1211
+ label-studio-converter toLabelStudio ./annotations/
1212
+
1213
+ # Copy images maintaining full directory structure from execution directory
1214
+ label-studio-converter toLabelStudio ./annotations/ \
1215
+ --copyImages \
1216
+ --imageBaseDir input-dir \
1217
+ --outDir ./output
679
1218
  ```
680
1219
 
681
- ##### Shape Normalization Examples
1220
+ ##### Shape Normalization
682
1221
 
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:
1222
+ Diamond/rotated shapes axis-aligned rectangles:
686
1223
 
687
1224
  ```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
1225
+ label-studio-converter enhance-ppocr ./data \
1226
+ --normalizeShape rectangle \
1227
+ --outDir ./normalized
693
1228
  ```
694
1229
 
695
1230
  <details>
696
- <summary>
697
- <b>Before normalization</b> (diamond-like shapes):
698
- </summary>
1231
+ <summary>Visual comparison</summary>
699
1232
 
700
- ![Before normalization](./docs/images/label-studio-original-diamond.png)
701
-
702
- </details>
1233
+ **Before:** Diamond-like shapes
703
1234
 
704
- <details>
705
- <summary>
706
- <b>After normalization</b> (axis-aligned rectangles):
707
- </summary>
708
-
709
- Command:
1235
+ ![Before normalization](./docs/images/label-studio-original-diamond.png)
710
1236
 
711
- ```bash
712
- ./dist/cli.js toPPOCR ./tmp --baseImageDir output --normalizeShape rectangle
713
- ```
1237
+ **After:** Axis-aligned rectangles
714
1238
 
715
1239
  ![After normalization](./docs/images/label-studio-converted-diamond.png)
716
1240
 
717
- </details>
718
-
719
- <details>
720
- <summary>
721
- <b>Before normalization</b> (diamond-like vertical shapes):
722
- </summary>
1241
+ **Vertical text example:**
723
1242
 
724
- ![Before normalization (vert)](./docs/images/label-studio-original-diamond-vert.png)
1243
+ ![Before (vertical)](./docs/images/label-studio-original-diamond-vert.png)
1244
+ ![After (vertical)](./docs/images/label-studio-converted-diamond-vert.png)
725
1245
 
726
1246
  </details>
727
1247
 
728
- <details>
729
- <summary>
730
- <b>After normalization</b> (axis-aligned vertical rectangles):
731
- </summary>
732
-
733
- Command:
1248
+ > [!NOTE]
1249
+ > **Key Behaviors:**
1250
+ >
1251
+ > - Remote images (`http://`, `https://`) are automatically downloaded
1252
+ > - Path resolution: `${baseServerUrl}/${relativeToOutDir}/image.jpg`
1253
+ > - All PPOCRLabel positions treated as polygons in Label Studio
1254
+ > - Missing images use fallback dimensions (1920×1080) and log warning
734
1255
 
735
1256
  ```bash
736
1257
  ./dist/cli.js toPPOCR ./tmp --baseImageDir output --normalizeShape rectangle
@@ -740,59 +1261,6 @@ Command:
740
1261
 
741
1262
  </details>
742
1263
 
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
1264
  ### Using generated files with Label Studio
797
1265
 
798
1266
  #### Interface setup
@@ -1121,10 +1589,10 @@ Converted back to Label Studio annotation:
1121
1589
  "last_created_by": null
1122
1590
  }
1123
1591
  ],
1124
- "file_upload": "5b1e3483-example.jpg",
1592
+ "file_upload": "example.jpg",
1125
1593
  "drafts": [],
1126
1594
  "predictions": [],
1127
- "data": { "ocr": "\/data\/upload\/2\/5b1e3483-example.jpg" },
1595
+ "data": { "ocr": "\/example.jpg" },
1128
1596
  "meta": {},
1129
1597
  "created_at": "2026-01-07T03:13:41.175183Z",
1130
1598
  "updated_at": "2026-01-10T03:21:09.923449Z",
@@ -1159,7 +1627,7 @@ Command:
1159
1627
  Output:
1160
1628
 
1161
1629
  ```
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}]
1630
+ 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
1631
  ```
1164
1632
 
1165
1633
  </details>
@@ -1385,11 +1853,11 @@ Output:
1385
1853
  "last_created_by": null
1386
1854
  }
1387
1855
  ],
1388
- "file_upload": "5b1e3483-example.jpg",
1856
+ "file_upload": "example.jpg",
1389
1857
  "drafts": [],
1390
1858
  "predictions": [],
1391
1859
  "data": {
1392
- "ocr": "http://localhost:8081/output/5b1e3483-example.jpg"
1860
+ "ocr": "http://localhost:8081/output/example.jpg"
1393
1861
  },
1394
1862
  "meta": {},
1395
1863
  "created_at": "2026-01-10T03:25:05.530Z",
@@ -1441,7 +1909,8 @@ commands:
1441
1909
  rm -rf ./output-label-studio
1442
1910
  ```
1443
1911
 
1444
- - When you did not specify an output directory (default: files are saved in the same directory as the source files):
1912
+ - When you did not specify an output directory (default: files are saved in the
1913
+ same directory as the source files):
1445
1914
 
1446
1915
  **For default output file names:**
1447
1916
 
@@ -1474,7 +1943,8 @@ commands:
1474
1943
  Remove-Item -Path ".\output-label-studio" -Recurse -Force
1475
1944
  ```
1476
1945
 
1477
- - When you did not specify an output directory (default: files are saved in the same directory as the source files):
1946
+ - When you did not specify an output directory (default: files are saved in the
1947
+ same directory as the source files):
1478
1948
 
1479
1949
  **For default output file names:**
1480
1950