label-studio-converter 1.3.0 → 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 +677 -370
- package/dist/bash-complete.cjs +2902 -1837
- package/dist/bash-complete.cjs.map +1 -1
- package/dist/bash-complete.js +2889 -1827
- package/dist/bash-complete.js.map +1 -1
- package/dist/cli.cjs +2902 -1837
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2890 -1828
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +2194 -1117
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2027 -363
- package/dist/index.d.ts +2027 -363
- package/dist/index.js +2122 -1114
- package/dist/index.js.map +1 -1
- package/package.json +22 -20
package/README.md
CHANGED
|
@@ -21,8 +21,29 @@
|
|
|
21
21
|
- [Usage](#eyes-usage)
|
|
22
22
|
- [Library Usage](#library-usage)
|
|
23
23
|
- [CLI Usage](#cli-usage)
|
|
24
|
+
- [Available Commands](#available-commands)
|
|
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)
|
|
37
|
+
- [Detailed Command Help](#detailed-command-help)
|
|
38
|
+
- [toLabelStudio Command](#tolabelstudio-command)
|
|
39
|
+
- [toPPOCR Command](#toppocr-command)
|
|
40
|
+
- [enhance-labelstudio Command](#enhance-labelstudio-command)
|
|
41
|
+
- [enhance-ppocr Command](#enhance-ppocr-command)
|
|
24
42
|
- [Examples](#examples)
|
|
25
|
-
|
|
43
|
+
- [Basic Conversion](#basic-conversion)
|
|
44
|
+
- [Enhancement Pipeline](#enhancement-pipeline)
|
|
45
|
+
- [File Organization](#file-organization)
|
|
46
|
+
- [Shape Normalization](#shape-normalization)
|
|
26
47
|
- [Using generated files with Label Studio](#using-generated-files-with-label-studio)
|
|
27
48
|
- [Interface setup](#interface-setup)
|
|
28
49
|
- [Serving annotation files locally](#serving-annotation-files-locally)
|
|
@@ -124,14 +145,14 @@ pnpm install
|
|
|
124
145
|
|
|
125
146
|
```ts
|
|
126
147
|
import {
|
|
127
|
-
|
|
128
|
-
|
|
148
|
+
fullLabelStudioToPPOCRConverters,
|
|
149
|
+
minLabelStudioToPPOCRConverters,
|
|
129
150
|
ppocrToLabelStudio
|
|
130
151
|
} from 'label-studio-converter';
|
|
131
152
|
|
|
132
153
|
// Convert Label Studio Full Format to PPOCRLabel
|
|
133
154
|
const fullData = [...]; // FullOCRLabelStudio type
|
|
134
|
-
const ppocrMap = await
|
|
155
|
+
const ppocrMap = await fullLabelStudioToPPOCRConverters(fullData, {
|
|
135
156
|
baseImageDir: 'images/ch',
|
|
136
157
|
normalizeShape: 'rectangle',
|
|
137
158
|
widthIncrement: 5,
|
|
@@ -141,7 +162,7 @@ const ppocrMap = await labelStudioToPPOCR(fullData, {
|
|
|
141
162
|
|
|
142
163
|
// Convert Label Studio Min Format to PPOCRLabel
|
|
143
164
|
const minData = [...]; // MinOCRLabelStudio type
|
|
144
|
-
const ppocrMap2 = await
|
|
165
|
+
const ppocrMap2 = await minLabelStudioToPPOCRConverters(minData, {
|
|
145
166
|
baseImageDir: 'images/ch',
|
|
146
167
|
precision: 0
|
|
147
168
|
});
|
|
@@ -217,13 +238,15 @@ const sorted = sortBoundingBoxes(annotations, 'top-bottom', 'ltr');
|
|
|
217
238
|
|
|
218
239
|
### CLI Usage
|
|
219
240
|
|
|
220
|
-
|
|
241
|
+
#### Available Commands
|
|
221
242
|
|
|
222
243
|
```bash
|
|
223
244
|
label-studio-converter --help
|
|
224
245
|
```
|
|
225
246
|
|
|
226
|
-
|
|
247
|
+
**Output:**
|
|
248
|
+
|
|
249
|
+
```
|
|
227
250
|
USAGE
|
|
228
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>...
|
|
229
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>...
|
|
@@ -245,11 +268,576 @@ COMMANDS
|
|
|
245
268
|
enhance-ppocr Enhance PPOCRLabel files with sorting, normalization, and resizing
|
|
246
269
|
```
|
|
247
270
|
|
|
248
|
-
|
|
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
|
|
426
|
+
|
|
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
|
+
```
|
|
249
726
|
|
|
250
|
-
|
|
727
|
+
**Command:**
|
|
251
728
|
|
|
252
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
|
|
775
|
+
|
|
776
|
+
**OUTPUT Resolution**: Same as `toLabelStudio` converter
|
|
777
|
+
|
|
778
|
+
- Generates Label Studio JSON with `data.ocr` URLs
|
|
779
|
+
- Applies `baseServerUrl` formatting
|
|
780
|
+
- Computes relative paths from output location to images
|
|
781
|
+
|
|
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
|
|
829
|
+
|
|
830
|
+
#### Detailed Command Help
|
|
831
|
+
|
|
832
|
+
##### toLabelStudio Command
|
|
833
|
+
|
|
834
|
+
```bash
|
|
835
|
+
label-studio-converter toLabelStudio --help
|
|
836
|
+
```
|
|
837
|
+
|
|
838
|
+
**Output:**
|
|
839
|
+
|
|
840
|
+
```
|
|
253
841
|
USAGE
|
|
254
842
|
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>...
|
|
255
843
|
label-studio-converter toLabelStudio --help
|
|
@@ -281,9 +869,15 @@ ARGUMENTS
|
|
|
281
869
|
args... Input directories containing PPOCRLabel files
|
|
282
870
|
```
|
|
283
871
|
|
|
284
|
-
|
|
872
|
+
##### toPPOCR Command
|
|
285
873
|
|
|
286
874
|
```bash
|
|
875
|
+
label-studio-converter toPPOCR --help
|
|
876
|
+
```
|
|
877
|
+
|
|
878
|
+
**Output:**
|
|
879
|
+
|
|
880
|
+
```
|
|
287
881
|
USAGE
|
|
288
882
|
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>...
|
|
289
883
|
label-studio-converter toPPOCR --help
|
|
@@ -309,10 +903,15 @@ ARGUMENTS
|
|
|
309
903
|
args... Input directories containing Label Studio files
|
|
310
904
|
```
|
|
311
905
|
|
|
312
|
-
|
|
313
|
-
normalization, and resizing
|
|
906
|
+
##### enhance-labelstudio Command
|
|
314
907
|
|
|
315
908
|
```bash
|
|
909
|
+
label-studio-converter enhance-labelstudio --help
|
|
910
|
+
```
|
|
911
|
+
|
|
912
|
+
**Output:**
|
|
913
|
+
|
|
914
|
+
```
|
|
316
915
|
USAGE
|
|
317
916
|
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>...
|
|
318
917
|
label-studio-converter enhance-labelstudio --help
|
|
@@ -338,9 +937,15 @@ ARGUMENTS
|
|
|
338
937
|
args... Input directories containing Label Studio JSON files
|
|
339
938
|
```
|
|
340
939
|
|
|
341
|
-
|
|
940
|
+
##### enhance-ppocr Command
|
|
342
941
|
|
|
343
942
|
```bash
|
|
943
|
+
label-studio-converter enhance-ppocr --help
|
|
944
|
+
```
|
|
945
|
+
|
|
946
|
+
**Output:**
|
|
947
|
+
|
|
948
|
+
```
|
|
344
949
|
USAGE
|
|
345
950
|
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>...
|
|
346
951
|
label-studio-converter enhance-ppocr --help
|
|
@@ -365,348 +970,103 @@ ARGUMENTS
|
|
|
365
970
|
args... Input directories containing PPOCRLabel files
|
|
366
971
|
```
|
|
367
972
|
|
|
368
|
-
**Error Handling:**
|
|
369
|
-
|
|
370
|
-
The `toLabelStudio` command handles missing or unreadable image files gracefully:
|
|
371
|
-
|
|
372
|
-
- If an image file referenced in PPOCRLabel cannot be found or read, a warning is logged
|
|
373
|
-
- Default dimensions of **1920×1080** are used as fallback
|
|
374
|
-
- Conversion continues for remaining images without interruption
|
|
375
|
-
|
|
376
|
-
This allows the conversion process to complete even when some image files are missing from the dataset.
|
|
377
|
-
|
|
378
973
|
#### Examples
|
|
379
974
|
|
|
380
|
-
|
|
975
|
+
##### Basic Conversion
|
|
381
976
|
|
|
382
977
|
```bash
|
|
383
|
-
#
|
|
384
|
-
label-studio-converter toLabelStudio ./input-ppocr --outDir ./output
|
|
385
|
-
|
|
386
|
-
# Convert Label Studio files to PPOCRLabel format
|
|
387
|
-
label-studio-converter toPPOCR ./input-label-studio --outDir ./output-ppocr
|
|
388
|
-
|
|
389
|
-
# Convert with custom output filename for PPOCR
|
|
390
|
-
label-studio-converter toPPOCR ./input-label-studio --outDir ./output-ppocr --fileName MyLabels.txt
|
|
391
|
-
|
|
392
|
-
# Convert with base image directory path
|
|
393
|
-
label-studio-converter toPPOCR ./input-label-studio --baseImageDir images/ch
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
> [!NOTE]
|
|
397
|
-
> By default, all PPOCRLabel positions are treated as **polygons** in Label Studio.
|
|
398
|
-
|
|
399
|
-
**toLabelStudio Options:**
|
|
400
|
-
|
|
401
|
-
```bash
|
|
402
|
-
# Create separate JSON file for each image
|
|
403
|
-
label-studio-converter toLabelStudio ./input-ppocr \
|
|
404
|
-
--outDir ./output \
|
|
405
|
-
--createFilePerImage
|
|
406
|
-
|
|
407
|
-
# Specify custom label name (default is "Text")
|
|
408
|
-
label-studio-converter toLabelStudio ./input-ppocr \
|
|
409
|
-
--outDir ./output \
|
|
410
|
-
--defaultLabelName Handwriting
|
|
411
|
-
|
|
412
|
-
# Convert to minimal format (without serving support)
|
|
413
|
-
label-studio-converter toLabelStudio ./input-ppocr \
|
|
414
|
-
--outDir ./output \
|
|
415
|
-
--noToFullJson
|
|
978
|
+
# PPOCRLabel → Label Studio
|
|
979
|
+
label-studio-converter toLabelStudio ./input-ppocr --outDir ./output
|
|
416
980
|
|
|
417
|
-
#
|
|
418
|
-
label-studio-converter
|
|
419
|
-
--outDir ./output \
|
|
420
|
-
--noCreateFileListForServing
|
|
981
|
+
# Label Studio → PPOCRLabel
|
|
982
|
+
label-studio-converter toPPOCR ./input-label-studio --outDir ./output --baseImageDir images/ch
|
|
421
983
|
|
|
422
|
-
#
|
|
984
|
+
# File-per-image + custom server URL
|
|
423
985
|
label-studio-converter toLabelStudio ./input-ppocr \
|
|
424
986
|
--outDir ./output \
|
|
425
|
-
--
|
|
987
|
+
--createFilePerImage \
|
|
426
988
|
--baseServerUrl http://192.168.1.100:8080
|
|
427
989
|
|
|
428
|
-
#
|
|
429
|
-
|
|
430
|
-
label-studio-converter toLabelStudio ./input-ppocr \
|
|
431
|
-
--outDir ./output \
|
|
432
|
-
--outputMode predictions
|
|
433
|
-
|
|
434
|
-
# Convert to annotations format (default, editable ground truth)
|
|
435
|
-
label-studio-converter toLabelStudio ./input-ppocr \
|
|
436
|
-
--outDir ./output \
|
|
437
|
-
--outputMode annotations
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
> [!IMPORTANT]
|
|
441
|
-
> **Output Mode Restrictions:**
|
|
442
|
-
>
|
|
443
|
-
> - The `--outputMode` flag is only available for:
|
|
444
|
-
> - `toLabelStudio` command (when using `--toFullJson`)
|
|
445
|
-
> - `enhance-labelstudio` command (for Full JSON format files only)
|
|
446
|
-
> - **Not available** for:
|
|
447
|
-
> - `toPPOCR` command (PPOCR format doesn't distinguish annotations/predictions)
|
|
448
|
-
> - `enhance-ppocr` command (PPOCR format doesn't distinguish annotations/predictions)
|
|
449
|
-
> - Min JSON Label Studio format (doesn't support annotations/predictions)
|
|
450
|
-
>
|
|
451
|
-
> **Prediction Scores:**
|
|
452
|
-
>
|
|
453
|
-
> - When converting from PPOCRLabel to Label Studio with `--outputMode predictions`, the `dt_score` field from PPOCRLabel is automatically mapped to the prediction `score` field in Label Studio
|
|
454
|
-
> - This allows pre-annotation confidence scores to be preserved and displayed in Label Studio
|
|
455
|
-
> - Score values should be between 0.0 and 1.0 (confidence percentage)
|
|
456
|
-
|
|
457
|
-
**toPPOCR Options:**
|
|
458
|
-
|
|
459
|
-
```bash
|
|
460
|
-
# Basic conversion with output directory
|
|
461
|
-
label-studio-converter toPPOCR ./input-label-studio \
|
|
462
|
-
--outDir ./output
|
|
463
|
-
|
|
464
|
-
# Custom output filename
|
|
465
|
-
label-studio-converter toPPOCR ./input-label-studio \
|
|
466
|
-
--outDir ./output \
|
|
467
|
-
--fileName CustomLabel.txt
|
|
468
|
-
|
|
469
|
-
# Add base image directory to paths
|
|
470
|
-
label-studio-converter toPPOCR ./input-label-studio \
|
|
471
|
-
--outDir ./output \
|
|
472
|
-
--baseImageDir dataset/images
|
|
990
|
+
# Predictions format (read-only pre-annotations)
|
|
991
|
+
label-studio-converter toLabelStudio ./input-ppocr --outputMode predictions
|
|
473
992
|
```
|
|
474
993
|
|
|
475
|
-
|
|
994
|
+
##### Enhancement Pipeline
|
|
476
995
|
|
|
477
996
|
```bash
|
|
478
|
-
#
|
|
479
|
-
label-studio-converter toLabelStudio ./data --recursive
|
|
480
|
-
|
|
481
|
-
# Search with custom pattern (only files starting with "Label")
|
|
482
|
-
label-studio-converter toLabelStudio ./data \
|
|
483
|
-
--recursive \
|
|
484
|
-
--filePattern "Label.*\.txt$"
|
|
485
|
-
|
|
486
|
-
# Convert only specific JSON files (e.g., final annotations)
|
|
487
|
-
label-studio-converter toPPOCR ./annotations \
|
|
488
|
-
--recursive \
|
|
489
|
-
--filePattern ".*_final\.json$"
|
|
490
|
-
|
|
491
|
-
# Enhance only specific files matching pattern
|
|
492
|
-
label-studio-converter enhance-ppocr ./dataset \
|
|
493
|
-
--recursive \
|
|
494
|
-
--filePattern "train_.*\.txt$"
|
|
495
|
-
```
|
|
496
|
-
|
|
497
|
-
> [!NOTE]
|
|
498
|
-
>
|
|
499
|
-
> - `--recursive`: Searches all subdirectories for matching files
|
|
500
|
-
> - `--filePattern`: Regex pattern to filter files (default: `.*\.txt$` for PPOCR, `.*\.json$` for Label Studio)
|
|
501
|
-
> - Patterns are flexible - use any regex, but ensure they match appropriate file types (.txt for PPOCR, .json for Label Studio)
|
|
502
|
-
|
|
503
|
-
### Enhancement Features
|
|
504
|
-
|
|
505
|
-
The tool provides powerful enhancement capabilities that can be used standalone or integrated with conversion:
|
|
506
|
-
|
|
507
|
-
**Enhance PPOCRLabel files:**
|
|
508
|
-
|
|
509
|
-
```bash
|
|
510
|
-
# Sort annotations from top to bottom, left to right
|
|
511
|
-
label-studio-converter enhance-ppocr ./data --sortVertical top-bottom --sortHorizontal ltr
|
|
512
|
-
|
|
513
|
-
# Normalize diamond shapes to rectangles and resize
|
|
514
|
-
label-studio-converter enhance-ppocr ./data --normalizeShape rectangle --widthIncrement 10 --heightIncrement 5
|
|
515
|
-
|
|
516
|
-
# Apply all enhancements
|
|
997
|
+
# Sort + normalize + resize
|
|
517
998
|
label-studio-converter enhance-ppocr ./data \
|
|
518
999
|
--sortVertical top-bottom \
|
|
519
1000
|
--sortHorizontal ltr \
|
|
520
1001
|
--normalizeShape rectangle \
|
|
521
1002
|
--widthIncrement 5 \
|
|
522
|
-
--heightIncrement 5
|
|
523
|
-
--precision 0
|
|
524
|
-
```
|
|
525
|
-
|
|
526
|
-
**Enhance Label Studio files:**
|
|
527
|
-
|
|
528
|
-
```bash
|
|
529
|
-
# Sort and normalize Label Studio annotations
|
|
530
|
-
label-studio-converter enhance-labelstudio ./data \
|
|
531
|
-
--sortVertical top-bottom \
|
|
532
|
-
--normalizeShape rectangle \
|
|
533
|
-
--precision 2
|
|
534
|
-
|
|
535
|
-
# Works with both Full and Min formats automatically
|
|
536
|
-
label-studio-converter enhance-labelstudio ./label-studio-files --outDir ./enhanced
|
|
537
|
-
```
|
|
1003
|
+
--heightIncrement 5
|
|
538
1004
|
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
```bash
|
|
547
|
-
# Sort annotations from top to bottom
|
|
548
|
-
label-studio-converter enhance-ppocr ./data --sortVertical top-bottom
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
- `--sortHorizontal`: Sort bounding boxes horizontally
|
|
552
|
-
- `none` (default): No sorting
|
|
553
|
-
- `ltr`: Sort left to right (useful for English, most European languages)
|
|
554
|
-
- `rtl`: Sort right to left (useful for Arabic, Hebrew)
|
|
555
|
-
- Example:
|
|
556
|
-
|
|
557
|
-
```bash
|
|
558
|
-
# Sort annotations left to right
|
|
559
|
-
label-studio-converter enhance-ppocr ./data --sortHorizontal ltr
|
|
560
|
-
|
|
561
|
-
# Sort annotations right to left
|
|
562
|
-
label-studio-converter enhance-ppocr ./data --sortHorizontal rtl
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
- `--normalizeShape`: Normalize shapes
|
|
566
|
-
- `none` (default): Keep original shape
|
|
567
|
-
- `rectangle`: Convert diamond-like or rotated shapes to axis-aligned rectangles
|
|
568
|
-
- Example:
|
|
569
|
-
```bash
|
|
570
|
-
# Convert irregular shapes to clean rectangles
|
|
571
|
-
label-studio-converter enhance-ppocr ./data --normalizeShape rectangle
|
|
572
|
-
```
|
|
573
|
-
|
|
574
|
-
- `--widthIncrement`: Increase/decrease width (pixels, can be negative)
|
|
575
|
-
- Default: `0`
|
|
576
|
-
- Examples:
|
|
577
|
-
|
|
578
|
-
```bash
|
|
579
|
-
# Increase width by 10 pixels
|
|
580
|
-
label-studio-converter enhance-ppocr ./data --widthIncrement 10
|
|
581
|
-
|
|
582
|
-
# Decrease width by 5 pixels
|
|
583
|
-
label-studio-converter enhance-ppocr ./data --widthIncrement -5
|
|
584
|
-
```
|
|
585
|
-
|
|
586
|
-
- `--heightIncrement`: Increase/decrease height (pixels, can be negative)
|
|
587
|
-
- Default: `0`
|
|
588
|
-
- Examples:
|
|
589
|
-
|
|
590
|
-
```bash
|
|
591
|
-
# Increase height by 15 pixels
|
|
592
|
-
label-studio-converter enhance-ppocr ./data --heightIncrement 15
|
|
593
|
-
|
|
594
|
-
# Decrease height by 3 pixels
|
|
595
|
-
label-studio-converter enhance-ppocr ./data --heightIncrement -3
|
|
596
|
-
```
|
|
597
|
-
|
|
598
|
-
- `--precision`: Control the number of decimal places for coordinate values
|
|
599
|
-
- `-1`: Full precision - no rounding, keeps all decimal places (default for Label Studio output)
|
|
600
|
-
- Example output: `27.44656917885264`
|
|
601
|
-
- `0`: Round to integers (default for PPOCR output)
|
|
602
|
-
- Example output: `27`
|
|
603
|
-
- `1`: Round to 1 decimal place
|
|
604
|
-
- Example output: `27.4`
|
|
605
|
-
- `2`: Round to 2 decimal places
|
|
606
|
-
- Example output: `27.45`
|
|
607
|
-
- Any positive integer for that many decimal places
|
|
608
|
-
- Examples:
|
|
609
|
-
|
|
610
|
-
```bash
|
|
611
|
-
# Use full precision
|
|
612
|
-
label-studio-converter toLabelStudio ./data --precision -1
|
|
613
|
-
|
|
614
|
-
# Use integer coordinates
|
|
615
|
-
label-studio-converter toPPOCR ./data --precision 0
|
|
616
|
-
|
|
617
|
-
# Use 2 decimal places
|
|
618
|
-
label-studio-converter enhance-labelstudio ./data --precision 2
|
|
619
|
-
```
|
|
620
|
-
|
|
621
|
-
**Conversion with Enhancement:**
|
|
622
|
-
|
|
623
|
-
All enhancement options are available in conversion commands:
|
|
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
|
|
624
1012
|
|
|
625
|
-
|
|
626
|
-
# Convert with enhancements applied during conversion
|
|
1013
|
+
# Convert with full enhancement pipeline
|
|
627
1014
|
label-studio-converter toLabelStudio ./input-ppocr \
|
|
628
1015
|
--outDir ./output \
|
|
629
|
-
--sortVertical top-bottom \
|
|
630
1016
|
--normalizeShape rectangle \
|
|
631
|
-
--
|
|
632
|
-
|
|
633
|
-
label-studio-converter toPPOCR ./input-label-studio \
|
|
634
|
-
--outDir ./output \
|
|
635
|
-
--sortVertical top-bottom \
|
|
636
|
-
--sortHorizontal ltr \
|
|
637
|
-
--normalizeShape rectangle
|
|
1017
|
+
--adaptResize \
|
|
1018
|
+
--sortVertical top-bottom
|
|
638
1019
|
```
|
|
639
1020
|
|
|
640
|
-
|
|
1021
|
+
##### File Organization
|
|
641
1022
|
|
|
642
1023
|
```bash
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
1024
|
+
# Recursive search with pattern matching
|
|
1025
|
+
label-studio-converter toLabelStudio ./dataset \
|
|
1026
|
+
--recursive \
|
|
1027
|
+
--filePattern "train_.*\.txt$"
|
|
647
1028
|
|
|
648
|
-
|
|
649
|
-
label-studio-converter
|
|
1029
|
+
# Custom output filenames
|
|
1030
|
+
label-studio-converter toPPOCR ./data \
|
|
1031
|
+
--outDir ./output \
|
|
1032
|
+
--fileName MyLabels.txt
|
|
650
1033
|
```
|
|
651
1034
|
|
|
652
|
-
|
|
653
|
-
> Minimal Label Studio format cannot be used for serving in Label Studio, as it
|
|
654
|
-
> lacks necessary fields such as `id` and `data`. So you can only use minimal
|
|
655
|
-
> format for conversion back to PPOCRLabelv2 format or other purposes.
|
|
656
|
-
|
|
657
|
-
**Shape Normalization**
|
|
1035
|
+
##### Shape Normalization
|
|
658
1036
|
|
|
659
|
-
|
|
660
|
-
rectangles. This is useful when your annotations have irregular shapes that you
|
|
661
|
-
want to normalize to clean, horizontal/vertical bounding boxes:
|
|
1037
|
+
Diamond/rotated shapes → axis-aligned rectangles:
|
|
662
1038
|
|
|
663
1039
|
```bash
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
# For toPPOCR command
|
|
668
|
-
label-studio-converter toPPOCR ./input-label-studio --outDir ./output --normalizeShape rectangle
|
|
1040
|
+
label-studio-converter enhance-ppocr ./data \
|
|
1041
|
+
--normalizeShape rectangle \
|
|
1042
|
+
--outDir ./normalized
|
|
669
1043
|
```
|
|
670
1044
|
|
|
671
1045
|
<details>
|
|
672
|
-
<summary>
|
|
673
|
-
<b>Before normalization</b> (diamond-like shapes):
|
|
674
|
-
</summary>
|
|
1046
|
+
<summary>Visual comparison</summary>
|
|
675
1047
|
|
|
676
|
-
|
|
1048
|
+
**Before:** Diamond-like shapes
|
|
677
1049
|
|
|
678
|
-
|
|
1050
|
+

|
|
679
1051
|
|
|
680
|
-
|
|
681
|
-
<summary>
|
|
682
|
-
<b>After normalization</b> (axis-aligned rectangles):
|
|
683
|
-
</summary>
|
|
684
|
-
|
|
685
|
-
Command:
|
|
686
|
-
|
|
687
|
-
```bash
|
|
688
|
-
./dist/cli.js toPPOCR ./tmp --baseImageDir output --normalizeShape rectangle
|
|
689
|
-
```
|
|
1052
|
+
**After:** Axis-aligned rectangles
|
|
690
1053
|
|
|
691
1054
|

|
|
692
1055
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
<details>
|
|
696
|
-
<summary>
|
|
697
|
-
<b>Before normalization</b> (diamond-like vertical shapes):
|
|
698
|
-
</summary>
|
|
1056
|
+
**Vertical text example:**
|
|
699
1057
|
|
|
700
|
-

|
|
1059
|
+

|
|
701
1060
|
|
|
702
1061
|
</details>
|
|
703
1062
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
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
|
|
710
1070
|
|
|
711
1071
|
```bash
|
|
712
1072
|
./dist/cli.js toPPOCR ./tmp --baseImageDir output --normalizeShape rectangle
|
|
@@ -716,61 +1076,6 @@ Command:
|
|
|
716
1076
|
|
|
717
1077
|
</details>
|
|
718
1078
|
|
|
719
|
-
**Bounding Box Resizing**
|
|
720
|
-
|
|
721
|
-
Increase or decrease bounding box dimensions while keeping them centered. This
|
|
722
|
-
is useful for adjusting annotation margins:
|
|
723
|
-
|
|
724
|
-
```bash
|
|
725
|
-
# Increase width by 10 pixels and height by 20 pixels
|
|
726
|
-
label-studio-converter toLabelStudio ./input-ppocr --outDir ./output --widthIncrement 10 --heightIncrement 20
|
|
727
|
-
|
|
728
|
-
# Decrease width by 5 pixels (negative increment)
|
|
729
|
-
label-studio-converter toLabelStudio ./input-ppocr --outDir ./output --widthIncrement -5
|
|
730
|
-
|
|
731
|
-
# Works with toPPOCR as well
|
|
732
|
-
label-studio-converter toPPOCR ./input-label-studio --outDir ./output --widthIncrement 10 --heightIncrement 10
|
|
733
|
-
```
|
|
734
|
-
|
|
735
|
-
**Combining Features**
|
|
736
|
-
|
|
737
|
-
You can combine shape normalization and resizing:
|
|
738
|
-
|
|
739
|
-
```bash
|
|
740
|
-
# Normalize to rectangle and increase size
|
|
741
|
-
label-studio-converter toLabelStudio ./input-ppocr --outDir ./output --normalizeShape rectangle --widthIncrement 5 --heightIncrement 5
|
|
742
|
-
|
|
743
|
-
# Also works with sorting
|
|
744
|
-
label-studio-converter toLabelStudio ./input-ppocr --outDir ./output --normalizeShape rectangle --widthIncrement 10 --sortVertical top-bottom --sortHorizontal ltr
|
|
745
|
-
```
|
|
746
|
-
|
|
747
|
-
**Number Precision Control**
|
|
748
|
-
|
|
749
|
-
Control the precision of coordinate values in the output. This is useful for
|
|
750
|
-
matching format expectations or reducing file size:
|
|
751
|
-
|
|
752
|
-
```bash
|
|
753
|
-
# Convert to Label Studio with full precision (default: -1)
|
|
754
|
-
label-studio-converter toLabelStudio ./input-ppocr --outDir ./output --precision -1
|
|
755
|
-
|
|
756
|
-
# Convert to PPOCR with integer coordinates (default: 0)
|
|
757
|
-
label-studio-converter toPPOCR ./input-label-studio --outDir ./output --precision 0
|
|
758
|
-
|
|
759
|
-
# Use 2 decimal places for more compact but still precise coordinates
|
|
760
|
-
label-studio-converter toLabelStudio ./input-ppocr --outDir ./output --precision 2
|
|
761
|
-
```
|
|
762
|
-
|
|
763
|
-
Precision values:
|
|
764
|
-
|
|
765
|
-
- `-1`: Full floating-point precision (default for Label Studio output)
|
|
766
|
-
- `0`: Round to integers (default for PPOCR output)
|
|
767
|
-
- `1+`: Round to specified number of decimal places
|
|
768
|
-
|
|
769
|
-
> [!NOTE]
|
|
770
|
-
> The default precision matches typical format conventions: Label Studio uses
|
|
771
|
-
> full precision for percentage-based coordinates, while PPOCR format typically
|
|
772
|
-
> uses integer pixel coordinates.
|
|
773
|
-
|
|
774
1079
|
### Using generated files with Label Studio
|
|
775
1080
|
|
|
776
1081
|
#### Interface setup
|
|
@@ -1099,10 +1404,10 @@ Converted back to Label Studio annotation:
|
|
|
1099
1404
|
"last_created_by": null
|
|
1100
1405
|
}
|
|
1101
1406
|
],
|
|
1102
|
-
"file_upload": "
|
|
1407
|
+
"file_upload": "example.jpg",
|
|
1103
1408
|
"drafts": [],
|
|
1104
1409
|
"predictions": [],
|
|
1105
|
-
"data": { "ocr": "\/
|
|
1410
|
+
"data": { "ocr": "\/example.jpg" },
|
|
1106
1411
|
"meta": {},
|
|
1107
1412
|
"created_at": "2026-01-07T03:13:41.175183Z",
|
|
1108
1413
|
"updated_at": "2026-01-10T03:21:09.923449Z",
|
|
@@ -1137,7 +1442,7 @@ Command:
|
|
|
1137
1442
|
Output:
|
|
1138
1443
|
|
|
1139
1444
|
```
|
|
1140
|
-
|
|
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}]
|
|
1141
1446
|
```
|
|
1142
1447
|
|
|
1143
1448
|
</details>
|
|
@@ -1363,11 +1668,11 @@ Output:
|
|
|
1363
1668
|
"last_created_by": null
|
|
1364
1669
|
}
|
|
1365
1670
|
],
|
|
1366
|
-
"file_upload": "
|
|
1671
|
+
"file_upload": "example.jpg",
|
|
1367
1672
|
"drafts": [],
|
|
1368
1673
|
"predictions": [],
|
|
1369
1674
|
"data": {
|
|
1370
|
-
"ocr": "http://localhost:8081/output/
|
|
1675
|
+
"ocr": "http://localhost:8081/output/example.jpg"
|
|
1371
1676
|
},
|
|
1372
1677
|
"meta": {},
|
|
1373
1678
|
"created_at": "2026-01-10T03:25:05.530Z",
|
|
@@ -1419,7 +1724,8 @@ commands:
|
|
|
1419
1724
|
rm -rf ./output-label-studio
|
|
1420
1725
|
```
|
|
1421
1726
|
|
|
1422
|
-
- 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):
|
|
1423
1729
|
|
|
1424
1730
|
**For default output file names:**
|
|
1425
1731
|
|
|
@@ -1452,7 +1758,8 @@ commands:
|
|
|
1452
1758
|
Remove-Item -Path ".\output-label-studio" -Recurse -Force
|
|
1453
1759
|
```
|
|
1454
1760
|
|
|
1455
|
-
- 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):
|
|
1456
1763
|
|
|
1457
1764
|
**For default output file names:**
|
|
1458
1765
|
|