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 +634 -349
- package/dist/bash-complete.cjs +2873 -1721
- package/dist/bash-complete.cjs.map +1 -1
- package/dist/bash-complete.js +2872 -1721
- package/dist/bash-complete.js.map +1 -1
- package/dist/cli.cjs +2885 -1733
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2873 -1722
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +2206 -1041
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2027 -513
- package/dist/index.d.ts +2027 -513
- package/dist/index.js +2126 -1031
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
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
|
|
26
|
-
- [
|
|
27
|
-
- [
|
|
28
|
-
- [
|
|
29
|
-
- [
|
|
30
|
-
- [
|
|
31
|
-
|
|
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
|
|
39
|
-
- [
|
|
40
|
-
- [
|
|
41
|
-
- [
|
|
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
|
-
|
|
149
|
-
|
|
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
|
|
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
|
|
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
|
|
272
|
-
|
|
273
|
-
#####
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
-
|
|
278
|
-
|
|
279
|
-
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
-
|
|
284
|
-
Default
|
|
285
|
-
-
|
|
286
|
-
|
|
287
|
-
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
-
|
|
298
|
-
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
-
|
|
304
|
-
|
|
305
|
-
- `
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
-
|
|
309
|
-
|
|
310
|
-
-
|
|
311
|
-
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
-
|
|
317
|
-
|
|
318
|
-
-
|
|
319
|
-
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
-
|
|
326
|
-
|
|
327
|
-
-
|
|
328
|
-
|
|
329
|
-
-
|
|
330
|
-
|
|
331
|
-
-
|
|
332
|
-
|
|
333
|
-
-
|
|
334
|
-
|
|
335
|
-
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
-
|
|
340
|
-
- `
|
|
341
|
-
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
-
|
|
346
|
-
|
|
347
|
-
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
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
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
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
|
-
|
|
776
|
+
**OUTPUT Resolution**: Same as `toLabelStudio` converter
|
|
367
777
|
|
|
368
|
-
|
|
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
|
-
-
|
|
371
|
-
|
|
372
|
-
|
|
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
|
|
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
|
-
#
|
|
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
|
-
#
|
|
547
|
-
label-studio-converter
|
|
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
|
-
#
|
|
984
|
+
# File-per-image + custom server URL
|
|
557
985
|
label-studio-converter toLabelStudio ./input-ppocr \
|
|
558
986
|
--outDir ./output \
|
|
559
|
-
--
|
|
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
|
-
#
|
|
568
|
-
|
|
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
|
-
#####
|
|
994
|
+
##### Enhancement Pipeline
|
|
580
995
|
|
|
581
996
|
```bash
|
|
582
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
654
|
-
|
|
655
|
-
|
|
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
|
-
--
|
|
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
|
-
|
|
1021
|
+
##### File Organization
|
|
665
1022
|
|
|
666
1023
|
```bash
|
|
667
|
-
#
|
|
668
|
-
label-studio-converter toLabelStudio ./
|
|
669
|
-
--
|
|
670
|
-
--
|
|
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
|
-
|
|
1029
|
+
# Custom output filenames
|
|
1030
|
+
label-studio-converter toPPOCR ./data \
|
|
675
1031
|
--outDir ./output \
|
|
676
|
-
--
|
|
677
|
-
--sortHorizontal ltr \
|
|
678
|
-
--normalizeShape rectangle
|
|
1032
|
+
--fileName MyLabels.txt
|
|
679
1033
|
```
|
|
680
1034
|
|
|
681
|
-
##### Shape Normalization
|
|
1035
|
+
##### Shape Normalization
|
|
682
1036
|
|
|
683
|
-
|
|
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
|
-
|
|
689
|
-
|
|
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
|
-
|
|
1048
|
+
**Before:** Diamond-like shapes
|
|
701
1049
|
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
<details>
|
|
705
|
-
<summary>
|
|
706
|
-
<b>After normalization</b> (axis-aligned rectangles):
|
|
707
|
-
</summary>
|
|
708
|
-
|
|
709
|
-
Command:
|
|
1050
|
+

|
|
710
1051
|
|
|
711
|
-
|
|
712
|
-
./dist/cli.js toPPOCR ./tmp --baseImageDir output --normalizeShape rectangle
|
|
713
|
-
```
|
|
1052
|
+
**After:** Axis-aligned rectangles
|
|
714
1053
|
|
|
715
1054
|

|
|
716
1055
|
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
<details>
|
|
720
|
-
<summary>
|
|
721
|
-
<b>Before normalization</b> (diamond-like vertical shapes):
|
|
722
|
-
</summary>
|
|
1056
|
+
**Vertical text example:**
|
|
723
1057
|
|
|
724
|
-

|
|
1059
|
+

|
|
725
1060
|
|
|
726
1061
|
</details>
|
|
727
1062
|
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
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": "
|
|
1407
|
+
"file_upload": "example.jpg",
|
|
1125
1408
|
"drafts": [],
|
|
1126
1409
|
"predictions": [],
|
|
1127
|
-
"data": { "ocr": "\/
|
|
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
|
-
|
|
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": "
|
|
1671
|
+
"file_upload": "example.jpg",
|
|
1389
1672
|
"drafts": [],
|
|
1390
1673
|
"predictions": [],
|
|
1391
1674
|
"data": {
|
|
1392
|
-
"ocr": "http://localhost:8081/output/
|
|
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
|
|
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
|
|
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
|
|