label-studio-converter 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +294 -109
- package/dist/bash-complete.cjs +772 -197
- package/dist/bash-complete.cjs.map +1 -1
- package/dist/bash-complete.js +764 -190
- package/dist/bash-complete.js.map +1 -1
- package/dist/cli.cjs +771 -196
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +764 -190
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +640 -107
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +605 -5
- package/dist/index.d.ts +605 -5
- package/dist/index.js +625 -108
- package/dist/index.js.map +1 -1
- package/package.json +37 -36
package/dist/bash-complete.cjs
CHANGED
|
@@ -30,15 +30,15 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
30
|
mod
|
|
31
31
|
));
|
|
32
32
|
|
|
33
|
-
// node_modules/.pnpm/tsup@8.5.1_jiti@2.4.2_postcss@8.5.6_typescript@
|
|
33
|
+
// node_modules/.pnpm/tsup@8.5.1_jiti@2.4.2_postcss@8.5.6_typescript@6.0.3_yaml@2.9.0/node_modules/tsup/assets/cjs_shims.js
|
|
34
34
|
var init_cjs_shims = __esm({
|
|
35
|
-
"node_modules/.pnpm/tsup@8.5.1_jiti@2.4.2_postcss@8.5.6_typescript@
|
|
35
|
+
"node_modules/.pnpm/tsup@8.5.1_jiti@2.4.2_postcss@8.5.6_typescript@6.0.3_yaml@2.9.0/node_modules/tsup/assets/cjs_shims.js"() {
|
|
36
36
|
"use strict";
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
// src/constants.ts
|
|
41
|
-
var DEFAULT_DETECT_IMAGE_SIZE, DEFAULT_LABEL_NAME, DEFAULT_LABEL_STUDIO_FULL_JSON, DEFAULT_CREATE_FILE_PER_IMAGE, DEFAULT_CREATE_FILE_LIST_FOR_SERVING, DEFAULT_FILE_LIST_NAME, DEFAULT_BASE_SERVER_URL, DEFAULT_PPOCR_FILE_NAME, SORT_VERTICAL_NONE, SORT_VERTICAL_TOP_BOTTOM, SORT_VERTICAL_BOTTOM_TOP, DEFAULT_SORT_VERTICAL, SORT_HORIZONTAL_NONE, SORT_HORIZONTAL_LTR, SORT_HORIZONTAL_RTL, DEFAULT_SORT_HORIZONTAL, SHAPE_NORMALIZE_NONE, SHAPE_NORMALIZE_RECTANGLE, DEFAULT_SHAPE_NORMALIZE, DEFAULT_USE_ORIENTED_BOX, DEFAULT_WIDTH_INCREMENT, DEFAULT_HEIGHT_INCREMENT, DEFAULT_ADAPT_RESIZE_THRESHOLD, DEFAULT_ADAPT_RESIZE_MARGIN, DEFAULT_ADAPT_RESIZE_MIN_COMPONENT_SIZE, DEFAULT_ADAPT_RESIZE_MAX_COMPONENT_SIZE, DEFAULT_ADAPT_RESIZE_OUTLIER_PERCENTILE, DEFAULT_ADAPT_RESIZE_MORPHOLOGY_SIZE, DEFAULT_ADAPT_RESIZE_MAX_HORIZONTAL_EXPANSION, DEFAULT_ADAPT_RESIZE_TIMEOUT_MS, DEFAULT_ADAPT_RESIZE_MAX_BOX_SIZE, DEFAULT_LABEL_STUDIO_PRECISION, DEFAULT_PPOCR_PRECISION, DEFAULT_RECURSIVE, DEFAULT_PPOCR_FILE_PATTERN, DEFAULT_LABEL_STUDIO_FILE_PATTERN, OUTPUT_MODE_ANNOTATIONS, OUTPUT_MODE_PREDICTIONS, DEFAULT_OUTPUT_MODE, DEFAULT_BACKUP, BACKUP_SUFFIX_PREFIX, DEFAULT_COPY_IMAGES;
|
|
41
|
+
var DEFAULT_DETECT_IMAGE_SIZE, DEFAULT_LABEL_NAME, DEFAULT_LABEL_STUDIO_FULL_JSON, DEFAULT_CREATE_FILE_PER_IMAGE, DEFAULT_CREATE_FILE_LIST_FOR_SERVING, DEFAULT_FILE_LIST_NAME, DEFAULT_BASE_SERVER_URL, DEFAULT_PPOCR_FILE_NAME, SORT_VERTICAL_NONE, SORT_VERTICAL_TOP_BOTTOM, SORT_VERTICAL_BOTTOM_TOP, DEFAULT_SORT_VERTICAL, SORT_HORIZONTAL_NONE, SORT_HORIZONTAL_LTR, SORT_HORIZONTAL_RTL, DEFAULT_SORT_HORIZONTAL, SHAPE_NORMALIZE_NONE, SHAPE_NORMALIZE_RECTANGLE, DEFAULT_SHAPE_NORMALIZE, DEFAULT_USE_ORIENTED_BOX, DEFAULT_WIDTH_INCREMENT, DEFAULT_HEIGHT_INCREMENT, DEFAULT_ADAPT_RESIZE, DEFAULT_ADAPT_RESIZE_THRESHOLD, DEFAULT_ADAPT_RESIZE_MARGIN, DEFAULT_ADAPT_RESIZE_MIN_COMPONENT_SIZE, DEFAULT_ADAPT_RESIZE_MAX_COMPONENT_SIZE, DEFAULT_ADAPT_RESIZE_OUTLIER_PERCENTILE, DEFAULT_ADAPT_RESIZE_MORPHOLOGY_SIZE, DEFAULT_ADAPT_RESIZE_MAX_HORIZONTAL_EXPANSION, DEFAULT_ADAPT_RESIZE_TIMEOUT_MS, DEFAULT_ADAPT_RESIZE_MAX_BOX_SIZE, DEFAULT_ADAPT_RESIZE_PADDING_CHECK_WIDTH, DEFAULT_ADAPT_RESIZE_MIN_PADDING_BRIGHTNESS, DEFAULT_ADAPT_RESIZE_MIN_PADDING_RATIO, DEFAULT_ADAPT_RESIZE_USE_ADAPTIVE_THRESHOLD, DEFAULT_ADAPT_RESIZE_ADAPTIVE_BLOCK_SIZE, DEFAULT_LABEL_STUDIO_PRECISION, DEFAULT_PPOCR_PRECISION, DEFAULT_RECURSIVE, DEFAULT_PPOCR_FILE_PATTERN, DEFAULT_LABEL_STUDIO_FILE_PATTERN, OUTPUT_MODE_ANNOTATIONS, OUTPUT_MODE_PREDICTIONS, DEFAULT_OUTPUT_MODE, DEFAULT_BACKUP, BACKUP_SUFFIX_PREFIX, DEFAULT_COPY_IMAGES, IMAGE_BASE_DIR_TASK_FILE, IMAGE_BASE_DIR_INPUT_DIR, DEFAULT_IMAGE_BASE_DIR, DEFAULT_LABEL_STUDIO_OUTPUT_IMAGE_BASE_DIR;
|
|
42
42
|
var init_constants = __esm({
|
|
43
43
|
"src/constants.ts"() {
|
|
44
44
|
"use strict";
|
|
@@ -65,6 +65,7 @@ var init_constants = __esm({
|
|
|
65
65
|
DEFAULT_USE_ORIENTED_BOX = false;
|
|
66
66
|
DEFAULT_WIDTH_INCREMENT = 0;
|
|
67
67
|
DEFAULT_HEIGHT_INCREMENT = 0;
|
|
68
|
+
DEFAULT_ADAPT_RESIZE = false;
|
|
68
69
|
DEFAULT_ADAPT_RESIZE_THRESHOLD = 128;
|
|
69
70
|
DEFAULT_ADAPT_RESIZE_MARGIN = 5;
|
|
70
71
|
DEFAULT_ADAPT_RESIZE_MIN_COMPONENT_SIZE = 10;
|
|
@@ -72,8 +73,13 @@ var init_constants = __esm({
|
|
|
72
73
|
DEFAULT_ADAPT_RESIZE_OUTLIER_PERCENTILE = 2;
|
|
73
74
|
DEFAULT_ADAPT_RESIZE_MORPHOLOGY_SIZE = 2;
|
|
74
75
|
DEFAULT_ADAPT_RESIZE_MAX_HORIZONTAL_EXPANSION = 50;
|
|
75
|
-
DEFAULT_ADAPT_RESIZE_TIMEOUT_MS =
|
|
76
|
+
DEFAULT_ADAPT_RESIZE_TIMEOUT_MS = 15e3;
|
|
76
77
|
DEFAULT_ADAPT_RESIZE_MAX_BOX_SIZE = 3e3;
|
|
78
|
+
DEFAULT_ADAPT_RESIZE_PADDING_CHECK_WIDTH = 3;
|
|
79
|
+
DEFAULT_ADAPT_RESIZE_MIN_PADDING_BRIGHTNESS = 200;
|
|
80
|
+
DEFAULT_ADAPT_RESIZE_MIN_PADDING_RATIO = 0.85;
|
|
81
|
+
DEFAULT_ADAPT_RESIZE_USE_ADAPTIVE_THRESHOLD = true;
|
|
82
|
+
DEFAULT_ADAPT_RESIZE_ADAPTIVE_BLOCK_SIZE = 50;
|
|
77
83
|
DEFAULT_LABEL_STUDIO_PRECISION = -1;
|
|
78
84
|
DEFAULT_PPOCR_PRECISION = 0;
|
|
79
85
|
DEFAULT_RECURSIVE = false;
|
|
@@ -85,6 +91,10 @@ var init_constants = __esm({
|
|
|
85
91
|
DEFAULT_BACKUP = false;
|
|
86
92
|
BACKUP_SUFFIX_PREFIX = "backup-";
|
|
87
93
|
DEFAULT_COPY_IMAGES = true;
|
|
94
|
+
IMAGE_BASE_DIR_TASK_FILE = "task-file";
|
|
95
|
+
IMAGE_BASE_DIR_INPUT_DIR = "input-dir";
|
|
96
|
+
DEFAULT_IMAGE_BASE_DIR = IMAGE_BASE_DIR_TASK_FILE;
|
|
97
|
+
DEFAULT_LABEL_STUDIO_OUTPUT_IMAGE_BASE_DIR = "/data/local-files/?d=";
|
|
88
98
|
}
|
|
89
99
|
});
|
|
90
100
|
|
|
@@ -92,11 +102,17 @@ var init_constants = __esm({
|
|
|
92
102
|
function withOptions(fn, options) {
|
|
93
103
|
return [fn, options];
|
|
94
104
|
}
|
|
95
|
-
var Processor;
|
|
105
|
+
var defaultResolveInputImagePath, defaultResolveOutputImagePath, Processor;
|
|
96
106
|
var init_processor = __esm({
|
|
97
107
|
"src/lib/processor.ts"() {
|
|
98
108
|
"use strict";
|
|
99
109
|
init_cjs_shims();
|
|
110
|
+
defaultResolveInputImagePath = (taskImagePath) => {
|
|
111
|
+
return taskImagePath;
|
|
112
|
+
};
|
|
113
|
+
defaultResolveOutputImagePath = (taskImagePath) => {
|
|
114
|
+
return taskImagePath;
|
|
115
|
+
};
|
|
100
116
|
Processor = class {
|
|
101
117
|
input;
|
|
102
118
|
output;
|
|
@@ -113,8 +129,8 @@ var init_processor = __esm({
|
|
|
113
129
|
async process({
|
|
114
130
|
inputData,
|
|
115
131
|
taskFilePath,
|
|
116
|
-
resolveInputImagePath,
|
|
117
|
-
resolveOutputImagePath
|
|
132
|
+
resolveInputImagePath = defaultResolveInputImagePath,
|
|
133
|
+
resolveOutputImagePath = defaultResolveOutputImagePath
|
|
118
134
|
}) {
|
|
119
135
|
const [inputFn, inputOptions] = Array.isArray(this.input) ? this.input : [this.input, void 0];
|
|
120
136
|
const [outputFn, outputOptions] = Array.isArray(this.output) ? this.output : [this.output, void 0];
|
|
@@ -540,10 +556,62 @@ function withTimeout(promise, timeoutMs, timeoutValue) {
|
|
|
540
556
|
return Promise.race([
|
|
541
557
|
promise,
|
|
542
558
|
new Promise(
|
|
543
|
-
(
|
|
559
|
+
(resolve4) => setTimeout(() => resolve4(timeoutValue), timeoutMs)
|
|
544
560
|
)
|
|
545
561
|
]);
|
|
546
562
|
}
|
|
563
|
+
function calculateAdaptiveThreshold(grayscaleData, width, height) {
|
|
564
|
+
const histogram = new Array(256).fill(0);
|
|
565
|
+
for (let i = 0; i < grayscaleData.length; i++) {
|
|
566
|
+
const pixelValue = grayscaleData[i];
|
|
567
|
+
if (pixelValue !== void 0) {
|
|
568
|
+
histogram[pixelValue]++;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
const totalPixels = width * height;
|
|
572
|
+
let sum = 0;
|
|
573
|
+
for (let i = 0; i < 256; i++) {
|
|
574
|
+
sum += i * histogram[i];
|
|
575
|
+
}
|
|
576
|
+
let sumB = 0;
|
|
577
|
+
let wB = 0;
|
|
578
|
+
let wF = 0;
|
|
579
|
+
let maxVariance = 0;
|
|
580
|
+
let threshold = 0;
|
|
581
|
+
for (let t = 0; t < 256; t++) {
|
|
582
|
+
wB += histogram[t];
|
|
583
|
+
if (wB === 0) continue;
|
|
584
|
+
wF = totalPixels - wB;
|
|
585
|
+
if (wF === 0) break;
|
|
586
|
+
sumB += t * histogram[t];
|
|
587
|
+
const mB = sumB / wB;
|
|
588
|
+
const mF = (sum - sumB) / wF;
|
|
589
|
+
const variance = wB * wF * (mB - mF) * (mB - mF);
|
|
590
|
+
if (variance > maxVariance) {
|
|
591
|
+
maxVariance = variance;
|
|
592
|
+
threshold = t;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
return Math.max(100, Math.min(200, threshold + 10));
|
|
596
|
+
}
|
|
597
|
+
function validatePaddingStrip(grayscaleData, x1, y1, x2, y2, width, height, minBrightness, minRatio) {
|
|
598
|
+
let totalPixels = 0;
|
|
599
|
+
let whitePixels = 0;
|
|
600
|
+
for (let y = Math.floor(y1); y <= Math.ceil(y2); y++) {
|
|
601
|
+
for (let x = Math.floor(x1); x <= Math.ceil(x2); x++) {
|
|
602
|
+
if (x >= 0 && x < width && y >= 0 && y < height) {
|
|
603
|
+
totalPixels++;
|
|
604
|
+
const idx = y * width + x;
|
|
605
|
+
const pixelValue = grayscaleData[idx];
|
|
606
|
+
if (pixelValue !== void 0 && pixelValue >= minBrightness) {
|
|
607
|
+
whitePixels++;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
if (totalPixels === 0) return false;
|
|
613
|
+
return whitePixels / totalPixels >= minRatio;
|
|
614
|
+
}
|
|
547
615
|
async function adaptiveResizeBoundingBox(points, imagePath, options) {
|
|
548
616
|
if (points.length === 0 || !(0, import_node_fs.existsSync)(imagePath)) {
|
|
549
617
|
return points;
|
|
@@ -555,7 +623,11 @@ async function adaptiveResizeBoundingBox(points, imagePath, options) {
|
|
|
555
623
|
maxComponentSize = DEFAULT_ADAPT_RESIZE_MAX_COMPONENT_SIZE,
|
|
556
624
|
outlierPercentile = DEFAULT_ADAPT_RESIZE_OUTLIER_PERCENTILE,
|
|
557
625
|
morphologySize = DEFAULT_ADAPT_RESIZE_MORPHOLOGY_SIZE,
|
|
558
|
-
maxHorizontalExpansion = DEFAULT_ADAPT_RESIZE_MAX_HORIZONTAL_EXPANSION
|
|
626
|
+
maxHorizontalExpansion = DEFAULT_ADAPT_RESIZE_MAX_HORIZONTAL_EXPANSION,
|
|
627
|
+
paddingCheckWidth = DEFAULT_ADAPT_RESIZE_PADDING_CHECK_WIDTH,
|
|
628
|
+
minPaddingBrightness = DEFAULT_ADAPT_RESIZE_MIN_PADDING_BRIGHTNESS,
|
|
629
|
+
minPaddingRatio = DEFAULT_ADAPT_RESIZE_MIN_PADDING_RATIO,
|
|
630
|
+
useAdaptiveThreshold = DEFAULT_ADAPT_RESIZE_USE_ADAPTIVE_THRESHOLD
|
|
559
631
|
} = options;
|
|
560
632
|
try {
|
|
561
633
|
const rotation = getBoxRotation(points);
|
|
@@ -600,14 +672,30 @@ async function adaptiveResizeBoundingBox(points, imagePath, options) {
|
|
|
600
672
|
if (analysisW <= 0 || analysisH <= 0) {
|
|
601
673
|
return points;
|
|
602
674
|
}
|
|
603
|
-
const
|
|
675
|
+
const grayscaleImage = image.extract({
|
|
604
676
|
left: analysisX,
|
|
605
677
|
top: analysisY,
|
|
606
678
|
width: analysisW,
|
|
607
679
|
height: analysisH
|
|
608
|
-
}).grayscale()
|
|
680
|
+
}).grayscale();
|
|
681
|
+
const { data: grayscaleData, info: grayscaleInfo } = await grayscaleImage.raw().toBuffer({ resolveWithObject: true });
|
|
682
|
+
let actualThreshold = threshold;
|
|
683
|
+
if (useAdaptiveThreshold) {
|
|
684
|
+
actualThreshold = calculateAdaptiveThreshold(
|
|
685
|
+
grayscaleData,
|
|
686
|
+
grayscaleInfo.width,
|
|
687
|
+
grayscaleInfo.height
|
|
688
|
+
);
|
|
689
|
+
}
|
|
690
|
+
const { data: binaryData, info } = await (0, import_sharp.default)(grayscaleData, {
|
|
691
|
+
raw: {
|
|
692
|
+
width: grayscaleInfo.width,
|
|
693
|
+
height: grayscaleInfo.height,
|
|
694
|
+
channels: 1
|
|
695
|
+
}
|
|
696
|
+
}).threshold(actualThreshold).raw().toBuffer({ resolveWithObject: true });
|
|
609
697
|
const morphed = morphologicalClosing(
|
|
610
|
-
|
|
698
|
+
binaryData,
|
|
611
699
|
info.width,
|
|
612
700
|
info.height,
|
|
613
701
|
morphologySize
|
|
@@ -616,7 +704,7 @@ async function adaptiveResizeBoundingBox(points, imagePath, options) {
|
|
|
616
704
|
morphed,
|
|
617
705
|
info.width,
|
|
618
706
|
info.height,
|
|
619
|
-
|
|
707
|
+
actualThreshold
|
|
620
708
|
);
|
|
621
709
|
const validComponents = components.filter(
|
|
622
710
|
(comp) => comp.size >= minComponentSize && comp.size <= maxComponentSize
|
|
@@ -643,10 +731,10 @@ async function adaptiveResizeBoundingBox(points, imagePath, options) {
|
|
|
643
731
|
const minY = sortedY[0] || 0;
|
|
644
732
|
const maxY = sortedY[sortedY.length - 1] || info.height - 1;
|
|
645
733
|
const detectSeparator = createSeparatorDetector({
|
|
646
|
-
data,
|
|
734
|
+
data: binaryData,
|
|
647
735
|
width: info.width,
|
|
648
736
|
height: info.height,
|
|
649
|
-
threshold
|
|
737
|
+
threshold: actualThreshold
|
|
650
738
|
});
|
|
651
739
|
const originalBoxMinX = x - analysisX;
|
|
652
740
|
const originalBoxMaxX = x - analysisX + w;
|
|
@@ -659,21 +747,142 @@ async function adaptiveResizeBoundingBox(points, imagePath, options) {
|
|
|
659
747
|
detectSeparator,
|
|
660
748
|
info.width
|
|
661
749
|
);
|
|
662
|
-
|
|
750
|
+
let limitedMinX = Math.max(
|
|
663
751
|
leftBoundary,
|
|
664
752
|
originalBoxMinX - maxHorizontalExpansion
|
|
665
753
|
);
|
|
666
|
-
|
|
754
|
+
let limitedMaxX = Math.min(
|
|
667
755
|
rightBoundary,
|
|
668
756
|
originalBoxMaxX + maxHorizontalExpansion
|
|
669
757
|
);
|
|
758
|
+
let limitedMinY = minY;
|
|
759
|
+
let limitedMaxY = maxY;
|
|
760
|
+
const leftPaddingValid = validatePaddingStrip(
|
|
761
|
+
grayscaleData,
|
|
762
|
+
limitedMinX,
|
|
763
|
+
limitedMinY,
|
|
764
|
+
Math.min(limitedMinX + paddingCheckWidth - 1, limitedMaxX),
|
|
765
|
+
limitedMaxY,
|
|
766
|
+
info.width,
|
|
767
|
+
info.height,
|
|
768
|
+
minPaddingBrightness,
|
|
769
|
+
minPaddingRatio
|
|
770
|
+
);
|
|
771
|
+
if (!leftPaddingValid && limitedMinX < originalBoxMinX) {
|
|
772
|
+
for (let i = 0; i < maxHorizontalExpansion; i++) {
|
|
773
|
+
limitedMinX++;
|
|
774
|
+
if (validatePaddingStrip(
|
|
775
|
+
grayscaleData,
|
|
776
|
+
limitedMinX,
|
|
777
|
+
limitedMinY,
|
|
778
|
+
Math.min(limitedMinX + paddingCheckWidth - 1, limitedMaxX),
|
|
779
|
+
limitedMaxY,
|
|
780
|
+
info.width,
|
|
781
|
+
info.height,
|
|
782
|
+
minPaddingBrightness,
|
|
783
|
+
minPaddingRatio
|
|
784
|
+
)) {
|
|
785
|
+
break;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
const rightPaddingValid = validatePaddingStrip(
|
|
790
|
+
grayscaleData,
|
|
791
|
+
Math.max(limitedMaxX - paddingCheckWidth + 1, limitedMinX),
|
|
792
|
+
limitedMinY,
|
|
793
|
+
limitedMaxX,
|
|
794
|
+
limitedMaxY,
|
|
795
|
+
info.width,
|
|
796
|
+
info.height,
|
|
797
|
+
minPaddingBrightness,
|
|
798
|
+
minPaddingRatio
|
|
799
|
+
);
|
|
800
|
+
if (!rightPaddingValid && limitedMaxX > originalBoxMaxX) {
|
|
801
|
+
for (let i = 0; i < maxHorizontalExpansion; i++) {
|
|
802
|
+
limitedMaxX--;
|
|
803
|
+
if (validatePaddingStrip(
|
|
804
|
+
grayscaleData,
|
|
805
|
+
Math.max(limitedMaxX - paddingCheckWidth + 1, limitedMinX),
|
|
806
|
+
limitedMinY,
|
|
807
|
+
limitedMaxX,
|
|
808
|
+
limitedMaxY,
|
|
809
|
+
info.width,
|
|
810
|
+
info.height,
|
|
811
|
+
minPaddingBrightness,
|
|
812
|
+
minPaddingRatio
|
|
813
|
+
)) {
|
|
814
|
+
break;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
const topPaddingValid = validatePaddingStrip(
|
|
819
|
+
grayscaleData,
|
|
820
|
+
limitedMinX,
|
|
821
|
+
limitedMinY,
|
|
822
|
+
limitedMaxX,
|
|
823
|
+
Math.min(limitedMinY + paddingCheckWidth - 1, limitedMaxY),
|
|
824
|
+
info.width,
|
|
825
|
+
info.height,
|
|
826
|
+
minPaddingBrightness,
|
|
827
|
+
minPaddingRatio
|
|
828
|
+
);
|
|
829
|
+
if (!topPaddingValid && limitedMinY > 0) {
|
|
830
|
+
for (let i = 0; i < 20; i++) {
|
|
831
|
+
limitedMinY++;
|
|
832
|
+
if (validatePaddingStrip(
|
|
833
|
+
grayscaleData,
|
|
834
|
+
limitedMinX,
|
|
835
|
+
limitedMinY,
|
|
836
|
+
limitedMaxX,
|
|
837
|
+
Math.min(limitedMinY + paddingCheckWidth - 1, limitedMaxY),
|
|
838
|
+
info.width,
|
|
839
|
+
info.height,
|
|
840
|
+
minPaddingBrightness,
|
|
841
|
+
minPaddingRatio
|
|
842
|
+
)) {
|
|
843
|
+
break;
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
const bottomPaddingValid = validatePaddingStrip(
|
|
848
|
+
grayscaleData,
|
|
849
|
+
limitedMinX,
|
|
850
|
+
Math.max(limitedMaxY - paddingCheckWidth + 1, limitedMinY),
|
|
851
|
+
limitedMaxX,
|
|
852
|
+
limitedMaxY,
|
|
853
|
+
info.width,
|
|
854
|
+
info.height,
|
|
855
|
+
minPaddingBrightness,
|
|
856
|
+
minPaddingRatio
|
|
857
|
+
);
|
|
858
|
+
if (!bottomPaddingValid && limitedMaxY < info.height - 1) {
|
|
859
|
+
for (let i = 0; i < 20; i++) {
|
|
860
|
+
limitedMaxY--;
|
|
861
|
+
if (validatePaddingStrip(
|
|
862
|
+
grayscaleData,
|
|
863
|
+
limitedMinX,
|
|
864
|
+
Math.max(limitedMaxY - paddingCheckWidth + 1, limitedMinY),
|
|
865
|
+
limitedMaxX,
|
|
866
|
+
limitedMaxY,
|
|
867
|
+
info.width,
|
|
868
|
+
info.height,
|
|
869
|
+
minPaddingBrightness,
|
|
870
|
+
minPaddingRatio
|
|
871
|
+
)) {
|
|
872
|
+
break;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
670
876
|
const newMinX = Math.max(0, analysisX + limitedMinX - margin);
|
|
671
|
-
const newMinY = Math.max(0, analysisY +
|
|
877
|
+
const newMinY = Math.max(0, analysisY + limitedMinY - margin);
|
|
672
878
|
const newMaxX = Math.min(
|
|
673
879
|
metadata.width,
|
|
674
880
|
analysisX + limitedMaxX + 1 + margin
|
|
675
881
|
);
|
|
676
|
-
const newMaxY = Math.min(
|
|
882
|
+
const newMaxY = Math.min(
|
|
883
|
+
metadata.height,
|
|
884
|
+
analysisY + limitedMaxY + 1 + margin
|
|
885
|
+
);
|
|
677
886
|
if (isRotated) {
|
|
678
887
|
const center = calculateCenter(points);
|
|
679
888
|
const cos = Math.cos(rotation);
|
|
@@ -720,13 +929,18 @@ var init_adapt_resize = __esm({
|
|
|
720
929
|
init_separator_detection();
|
|
721
930
|
adaptResizeTransformer = (async (boxes, imageFilePath, options) => {
|
|
722
931
|
const {
|
|
723
|
-
threshold =
|
|
724
|
-
margin =
|
|
725
|
-
minComponentSize =
|
|
726
|
-
maxComponentSize =
|
|
727
|
-
outlierPercentile =
|
|
728
|
-
morphologySize =
|
|
729
|
-
maxHorizontalExpansion =
|
|
932
|
+
threshold = DEFAULT_ADAPT_RESIZE_THRESHOLD,
|
|
933
|
+
margin = DEFAULT_ADAPT_RESIZE_MARGIN,
|
|
934
|
+
minComponentSize = DEFAULT_ADAPT_RESIZE_MIN_COMPONENT_SIZE,
|
|
935
|
+
maxComponentSize = DEFAULT_ADAPT_RESIZE_MAX_COMPONENT_SIZE,
|
|
936
|
+
outlierPercentile = DEFAULT_ADAPT_RESIZE_OUTLIER_PERCENTILE,
|
|
937
|
+
morphologySize = DEFAULT_ADAPT_RESIZE_MORPHOLOGY_SIZE,
|
|
938
|
+
maxHorizontalExpansion = DEFAULT_ADAPT_RESIZE_MAX_HORIZONTAL_EXPANSION,
|
|
939
|
+
paddingCheckWidth = DEFAULT_ADAPT_RESIZE_PADDING_CHECK_WIDTH,
|
|
940
|
+
minPaddingBrightness = DEFAULT_ADAPT_RESIZE_MIN_PADDING_BRIGHTNESS,
|
|
941
|
+
minPaddingRatio = DEFAULT_ADAPT_RESIZE_MIN_PADDING_RATIO,
|
|
942
|
+
useAdaptiveThreshold = DEFAULT_ADAPT_RESIZE_USE_ADAPTIVE_THRESHOLD,
|
|
943
|
+
adaptiveBlockSize = DEFAULT_ADAPT_RESIZE_ADAPTIVE_BLOCK_SIZE
|
|
730
944
|
} = options || {};
|
|
731
945
|
if (boxes.length === 0) {
|
|
732
946
|
return boxes;
|
|
@@ -734,6 +948,9 @@ var init_adapt_resize = __esm({
|
|
|
734
948
|
console.log(
|
|
735
949
|
`Processing ${boxes.length} boxes with adaptive resize for: ${imageFilePath}`
|
|
736
950
|
);
|
|
951
|
+
if (useAdaptiveThreshold) {
|
|
952
|
+
console.log(" Using adaptive thresholding based on image histogram");
|
|
953
|
+
}
|
|
737
954
|
const resized = await Promise.all(
|
|
738
955
|
boxes.map(async (box, index) => {
|
|
739
956
|
const newPoints = await withTimeout(
|
|
@@ -744,7 +961,12 @@ var init_adapt_resize = __esm({
|
|
|
744
961
|
maxComponentSize,
|
|
745
962
|
outlierPercentile,
|
|
746
963
|
morphologySize,
|
|
747
|
-
maxHorizontalExpansion
|
|
964
|
+
maxHorizontalExpansion,
|
|
965
|
+
paddingCheckWidth,
|
|
966
|
+
minPaddingBrightness,
|
|
967
|
+
minPaddingRatio,
|
|
968
|
+
useAdaptiveThreshold,
|
|
969
|
+
adaptiveBlockSize
|
|
748
970
|
}),
|
|
749
971
|
DEFAULT_ADAPT_RESIZE_TIMEOUT_MS,
|
|
750
972
|
box.points
|
|
@@ -1186,6 +1408,34 @@ var init_schema3 = __esm({
|
|
|
1186
1408
|
}
|
|
1187
1409
|
});
|
|
1188
1410
|
|
|
1411
|
+
// src/modules/label-studio-output/schema.ts
|
|
1412
|
+
var import_zod5, OutputLabelStudioSchema;
|
|
1413
|
+
var init_schema4 = __esm({
|
|
1414
|
+
"src/modules/label-studio-output/schema.ts"() {
|
|
1415
|
+
"use strict";
|
|
1416
|
+
init_cjs_shims();
|
|
1417
|
+
import_zod5 = __toESM(require("zod"), 1);
|
|
1418
|
+
init_schema();
|
|
1419
|
+
OutputLabelStudioSchema = AnnotationSchema.extend({
|
|
1420
|
+
created_username: import_zod5.default.string(),
|
|
1421
|
+
created_ago: import_zod5.default.string().optional(),
|
|
1422
|
+
completed_by: import_zod5.default.object({
|
|
1423
|
+
id: import_zod5.default.number(),
|
|
1424
|
+
first_name: import_zod5.default.string(),
|
|
1425
|
+
last_name: import_zod5.default.string(),
|
|
1426
|
+
email: import_zod5.default.string()
|
|
1427
|
+
}),
|
|
1428
|
+
task: FullOCRLabelStudioSchema.omit({
|
|
1429
|
+
annotations: true,
|
|
1430
|
+
predictions: true,
|
|
1431
|
+
drafts: true
|
|
1432
|
+
}).extend({
|
|
1433
|
+
overlap: import_zod5.default.number()
|
|
1434
|
+
})
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1437
|
+
});
|
|
1438
|
+
|
|
1189
1439
|
// src/lib/image.ts
|
|
1190
1440
|
var import_node_fs2, import_promises, import_image_size, getImageDimensions;
|
|
1191
1441
|
var init_image = __esm({
|
|
@@ -1616,6 +1866,68 @@ var init_output3 = __esm({
|
|
|
1616
1866
|
}
|
|
1617
1867
|
});
|
|
1618
1868
|
|
|
1869
|
+
// src/modules/label-studio-output/input.ts
|
|
1870
|
+
var import_es_toolkit3, OutputLabelStudioInput;
|
|
1871
|
+
var init_input4 = __esm({
|
|
1872
|
+
"src/modules/label-studio-output/input.ts"() {
|
|
1873
|
+
"use strict";
|
|
1874
|
+
init_cjs_shims();
|
|
1875
|
+
import_es_toolkit3 = require("es-toolkit");
|
|
1876
|
+
init_geometry();
|
|
1877
|
+
OutputLabelStudioInput = (async (inputTask, resolveImagePath) => {
|
|
1878
|
+
const imageFilePath = await resolveImagePath(inputTask.task.data.ocr);
|
|
1879
|
+
const { id, result, ...metadata } = inputTask;
|
|
1880
|
+
const annoData = result;
|
|
1881
|
+
const imageMeta = annoData?.find(
|
|
1882
|
+
(item) => item.original_height !== void 0 && item.original_width !== void 0
|
|
1883
|
+
);
|
|
1884
|
+
let { original_height: imgHeight, original_width: imgWidth } = imageMeta ?? {};
|
|
1885
|
+
const groupByAnnoId = (0, import_es_toolkit3.groupBy)(annoData || [], (item) => item.id);
|
|
1886
|
+
return {
|
|
1887
|
+
id: id.toString(),
|
|
1888
|
+
height: imgHeight,
|
|
1889
|
+
width: imgWidth,
|
|
1890
|
+
imagePath: imageFilePath,
|
|
1891
|
+
metadata,
|
|
1892
|
+
boxes: Object.entries(groupByAnnoId).map(([annoId, items]) => {
|
|
1893
|
+
let baseAnno = {};
|
|
1894
|
+
for (const item of items) {
|
|
1895
|
+
baseAnno = { ...baseAnno, ...item.value };
|
|
1896
|
+
}
|
|
1897
|
+
let newPoints = "points" in baseAnno ? tupleToPoints(baseAnno.points) : [];
|
|
1898
|
+
if (newPoints.length === 0 && "x" in baseAnno && "y" in baseAnno && "width" in baseAnno && "height" in baseAnno) {
|
|
1899
|
+
newPoints = rectangleToPoints(
|
|
1900
|
+
baseAnno.x,
|
|
1901
|
+
baseAnno.y,
|
|
1902
|
+
baseAnno.width,
|
|
1903
|
+
baseAnno.height,
|
|
1904
|
+
imgWidth,
|
|
1905
|
+
imgHeight
|
|
1906
|
+
);
|
|
1907
|
+
}
|
|
1908
|
+
return {
|
|
1909
|
+
id: annoId,
|
|
1910
|
+
points: newPoints,
|
|
1911
|
+
metadata: baseAnno,
|
|
1912
|
+
score: imageMeta?.score,
|
|
1913
|
+
text: "text" in baseAnno ? Array.isArray(baseAnno.text) ? baseAnno.text.join(" ") : baseAnno.text : void 0
|
|
1914
|
+
};
|
|
1915
|
+
})
|
|
1916
|
+
};
|
|
1917
|
+
});
|
|
1918
|
+
}
|
|
1919
|
+
});
|
|
1920
|
+
|
|
1921
|
+
// src/modules/label-studio-output/output.ts
|
|
1922
|
+
var init_output4 = __esm({
|
|
1923
|
+
"src/modules/label-studio-output/output.ts"() {
|
|
1924
|
+
"use strict";
|
|
1925
|
+
init_cjs_shims();
|
|
1926
|
+
init_constants();
|
|
1927
|
+
init_geometry();
|
|
1928
|
+
}
|
|
1929
|
+
});
|
|
1930
|
+
|
|
1619
1931
|
// src/config.ts
|
|
1620
1932
|
var baseFileIOFlagOptions, baseEnhanceFlagOptions;
|
|
1621
1933
|
var init_config = __esm({
|
|
@@ -1656,6 +1968,12 @@ var init_config = __esm({
|
|
|
1656
1968
|
kind: "boolean",
|
|
1657
1969
|
brief: `Copy images to output directory when --outDir is specified. Only applies to toLabelStudio and toPPOCR commands. Default: ${DEFAULT_COPY_IMAGES}`,
|
|
1658
1970
|
optional: true
|
|
1971
|
+
},
|
|
1972
|
+
imageBaseDir: {
|
|
1973
|
+
kind: "parsed",
|
|
1974
|
+
brief: `Base directory for resolving image paths. Options: "${IMAGE_BASE_DIR_TASK_FILE}" (relative to task file location), "${IMAGE_BASE_DIR_INPUT_DIR}" (relative to command execution directory). Default: "${DEFAULT_IMAGE_BASE_DIR}"`,
|
|
1975
|
+
parse: String,
|
|
1976
|
+
optional: true
|
|
1659
1977
|
}
|
|
1660
1978
|
};
|
|
1661
1979
|
baseEnhanceFlagOptions = {
|
|
@@ -1696,7 +2014,7 @@ var init_config = __esm({
|
|
|
1696
2014
|
},
|
|
1697
2015
|
adaptResize: {
|
|
1698
2016
|
kind: "boolean",
|
|
1699
|
-
brief: `Apply adaptive resize to automatically adjust bounding boxes based on image content. Default:
|
|
2017
|
+
brief: `Apply adaptive resize to automatically adjust bounding boxes based on image content. Default: ${DEFAULT_ADAPT_RESIZE}`,
|
|
1700
2018
|
optional: true
|
|
1701
2019
|
},
|
|
1702
2020
|
adaptResizeThreshold: {
|
|
@@ -1741,6 +2059,35 @@ var init_config = __esm({
|
|
|
1741
2059
|
parse: Number,
|
|
1742
2060
|
optional: true
|
|
1743
2061
|
},
|
|
2062
|
+
adaptResizePaddingCheckWidth: {
|
|
2063
|
+
kind: "parsed",
|
|
2064
|
+
brief: `Width of padding strip to validate (in pixels). Default: ${DEFAULT_ADAPT_RESIZE_PADDING_CHECK_WIDTH}`,
|
|
2065
|
+
parse: Number,
|
|
2066
|
+
optional: true
|
|
2067
|
+
},
|
|
2068
|
+
adaptResizeMinPaddingBrightness: {
|
|
2069
|
+
kind: "parsed",
|
|
2070
|
+
brief: `Minimum brightness for white padding pixels (0-255). Default: ${DEFAULT_ADAPT_RESIZE_MIN_PADDING_BRIGHTNESS}`,
|
|
2071
|
+
parse: Number,
|
|
2072
|
+
optional: true
|
|
2073
|
+
},
|
|
2074
|
+
adaptResizeMinPaddingRatio: {
|
|
2075
|
+
kind: "parsed",
|
|
2076
|
+
brief: `Minimum ratio of white pixels in padding strip (0-1). Default: ${DEFAULT_ADAPT_RESIZE_MIN_PADDING_RATIO}`,
|
|
2077
|
+
parse: Number,
|
|
2078
|
+
optional: true
|
|
2079
|
+
},
|
|
2080
|
+
adaptResizeUseAdaptiveThreshold: {
|
|
2081
|
+
kind: "boolean",
|
|
2082
|
+
brief: `Use adaptive thresholding based on image histogram (recommended). Default: ${DEFAULT_ADAPT_RESIZE_USE_ADAPTIVE_THRESHOLD}`,
|
|
2083
|
+
optional: true
|
|
2084
|
+
},
|
|
2085
|
+
adaptResizeAdaptiveBlockSize: {
|
|
2086
|
+
kind: "parsed",
|
|
2087
|
+
brief: `Block size for adaptive thresholding. Default: ${DEFAULT_ADAPT_RESIZE_ADAPTIVE_BLOCK_SIZE}`,
|
|
2088
|
+
parse: Number,
|
|
2089
|
+
optional: true
|
|
2090
|
+
},
|
|
1744
2091
|
precision: {
|
|
1745
2092
|
kind: "parsed",
|
|
1746
2093
|
brief: `Number of decimal places for coordinates. Use -1 for full precision (no rounding). Default: ${DEFAULT_PPOCR_PRECISION} (integers)`,
|
|
@@ -1764,13 +2111,14 @@ var init_label_studio_to_ppocr = __esm({
|
|
|
1764
2111
|
fullLabelStudioToPPOCRConverters = async (inputTasks, taskFilePath, outputDir, options) => {
|
|
1765
2112
|
const {
|
|
1766
2113
|
baseImageDir,
|
|
2114
|
+
imageBaseDir: _imageBaseDir,
|
|
1767
2115
|
sortVertical,
|
|
1768
2116
|
sortHorizontal,
|
|
1769
2117
|
normalizeShape,
|
|
1770
2118
|
useOrientedBox,
|
|
1771
2119
|
widthIncrement,
|
|
1772
2120
|
heightIncrement,
|
|
1773
|
-
adaptResize
|
|
2121
|
+
adaptResize,
|
|
1774
2122
|
adaptResizeThreshold,
|
|
1775
2123
|
adaptResizeMargin,
|
|
1776
2124
|
adaptResizeMinComponentSize,
|
|
@@ -1814,13 +2162,13 @@ var init_label_studio_to_ppocr = __esm({
|
|
|
1814
2162
|
const filename = (0, import_path.basename)(urlPath);
|
|
1815
2163
|
const fileDir2 = (0, import_path.dirname)(taskFilePath2);
|
|
1816
2164
|
const localPath = (0, import_path.join)(fileDir2, filename);
|
|
1817
|
-
await new Promise((
|
|
2165
|
+
await new Promise((resolve4, reject) => {
|
|
1818
2166
|
(0, import_https.get)(taskImagePath, (response) => {
|
|
1819
2167
|
const fileStream = (0, import_fs.createWriteStream)(localPath);
|
|
1820
2168
|
response.pipe(fileStream);
|
|
1821
2169
|
fileStream.on("finish", () => {
|
|
1822
2170
|
fileStream.close();
|
|
1823
|
-
|
|
2171
|
+
resolve4();
|
|
1824
2172
|
});
|
|
1825
2173
|
fileStream.on("error", reject);
|
|
1826
2174
|
}).on("error", reject);
|
|
@@ -1861,13 +2209,14 @@ var init_label_studio_to_ppocr = __esm({
|
|
|
1861
2209
|
minLabelStudioToPPOCRConverters = async (inputTasks, taskFilePath, outputDir, options) => {
|
|
1862
2210
|
const {
|
|
1863
2211
|
baseImageDir,
|
|
2212
|
+
imageBaseDir: _imageBaseDir,
|
|
1864
2213
|
sortVertical,
|
|
1865
2214
|
sortHorizontal,
|
|
1866
2215
|
normalizeShape,
|
|
1867
2216
|
useOrientedBox,
|
|
1868
2217
|
widthIncrement,
|
|
1869
2218
|
heightIncrement,
|
|
1870
|
-
adaptResize
|
|
2219
|
+
adaptResize,
|
|
1871
2220
|
adaptResizeThreshold,
|
|
1872
2221
|
adaptResizeMargin,
|
|
1873
2222
|
adaptResizeMinComponentSize,
|
|
@@ -1911,13 +2260,13 @@ var init_label_studio_to_ppocr = __esm({
|
|
|
1911
2260
|
const filename = (0, import_path.basename)(urlPath);
|
|
1912
2261
|
const fileDir2 = (0, import_path.dirname)(taskFilePath2);
|
|
1913
2262
|
const localPath = (0, import_path.join)(fileDir2, filename);
|
|
1914
|
-
await new Promise((
|
|
2263
|
+
await new Promise((resolve4, reject) => {
|
|
1915
2264
|
(0, import_https.get)(taskImagePath, (response) => {
|
|
1916
2265
|
const fileStream = (0, import_fs.createWriteStream)(localPath);
|
|
1917
2266
|
response.pipe(fileStream);
|
|
1918
2267
|
fileStream.on("finish", () => {
|
|
1919
2268
|
fileStream.close();
|
|
1920
|
-
|
|
2269
|
+
resolve4();
|
|
1921
2270
|
});
|
|
1922
2271
|
fileStream.on("error", reject);
|
|
1923
2272
|
}).on("error", reject);
|
|
@@ -1965,20 +2314,26 @@ var init_ppocr_to_label_studio = __esm({
|
|
|
1965
2314
|
"use strict";
|
|
1966
2315
|
init_cjs_shims();
|
|
1967
2316
|
import_path2 = require("path");
|
|
2317
|
+
init_constants();
|
|
1968
2318
|
init_lib();
|
|
1969
2319
|
ppocrToFullLabelStudioConverters = async (inputTasks, taskFilePath, options) => {
|
|
1970
2320
|
const {
|
|
1971
2321
|
baseServerUrl,
|
|
1972
2322
|
defaultLabelName,
|
|
1973
|
-
|
|
1974
|
-
|
|
2323
|
+
outputMode,
|
|
2324
|
+
outDir: _outDir,
|
|
2325
|
+
// Keep for potential future use
|
|
2326
|
+
copyImages: _copyImages = false,
|
|
2327
|
+
// Keep for potential future use
|
|
2328
|
+
imageBaseDir,
|
|
2329
|
+
inputBaseDir,
|
|
1975
2330
|
sortVertical,
|
|
1976
2331
|
sortHorizontal,
|
|
1977
2332
|
normalizeShape,
|
|
1978
2333
|
useOrientedBox,
|
|
1979
2334
|
widthIncrement,
|
|
1980
2335
|
heightIncrement,
|
|
1981
|
-
adaptResize
|
|
2336
|
+
adaptResize,
|
|
1982
2337
|
adaptResizeThreshold,
|
|
1983
2338
|
adaptResizeMargin,
|
|
1984
2339
|
adaptResizeMinComponentSize,
|
|
@@ -1986,6 +2341,11 @@ var init_ppocr_to_label_studio = __esm({
|
|
|
1986
2341
|
adaptResizeOutlierPercentile,
|
|
1987
2342
|
adaptResizeMorphologySize,
|
|
1988
2343
|
adaptResizeMaxHorizontalExpansion,
|
|
2344
|
+
adaptResizePaddingCheckWidth,
|
|
2345
|
+
adaptResizeMinPaddingBrightness,
|
|
2346
|
+
adaptResizeMinPaddingRatio,
|
|
2347
|
+
adaptResizeUseAdaptiveThreshold,
|
|
2348
|
+
adaptResizeAdaptiveBlockSize,
|
|
1989
2349
|
precision
|
|
1990
2350
|
} = options;
|
|
1991
2351
|
const transformerParams = [
|
|
@@ -2005,7 +2365,12 @@ var init_ppocr_to_label_studio = __esm({
|
|
|
2005
2365
|
maxComponentSize: adaptResizeMaxComponentSize,
|
|
2006
2366
|
outlierPercentile: adaptResizeOutlierPercentile,
|
|
2007
2367
|
morphologySize: adaptResizeMorphologySize,
|
|
2008
|
-
maxHorizontalExpansion: adaptResizeMaxHorizontalExpansion
|
|
2368
|
+
maxHorizontalExpansion: adaptResizeMaxHorizontalExpansion,
|
|
2369
|
+
paddingCheckWidth: adaptResizePaddingCheckWidth,
|
|
2370
|
+
minPaddingBrightness: adaptResizeMinPaddingBrightness,
|
|
2371
|
+
minPaddingRatio: adaptResizeMinPaddingRatio,
|
|
2372
|
+
useAdaptiveThreshold: adaptResizeUseAdaptiveThreshold,
|
|
2373
|
+
adaptiveBlockSize: adaptResizeAdaptiveBlockSize
|
|
2009
2374
|
})
|
|
2010
2375
|
] : [],
|
|
2011
2376
|
withOptions(roundTransformer, {
|
|
@@ -2026,35 +2391,23 @@ var init_ppocr_to_label_studio = __esm({
|
|
|
2026
2391
|
return (0, import_path2.join)(fileDir, taskImagePath);
|
|
2027
2392
|
}
|
|
2028
2393
|
};
|
|
2029
|
-
const resolveOutputImagePath = (taskImagePath,
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
const outputJsonDir = (0, import_path2.resolve)(outDir);
|
|
2033
|
-
if (copyImages) {
|
|
2034
|
-
const fileName = (0, import_path2.basename)(taskImagePath);
|
|
2035
|
-
resolvedPath = fileName;
|
|
2036
|
-
} else {
|
|
2037
|
-
const absoluteImagePath = (0, import_path2.resolve)(process.cwd(), taskImagePath);
|
|
2038
|
-
resolvedPath = (0, import_path2.relative)(outputJsonDir, absoluteImagePath);
|
|
2039
|
-
}
|
|
2040
|
-
} else {
|
|
2041
|
-
const taskDir = (0, import_path2.dirname)(taskFilePath2);
|
|
2042
|
-
resolvedPath = (0, import_path2.relative)(taskDir, taskImagePath);
|
|
2043
|
-
}
|
|
2394
|
+
const resolveOutputImagePath = (taskImagePath, _taskFilePath) => {
|
|
2395
|
+
const relativePath = imageBaseDir === IMAGE_BASE_DIR_INPUT_DIR && inputBaseDir ? (0, import_path2.relative)(inputBaseDir, taskImagePath) : (0, import_path2.basename)(taskImagePath);
|
|
2396
|
+
const resolvedPath = relativePath;
|
|
2044
2397
|
if (baseServerUrl !== void 0) {
|
|
2045
2398
|
if (baseServerUrl === "") {
|
|
2046
2399
|
return encodeURI(`/${resolvedPath}`);
|
|
2047
|
-
} else {
|
|
2048
|
-
const normalizedBaseUrl = baseServerUrl.replace(/\/+$/, "");
|
|
2049
|
-
return encodeURI(`${normalizedBaseUrl}/${resolvedPath}`);
|
|
2050
2400
|
}
|
|
2401
|
+
const normalizedBaseUrl = baseServerUrl.replace(/\/+$/, "");
|
|
2402
|
+
return encodeURI(`${normalizedBaseUrl}/${resolvedPath}`);
|
|
2051
2403
|
}
|
|
2052
2404
|
return resolvedPath;
|
|
2053
2405
|
};
|
|
2054
2406
|
const processor = new Processor({
|
|
2055
2407
|
input: PPOCRInput,
|
|
2056
2408
|
output: withOptions(FullOCRLabelStudioOutput, {
|
|
2057
|
-
defaultLabelName
|
|
2409
|
+
defaultLabelName,
|
|
2410
|
+
outputMode
|
|
2058
2411
|
}),
|
|
2059
2412
|
transformers: transformerParams
|
|
2060
2413
|
});
|
|
@@ -2074,8 +2427,12 @@ var init_ppocr_to_label_studio = __esm({
|
|
|
2074
2427
|
const {
|
|
2075
2428
|
baseServerUrl,
|
|
2076
2429
|
defaultLabelName,
|
|
2077
|
-
outDir,
|
|
2078
|
-
|
|
2430
|
+
outDir: _outDir,
|
|
2431
|
+
// Keep for potential future use
|
|
2432
|
+
copyImages: _copyImages = false,
|
|
2433
|
+
// Keep for potential future use
|
|
2434
|
+
imageBaseDir,
|
|
2435
|
+
inputBaseDir,
|
|
2079
2436
|
sortVertical,
|
|
2080
2437
|
sortHorizontal,
|
|
2081
2438
|
normalizeShape,
|
|
@@ -2111,28 +2468,15 @@ var init_ppocr_to_label_studio = __esm({
|
|
|
2111
2468
|
return (0, import_path2.join)(fileDir, taskImagePath);
|
|
2112
2469
|
}
|
|
2113
2470
|
};
|
|
2114
|
-
const resolveOutputImagePath = (taskImagePath,
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
const outputJsonDir = (0, import_path2.resolve)(outDir);
|
|
2118
|
-
if (copyImages) {
|
|
2119
|
-
const fileName = (0, import_path2.basename)(taskImagePath);
|
|
2120
|
-
resolvedPath = fileName;
|
|
2121
|
-
} else {
|
|
2122
|
-
const absoluteImagePath = (0, import_path2.resolve)(process.cwd(), taskImagePath);
|
|
2123
|
-
resolvedPath = (0, import_path2.relative)(outputJsonDir, absoluteImagePath);
|
|
2124
|
-
}
|
|
2125
|
-
} else {
|
|
2126
|
-
const taskDir = (0, import_path2.dirname)(taskFilePath2);
|
|
2127
|
-
resolvedPath = (0, import_path2.relative)(taskDir, taskImagePath);
|
|
2128
|
-
}
|
|
2471
|
+
const resolveOutputImagePath = (taskImagePath, _taskFilePath) => {
|
|
2472
|
+
const relativePath = imageBaseDir === IMAGE_BASE_DIR_INPUT_DIR && inputBaseDir ? (0, import_path2.relative)(inputBaseDir, taskImagePath) : (0, import_path2.basename)(taskImagePath);
|
|
2473
|
+
const resolvedPath = relativePath;
|
|
2129
2474
|
if (baseServerUrl !== void 0) {
|
|
2130
2475
|
if (baseServerUrl === "") {
|
|
2131
2476
|
return encodeURI(`/${resolvedPath}`);
|
|
2132
|
-
} else {
|
|
2133
|
-
const normalizedBaseUrl = baseServerUrl.replace(/\/+$/, "");
|
|
2134
|
-
return encodeURI(`${normalizedBaseUrl}/${resolvedPath}`);
|
|
2135
2477
|
}
|
|
2478
|
+
const normalizedBaseUrl = baseServerUrl.replace(/\/+$/, "");
|
|
2479
|
+
return encodeURI(`${normalizedBaseUrl}/${resolvedPath}`);
|
|
2136
2480
|
}
|
|
2137
2481
|
return resolvedPath;
|
|
2138
2482
|
};
|
|
@@ -2168,18 +2512,23 @@ var init_enhance_label_studio = __esm({
|
|
|
2168
2512
|
import_fs2 = require("fs");
|
|
2169
2513
|
import_https2 = require("https");
|
|
2170
2514
|
import_path3 = require("path");
|
|
2515
|
+
init_constants();
|
|
2171
2516
|
init_lib();
|
|
2172
2517
|
enhanceFullLabelStudioConverters = async (inputTasks, taskFilePath, options) => {
|
|
2173
2518
|
const {
|
|
2174
2519
|
baseServerUrl,
|
|
2175
|
-
outDir,
|
|
2520
|
+
outDir: _outDir,
|
|
2521
|
+
// Keep for potential future use
|
|
2522
|
+
imageBaseDir,
|
|
2523
|
+
copyImages: _copyImages,
|
|
2524
|
+
inputBaseDir,
|
|
2176
2525
|
sortVertical,
|
|
2177
2526
|
sortHorizontal,
|
|
2178
2527
|
normalizeShape,
|
|
2179
2528
|
useOrientedBox,
|
|
2180
2529
|
widthIncrement,
|
|
2181
2530
|
heightIncrement,
|
|
2182
|
-
adaptResize
|
|
2531
|
+
adaptResize,
|
|
2183
2532
|
adaptResizeThreshold,
|
|
2184
2533
|
adaptResizeMargin,
|
|
2185
2534
|
adaptResizeMinComponentSize,
|
|
@@ -2187,6 +2536,11 @@ var init_enhance_label_studio = __esm({
|
|
|
2187
2536
|
adaptResizeOutlierPercentile,
|
|
2188
2537
|
adaptResizeMorphologySize,
|
|
2189
2538
|
adaptResizeMaxHorizontalExpansion,
|
|
2539
|
+
adaptResizePaddingCheckWidth,
|
|
2540
|
+
adaptResizeMinPaddingBrightness,
|
|
2541
|
+
adaptResizeMinPaddingRatio,
|
|
2542
|
+
adaptResizeUseAdaptiveThreshold,
|
|
2543
|
+
adaptResizeAdaptiveBlockSize,
|
|
2190
2544
|
precision
|
|
2191
2545
|
} = options;
|
|
2192
2546
|
const transformerParams = [
|
|
@@ -2206,7 +2560,12 @@ var init_enhance_label_studio = __esm({
|
|
|
2206
2560
|
maxComponentSize: adaptResizeMaxComponentSize,
|
|
2207
2561
|
outlierPercentile: adaptResizeOutlierPercentile,
|
|
2208
2562
|
morphologySize: adaptResizeMorphologySize,
|
|
2209
|
-
maxHorizontalExpansion: adaptResizeMaxHorizontalExpansion
|
|
2563
|
+
maxHorizontalExpansion: adaptResizeMaxHorizontalExpansion,
|
|
2564
|
+
paddingCheckWidth: adaptResizePaddingCheckWidth,
|
|
2565
|
+
minPaddingBrightness: adaptResizeMinPaddingBrightness,
|
|
2566
|
+
minPaddingRatio: adaptResizeMinPaddingRatio,
|
|
2567
|
+
useAdaptiveThreshold: adaptResizeUseAdaptiveThreshold,
|
|
2568
|
+
adaptiveBlockSize: adaptResizeAdaptiveBlockSize
|
|
2210
2569
|
})
|
|
2211
2570
|
] : [],
|
|
2212
2571
|
withOptions(roundTransformer, {
|
|
@@ -2223,13 +2582,13 @@ var init_enhance_label_studio = __esm({
|
|
|
2223
2582
|
const urlPath = new URL(taskImagePath).pathname;
|
|
2224
2583
|
const filename = (0, import_path3.basename)(urlPath);
|
|
2225
2584
|
const localPath = (0, import_path3.join)(fileDir, filename);
|
|
2226
|
-
await new Promise((
|
|
2585
|
+
await new Promise((resolve4, reject) => {
|
|
2227
2586
|
(0, import_https2.get)(taskImagePath, (response) => {
|
|
2228
2587
|
const fileStream = (0, import_fs2.createWriteStream)(localPath);
|
|
2229
2588
|
response.pipe(fileStream);
|
|
2230
2589
|
fileStream.on("finish", () => {
|
|
2231
2590
|
fileStream.close();
|
|
2232
|
-
|
|
2591
|
+
resolve4();
|
|
2233
2592
|
});
|
|
2234
2593
|
fileStream.on("error", reject);
|
|
2235
2594
|
}).on("error", reject);
|
|
@@ -2239,19 +2598,15 @@ var init_enhance_label_studio = __esm({
|
|
|
2239
2598
|
const cleanPath = taskImagePath.replace(/^\/+/, "");
|
|
2240
2599
|
return (0, import_path3.join)(fileDir, cleanPath);
|
|
2241
2600
|
};
|
|
2242
|
-
const resolveOutputImagePath = (taskImagePath,
|
|
2243
|
-
|
|
2244
|
-
if (
|
|
2245
|
-
|
|
2246
|
-
const relativeDir = (0, import_path3.dirname)(relativePath);
|
|
2247
|
-
const outputSubDir = (0, import_path3.join)(outDir, relativeDir);
|
|
2248
|
-
resolvedPath = (0, import_path3.relative)(outputSubDir, taskImagePath);
|
|
2601
|
+
const resolveOutputImagePath = (taskImagePath, _taskFilePath) => {
|
|
2602
|
+
const relativePath = imageBaseDir === IMAGE_BASE_DIR_INPUT_DIR && inputBaseDir ? (0, import_path3.relative)(inputBaseDir, taskImagePath) : (0, import_path3.basename)(taskImagePath);
|
|
2603
|
+
if (baseServerUrl === void 0) {
|
|
2604
|
+
return relativePath;
|
|
2249
2605
|
}
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
return encodeURI(`${newBaseServerUrl}/${resolvedPath}`);
|
|
2606
|
+
if (baseServerUrl === "") {
|
|
2607
|
+
return "/" + relativePath;
|
|
2253
2608
|
}
|
|
2254
|
-
return
|
|
2609
|
+
return new URL(relativePath, baseServerUrl).href;
|
|
2255
2610
|
};
|
|
2256
2611
|
const processor = new Processor({
|
|
2257
2612
|
input: FullOCRLabelStudioInput,
|
|
@@ -2273,14 +2628,18 @@ var init_enhance_label_studio = __esm({
|
|
|
2273
2628
|
enhanceMinLabelStudioConverters = async (inputTasks, taskFilePath, options) => {
|
|
2274
2629
|
const {
|
|
2275
2630
|
baseServerUrl,
|
|
2276
|
-
outDir,
|
|
2631
|
+
outDir: _outDir,
|
|
2632
|
+
// Keep for potential future use
|
|
2633
|
+
imageBaseDir,
|
|
2634
|
+
copyImages: _copyImages,
|
|
2635
|
+
inputBaseDir,
|
|
2277
2636
|
sortVertical,
|
|
2278
2637
|
sortHorizontal,
|
|
2279
2638
|
normalizeShape,
|
|
2280
2639
|
useOrientedBox,
|
|
2281
2640
|
widthIncrement,
|
|
2282
2641
|
heightIncrement,
|
|
2283
|
-
adaptResize
|
|
2642
|
+
adaptResize,
|
|
2284
2643
|
adaptResizeThreshold,
|
|
2285
2644
|
adaptResizeMargin,
|
|
2286
2645
|
adaptResizeMinComponentSize,
|
|
@@ -2288,6 +2647,11 @@ var init_enhance_label_studio = __esm({
|
|
|
2288
2647
|
adaptResizeOutlierPercentile,
|
|
2289
2648
|
adaptResizeMorphologySize,
|
|
2290
2649
|
adaptResizeMaxHorizontalExpansion,
|
|
2650
|
+
adaptResizePaddingCheckWidth,
|
|
2651
|
+
adaptResizeMinPaddingBrightness,
|
|
2652
|
+
adaptResizeMinPaddingRatio,
|
|
2653
|
+
adaptResizeUseAdaptiveThreshold,
|
|
2654
|
+
adaptResizeAdaptiveBlockSize,
|
|
2291
2655
|
precision
|
|
2292
2656
|
} = options;
|
|
2293
2657
|
const transformerParams = [
|
|
@@ -2307,7 +2671,12 @@ var init_enhance_label_studio = __esm({
|
|
|
2307
2671
|
maxComponentSize: adaptResizeMaxComponentSize,
|
|
2308
2672
|
outlierPercentile: adaptResizeOutlierPercentile,
|
|
2309
2673
|
morphologySize: adaptResizeMorphologySize,
|
|
2310
|
-
maxHorizontalExpansion: adaptResizeMaxHorizontalExpansion
|
|
2674
|
+
maxHorizontalExpansion: adaptResizeMaxHorizontalExpansion,
|
|
2675
|
+
paddingCheckWidth: adaptResizePaddingCheckWidth,
|
|
2676
|
+
minPaddingBrightness: adaptResizeMinPaddingBrightness,
|
|
2677
|
+
minPaddingRatio: adaptResizeMinPaddingRatio,
|
|
2678
|
+
useAdaptiveThreshold: adaptResizeUseAdaptiveThreshold,
|
|
2679
|
+
adaptiveBlockSize: adaptResizeAdaptiveBlockSize
|
|
2311
2680
|
})
|
|
2312
2681
|
] : [],
|
|
2313
2682
|
withOptions(roundTransformer, {
|
|
@@ -2324,13 +2693,13 @@ var init_enhance_label_studio = __esm({
|
|
|
2324
2693
|
const urlPath = new URL(taskImagePath).pathname;
|
|
2325
2694
|
const filename = (0, import_path3.basename)(urlPath);
|
|
2326
2695
|
const localPath = (0, import_path3.join)(fileDir, filename);
|
|
2327
|
-
await new Promise((
|
|
2696
|
+
await new Promise((resolve4, reject) => {
|
|
2328
2697
|
(0, import_https2.get)(taskImagePath, (response) => {
|
|
2329
2698
|
const fileStream = (0, import_fs2.createWriteStream)(localPath);
|
|
2330
2699
|
response.pipe(fileStream);
|
|
2331
2700
|
fileStream.on("finish", () => {
|
|
2332
2701
|
fileStream.close();
|
|
2333
|
-
|
|
2702
|
+
resolve4();
|
|
2334
2703
|
});
|
|
2335
2704
|
fileStream.on("error", reject);
|
|
2336
2705
|
}).on("error", reject);
|
|
@@ -2340,19 +2709,15 @@ var init_enhance_label_studio = __esm({
|
|
|
2340
2709
|
const cleanPath = taskImagePath.replace(/^\/+/, "");
|
|
2341
2710
|
return (0, import_path3.join)(fileDir, cleanPath);
|
|
2342
2711
|
};
|
|
2343
|
-
const resolveOutputImagePath = (taskImagePath,
|
|
2344
|
-
|
|
2345
|
-
if (
|
|
2346
|
-
|
|
2347
|
-
const relativeDir = (0, import_path3.dirname)(relativePath);
|
|
2348
|
-
const outputSubDir = (0, import_path3.join)(outDir, relativeDir);
|
|
2349
|
-
resolvedPath = (0, import_path3.relative)(outputSubDir, taskImagePath);
|
|
2712
|
+
const resolveOutputImagePath = (taskImagePath, _taskFilePath) => {
|
|
2713
|
+
const relativePath = imageBaseDir === IMAGE_BASE_DIR_INPUT_DIR && inputBaseDir ? (0, import_path3.relative)(inputBaseDir, taskImagePath) : (0, import_path3.basename)(taskImagePath);
|
|
2714
|
+
if (baseServerUrl === void 0) {
|
|
2715
|
+
return relativePath;
|
|
2350
2716
|
}
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
return encodeURI(`${newBaseServerUrl}/${resolvedPath}`);
|
|
2717
|
+
if (baseServerUrl === "") {
|
|
2718
|
+
return "/" + relativePath;
|
|
2354
2719
|
}
|
|
2355
|
-
return
|
|
2720
|
+
return new URL(relativePath, baseServerUrl).href;
|
|
2356
2721
|
};
|
|
2357
2722
|
const processor = new Processor({
|
|
2358
2723
|
input: MinOCRLabelStudioInput,
|
|
@@ -2384,13 +2749,14 @@ var init_enhance_ppocr = __esm({
|
|
|
2384
2749
|
init_lib();
|
|
2385
2750
|
enhancePPOCRConverters = async (inputTasks, taskFilePath, options) => {
|
|
2386
2751
|
const {
|
|
2752
|
+
imageBaseDir: _imageBaseDir,
|
|
2387
2753
|
sortVertical,
|
|
2388
2754
|
sortHorizontal,
|
|
2389
2755
|
normalizeShape,
|
|
2390
2756
|
useOrientedBox,
|
|
2391
2757
|
widthIncrement,
|
|
2392
2758
|
heightIncrement,
|
|
2393
|
-
adaptResize
|
|
2759
|
+
adaptResize,
|
|
2394
2760
|
adaptResizeThreshold,
|
|
2395
2761
|
adaptResizeMargin,
|
|
2396
2762
|
adaptResizeMinComponentSize,
|
|
@@ -2398,6 +2764,11 @@ var init_enhance_ppocr = __esm({
|
|
|
2398
2764
|
adaptResizeOutlierPercentile,
|
|
2399
2765
|
adaptResizeMorphologySize,
|
|
2400
2766
|
adaptResizeMaxHorizontalExpansion,
|
|
2767
|
+
adaptResizePaddingCheckWidth,
|
|
2768
|
+
adaptResizeMinPaddingBrightness,
|
|
2769
|
+
adaptResizeMinPaddingRatio,
|
|
2770
|
+
adaptResizeUseAdaptiveThreshold,
|
|
2771
|
+
adaptResizeAdaptiveBlockSize,
|
|
2401
2772
|
precision
|
|
2402
2773
|
} = options;
|
|
2403
2774
|
const transformerParams = [
|
|
@@ -2417,7 +2788,12 @@ var init_enhance_ppocr = __esm({
|
|
|
2417
2788
|
maxComponentSize: adaptResizeMaxComponentSize,
|
|
2418
2789
|
outlierPercentile: adaptResizeOutlierPercentile,
|
|
2419
2790
|
morphologySize: adaptResizeMorphologySize,
|
|
2420
|
-
maxHorizontalExpansion: adaptResizeMaxHorizontalExpansion
|
|
2791
|
+
maxHorizontalExpansion: adaptResizeMaxHorizontalExpansion,
|
|
2792
|
+
paddingCheckWidth: adaptResizePaddingCheckWidth,
|
|
2793
|
+
minPaddingBrightness: adaptResizeMinPaddingBrightness,
|
|
2794
|
+
minPaddingRatio: adaptResizeMinPaddingRatio,
|
|
2795
|
+
useAdaptiveThreshold: adaptResizeUseAdaptiveThreshold,
|
|
2796
|
+
adaptiveBlockSize: adaptResizeAdaptiveBlockSize
|
|
2421
2797
|
})
|
|
2422
2798
|
] : [],
|
|
2423
2799
|
withOptions(roundTransformer, {
|
|
@@ -2463,6 +2839,32 @@ var init_enhance_ppocr = __esm({
|
|
|
2463
2839
|
}
|
|
2464
2840
|
});
|
|
2465
2841
|
|
|
2842
|
+
// src/converters/label-studio-output-to-ppocr.ts
|
|
2843
|
+
var outputLabelStudioToPPOCRConverters;
|
|
2844
|
+
var init_label_studio_output_to_ppocr = __esm({
|
|
2845
|
+
"src/converters/label-studio-output-to-ppocr.ts"() {
|
|
2846
|
+
"use strict";
|
|
2847
|
+
init_cjs_shims();
|
|
2848
|
+
init_lib();
|
|
2849
|
+
outputLabelStudioToPPOCRConverters = async (inputTasks, taskFilePath) => {
|
|
2850
|
+
const processor = new Processor({
|
|
2851
|
+
input: OutputLabelStudioInput,
|
|
2852
|
+
output: PPOCROutput
|
|
2853
|
+
});
|
|
2854
|
+
return await Promise.all(
|
|
2855
|
+
inputTasks.map(async (task) => {
|
|
2856
|
+
const outputData = await processor.process({
|
|
2857
|
+
inputData: task,
|
|
2858
|
+
taskFilePath,
|
|
2859
|
+
resolveOutputImagePath: (taskImagePath) => decodeURI(taskImagePath)
|
|
2860
|
+
});
|
|
2861
|
+
return outputData;
|
|
2862
|
+
})
|
|
2863
|
+
);
|
|
2864
|
+
};
|
|
2865
|
+
}
|
|
2866
|
+
});
|
|
2867
|
+
|
|
2466
2868
|
// src/lib/index.ts
|
|
2467
2869
|
var init_lib = __esm({
|
|
2468
2870
|
"src/lib/index.ts"() {
|
|
@@ -2478,17 +2880,21 @@ var init_lib = __esm({
|
|
|
2478
2880
|
init_schema();
|
|
2479
2881
|
init_schema2();
|
|
2480
2882
|
init_schema3();
|
|
2883
|
+
init_schema4();
|
|
2481
2884
|
init_input();
|
|
2482
2885
|
init_output();
|
|
2483
2886
|
init_input2();
|
|
2484
2887
|
init_output2();
|
|
2485
2888
|
init_input3();
|
|
2486
2889
|
init_output3();
|
|
2890
|
+
init_input4();
|
|
2891
|
+
init_output4();
|
|
2487
2892
|
init_config();
|
|
2488
2893
|
init_label_studio_to_ppocr();
|
|
2489
2894
|
init_ppocr_to_label_studio();
|
|
2490
2895
|
init_enhance_label_studio();
|
|
2491
2896
|
init_enhance_ppocr();
|
|
2897
|
+
init_label_studio_output_to_ppocr();
|
|
2492
2898
|
init_constants();
|
|
2493
2899
|
init_geometry();
|
|
2494
2900
|
}
|
|
@@ -2518,7 +2924,7 @@ var init_backup_utils = __esm({
|
|
|
2518
2924
|
// src/lib/file-utils.ts
|
|
2519
2925
|
async function findFiles(dirs, pattern, recursive) {
|
|
2520
2926
|
const allFiles = [];
|
|
2521
|
-
const regex = new RegExp(pattern);
|
|
2927
|
+
const regex = pattern ? new RegExp(pattern) : null;
|
|
2522
2928
|
async function scanDirectory(dirPath) {
|
|
2523
2929
|
const entries = await (0, import_promises3.readdir)(dirPath, { withFileTypes: true });
|
|
2524
2930
|
for (const entry of entries) {
|
|
@@ -2528,7 +2934,9 @@ async function findFiles(dirs, pattern, recursive) {
|
|
|
2528
2934
|
await scanDirectory(fullPath);
|
|
2529
2935
|
}
|
|
2530
2936
|
} else if (entry.isFile()) {
|
|
2531
|
-
if (regex.test(entry.name)) {
|
|
2937
|
+
if (regex && regex.test(entry.name)) {
|
|
2938
|
+
allFiles.push(fullPath);
|
|
2939
|
+
} else if (!regex) {
|
|
2532
2940
|
allFiles.push(fullPath);
|
|
2533
2941
|
}
|
|
2534
2942
|
}
|
|
@@ -2539,7 +2947,9 @@ async function findFiles(dirs, pattern, recursive) {
|
|
|
2539
2947
|
if (dirStat.isDirectory()) {
|
|
2540
2948
|
await scanDirectory(dir);
|
|
2541
2949
|
} else if (dirStat.isFile()) {
|
|
2542
|
-
if (regex.test(dir)) {
|
|
2950
|
+
if (regex && regex.test(dir)) {
|
|
2951
|
+
allFiles.push(dir);
|
|
2952
|
+
} else if (!regex) {
|
|
2543
2953
|
allFiles.push(dir);
|
|
2544
2954
|
}
|
|
2545
2955
|
}
|
|
@@ -2569,12 +2979,13 @@ async function convertToPPOCR(flags, ...inputDirs) {
|
|
|
2569
2979
|
backup = DEFAULT_BACKUP,
|
|
2570
2980
|
copyImages = DEFAULT_COPY_IMAGES,
|
|
2571
2981
|
baseImageDir,
|
|
2982
|
+
imageBaseDir = DEFAULT_IMAGE_BASE_DIR,
|
|
2572
2983
|
sortVertical = DEFAULT_SORT_VERTICAL,
|
|
2573
2984
|
sortHorizontal = DEFAULT_SORT_HORIZONTAL,
|
|
2574
2985
|
normalizeShape = DEFAULT_SHAPE_NORMALIZE,
|
|
2575
2986
|
widthIncrement = DEFAULT_WIDTH_INCREMENT,
|
|
2576
2987
|
heightIncrement = DEFAULT_HEIGHT_INCREMENT,
|
|
2577
|
-
adaptResize =
|
|
2988
|
+
adaptResize = DEFAULT_ADAPT_RESIZE,
|
|
2578
2989
|
adaptResizeThreshold = DEFAULT_ADAPT_RESIZE_THRESHOLD,
|
|
2579
2990
|
adaptResizeMargin = DEFAULT_ADAPT_RESIZE_MARGIN,
|
|
2580
2991
|
adaptResizeMinComponentSize = DEFAULT_ADAPT_RESIZE_MIN_COMPONENT_SIZE,
|
|
@@ -2594,11 +3005,12 @@ async function convertToPPOCR(flags, ...inputDirs) {
|
|
|
2594
3005
|
}
|
|
2595
3006
|
console.log(import_chalk.default.blue(`Found ${filePaths.length} files to process
|
|
2596
3007
|
`));
|
|
3008
|
+
const baseDir = inputDirs.length > 0 ? (0, import_path6.resolve)(inputDirs[0]) : process.cwd();
|
|
2597
3009
|
for (const filePath of filePaths) {
|
|
2598
3010
|
const file = (0, import_path6.basename)(filePath);
|
|
2599
3011
|
const relativePath = (0, import_path6.relative)(process.cwd(), filePath);
|
|
2600
3012
|
const relativeDir = (0, import_path6.dirname)(relativePath);
|
|
2601
|
-
console.log(import_chalk.default.gray(`Processing file: ${filePath}`));
|
|
3013
|
+
console.log(import_chalk.default.gray(`Processing file: "${filePath}"`));
|
|
2602
3014
|
try {
|
|
2603
3015
|
const fileData = await (0, import_promises4.readFile)(filePath, "utf-8");
|
|
2604
3016
|
const labelStudioData = JSON.parse(fileData);
|
|
@@ -2621,7 +3033,8 @@ async function convertToPPOCR(flags, ...inputDirs) {
|
|
|
2621
3033
|
adaptResizeOutlierPercentile,
|
|
2622
3034
|
adaptResizeMorphologySize,
|
|
2623
3035
|
adaptResizeMaxHorizontalExpansion,
|
|
2624
|
-
precision
|
|
3036
|
+
precision,
|
|
3037
|
+
imageBaseDir
|
|
2625
3038
|
};
|
|
2626
3039
|
const outputSubDir = outDir ? (0, import_path6.join)(outDir, relativeDir) : (0, import_path6.dirname)(filePath);
|
|
2627
3040
|
if (isFull) {
|
|
@@ -2658,11 +3071,18 @@ async function convertToPPOCR(flags, ...inputDirs) {
|
|
|
2658
3071
|
const cleanPath = imageUrl.startsWith("/") ? imageUrl.slice(1) : imageUrl;
|
|
2659
3072
|
sourceImagePath = (0, import_path6.join)(taskFileDir, cleanPath);
|
|
2660
3073
|
}
|
|
2661
|
-
|
|
3074
|
+
let destImagePath;
|
|
3075
|
+
if (imageBaseDir === IMAGE_BASE_DIR_INPUT_DIR) {
|
|
3076
|
+
const relativeFromInput = (0, import_path6.relative)(baseDir, sourceImagePath);
|
|
3077
|
+
destImagePath = (0, import_path6.join)(outDir, relativeFromInput);
|
|
3078
|
+
} else {
|
|
3079
|
+
const relativeFromTask = (0, import_path6.relative)(taskFileDir, sourceImagePath);
|
|
3080
|
+
destImagePath = (0, import_path6.join)(outputSubDir, relativeFromTask);
|
|
3081
|
+
}
|
|
2662
3082
|
await (0, import_promises4.mkdir)((0, import_path6.dirname)(destImagePath), { recursive: true });
|
|
2663
3083
|
await (0, import_promises4.copyFile)(sourceImagePath, destImagePath);
|
|
2664
3084
|
console.log(
|
|
2665
|
-
import_chalk.default.gray(` \u2713 Copied image: ${(0, import_path6.basename)(sourceImagePath)}`)
|
|
3085
|
+
import_chalk.default.gray(` \u2713 Copied image: "${(0, import_path6.basename)(sourceImagePath)}"`)
|
|
2666
3086
|
);
|
|
2667
3087
|
} catch (error) {
|
|
2668
3088
|
console.warn(
|
|
@@ -2685,14 +3105,14 @@ async function convertToPPOCR(flags, ...inputDirs) {
|
|
|
2685
3105
|
if (backup) {
|
|
2686
3106
|
const backupPath = await backupFileIfExists(outputPath);
|
|
2687
3107
|
if (backupPath) {
|
|
2688
|
-
console.log(import_chalk.default.gray(` Backed up to: ${backupPath}`));
|
|
3108
|
+
console.log(import_chalk.default.gray(` Backed up to: "${backupPath}"`));
|
|
2689
3109
|
}
|
|
2690
3110
|
}
|
|
2691
3111
|
await (0, import_promises4.writeFile)(outputPath, outputLines.join("\n"), "utf-8");
|
|
2692
|
-
console.log(import_chalk.default.green(`\u2713 Converted ${file} -> ${outputPath}`));
|
|
3112
|
+
console.log(import_chalk.default.green(`\u2713 Converted "${file}" -> "${outputPath}"`));
|
|
2693
3113
|
} catch (error) {
|
|
2694
3114
|
console.error(
|
|
2695
|
-
import_chalk.default.red(`\u2717 Failed to process ${file}:`),
|
|
3115
|
+
import_chalk.default.red(`\u2717 Failed to process "${file}":`),
|
|
2696
3116
|
error instanceof Error ? error.message : error
|
|
2697
3117
|
);
|
|
2698
3118
|
}
|
|
@@ -2740,12 +3160,13 @@ async function enhanceLabelStudio(flags, ...inputDirs) {
|
|
|
2740
3160
|
outDir,
|
|
2741
3161
|
fileName,
|
|
2742
3162
|
backup = DEFAULT_BACKUP,
|
|
3163
|
+
imageBaseDir = DEFAULT_IMAGE_BASE_DIR,
|
|
2743
3164
|
sortVertical = DEFAULT_SORT_VERTICAL,
|
|
2744
3165
|
sortHorizontal = DEFAULT_SORT_HORIZONTAL,
|
|
2745
3166
|
normalizeShape = DEFAULT_SHAPE_NORMALIZE,
|
|
2746
3167
|
widthIncrement = DEFAULT_WIDTH_INCREMENT,
|
|
2747
3168
|
heightIncrement = DEFAULT_HEIGHT_INCREMENT,
|
|
2748
|
-
adaptResize =
|
|
3169
|
+
adaptResize = DEFAULT_ADAPT_RESIZE,
|
|
2749
3170
|
adaptResizeThreshold = DEFAULT_ADAPT_RESIZE_THRESHOLD,
|
|
2750
3171
|
adaptResizeMargin = DEFAULT_ADAPT_RESIZE_MARGIN,
|
|
2751
3172
|
adaptResizeMinComponentSize = DEFAULT_ADAPT_RESIZE_MIN_COMPONENT_SIZE,
|
|
@@ -2768,7 +3189,7 @@ async function enhanceLabelStudio(flags, ...inputDirs) {
|
|
|
2768
3189
|
`));
|
|
2769
3190
|
for await (const filePath of filePaths) {
|
|
2770
3191
|
const file = (0, import_path7.basename)(filePath);
|
|
2771
|
-
console.log(import_chalk2.default.gray(`Processing file: ${filePath}`));
|
|
3192
|
+
console.log(import_chalk2.default.gray(`Processing file: "${filePath}"`));
|
|
2772
3193
|
try {
|
|
2773
3194
|
const fileData = await (0, import_promises5.readFile)(filePath, "utf-8");
|
|
2774
3195
|
const labelStudioData = JSON.parse(fileData);
|
|
@@ -2776,7 +3197,7 @@ async function enhanceLabelStudio(flags, ...inputDirs) {
|
|
|
2776
3197
|
if (outputMode !== DEFAULT_OUTPUT_MODE && !isFull) {
|
|
2777
3198
|
console.log(
|
|
2778
3199
|
import_chalk2.default.red(
|
|
2779
|
-
` Skipping file: ${filePath}
|
|
3200
|
+
` Skipping file: "${filePath}"
|
|
2780
3201
|
Error: --outputMode can only be used with Full JSON format. This file is in Min JSON format which does not support annotations/predictions distinction.`
|
|
2781
3202
|
)
|
|
2782
3203
|
);
|
|
@@ -2798,7 +3219,8 @@ async function enhanceLabelStudio(flags, ...inputDirs) {
|
|
|
2798
3219
|
adaptResizeOutlierPercentile,
|
|
2799
3220
|
adaptResizeMorphologySize,
|
|
2800
3221
|
adaptResizeMaxHorizontalExpansion,
|
|
2801
|
-
precision
|
|
3222
|
+
precision,
|
|
3223
|
+
imageBaseDir
|
|
2802
3224
|
};
|
|
2803
3225
|
if (isFull) {
|
|
2804
3226
|
outputTasks = await enhanceFullLabelStudioConverters(
|
|
@@ -2824,7 +3246,7 @@ async function enhanceLabelStudio(flags, ...inputDirs) {
|
|
|
2824
3246
|
if (backup) {
|
|
2825
3247
|
const backupPath = await backupFileIfExists(outputFilePath);
|
|
2826
3248
|
if (backupPath) {
|
|
2827
|
-
console.log(import_chalk2.default.gray(` Backed up to: ${backupPath}`));
|
|
3249
|
+
console.log(import_chalk2.default.gray(` Backed up to: "${backupPath}"`));
|
|
2828
3250
|
}
|
|
2829
3251
|
}
|
|
2830
3252
|
await (0, import_promises5.writeFile)(
|
|
@@ -2832,10 +3254,10 @@ async function enhanceLabelStudio(flags, ...inputDirs) {
|
|
|
2832
3254
|
JSON.stringify(outputTasks, null, 2),
|
|
2833
3255
|
"utf-8"
|
|
2834
3256
|
);
|
|
2835
|
-
console.log(import_chalk2.default.green(`\u2713 Enhanced file saved: ${outputFilePath}`));
|
|
3257
|
+
console.log(import_chalk2.default.green(`\u2713 Enhanced file saved: "${outputFilePath}"`));
|
|
2836
3258
|
} catch (error) {
|
|
2837
3259
|
console.error(
|
|
2838
|
-
import_chalk2.default.red(`Error processing file ${file}:`),
|
|
3260
|
+
import_chalk2.default.red(`Error processing file "${file}":`),
|
|
2839
3261
|
error instanceof Error ? error.message : String(error)
|
|
2840
3262
|
);
|
|
2841
3263
|
}
|
|
@@ -2868,12 +3290,13 @@ async function enhancePPOCR(flags, ...inputDirs) {
|
|
|
2868
3290
|
outDir,
|
|
2869
3291
|
fileName,
|
|
2870
3292
|
backup = DEFAULT_BACKUP,
|
|
3293
|
+
imageBaseDir = DEFAULT_IMAGE_BASE_DIR,
|
|
2871
3294
|
sortVertical = DEFAULT_SORT_VERTICAL,
|
|
2872
3295
|
sortHorizontal = DEFAULT_SORT_HORIZONTAL,
|
|
2873
3296
|
normalizeShape = DEFAULT_SHAPE_NORMALIZE,
|
|
2874
3297
|
widthIncrement = DEFAULT_WIDTH_INCREMENT,
|
|
2875
3298
|
heightIncrement = DEFAULT_HEIGHT_INCREMENT,
|
|
2876
|
-
adaptResize =
|
|
3299
|
+
adaptResize = DEFAULT_ADAPT_RESIZE,
|
|
2877
3300
|
adaptResizeThreshold = DEFAULT_ADAPT_RESIZE_THRESHOLD,
|
|
2878
3301
|
adaptResizeMargin = DEFAULT_ADAPT_RESIZE_MARGIN,
|
|
2879
3302
|
adaptResizeMinComponentSize = DEFAULT_ADAPT_RESIZE_MIN_COMPONENT_SIZE,
|
|
@@ -2895,7 +3318,7 @@ async function enhancePPOCR(flags, ...inputDirs) {
|
|
|
2895
3318
|
`));
|
|
2896
3319
|
for (const filePath of filePaths) {
|
|
2897
3320
|
const file = (0, import_path8.basename)(filePath);
|
|
2898
|
-
console.log(import_chalk3.default.gray(`Processing file: ${filePath}`));
|
|
3321
|
+
console.log(import_chalk3.default.gray(`Processing file: "${filePath}"`));
|
|
2899
3322
|
try {
|
|
2900
3323
|
const fileData = await (0, import_promises6.readFile)(filePath, "utf-8");
|
|
2901
3324
|
const lines = fileData.trim().split("\n");
|
|
@@ -2927,7 +3350,7 @@ async function enhancePPOCR(flags, ...inputDirs) {
|
|
|
2927
3350
|
}
|
|
2928
3351
|
if (inputTasks.length === 0) {
|
|
2929
3352
|
console.log(
|
|
2930
|
-
import_chalk3.default.yellow(` Skipping file with no valid data: ${filePath}`)
|
|
3353
|
+
import_chalk3.default.yellow(` Skipping file with no valid data: "${filePath}"`)
|
|
2931
3354
|
);
|
|
2932
3355
|
continue;
|
|
2933
3356
|
}
|
|
@@ -2945,7 +3368,8 @@ async function enhancePPOCR(flags, ...inputDirs) {
|
|
|
2945
3368
|
adaptResizeOutlierPercentile,
|
|
2946
3369
|
adaptResizeMorphologySize,
|
|
2947
3370
|
adaptResizeMaxHorizontalExpansion,
|
|
2948
|
-
precision
|
|
3371
|
+
precision,
|
|
3372
|
+
imageBaseDir
|
|
2949
3373
|
};
|
|
2950
3374
|
const outputTasks = await enhancePPOCRConverters(
|
|
2951
3375
|
inputTasks,
|
|
@@ -2963,14 +3387,14 @@ async function enhancePPOCR(flags, ...inputDirs) {
|
|
|
2963
3387
|
if (backup) {
|
|
2964
3388
|
const backupPath = await backupFileIfExists(outputFilePath);
|
|
2965
3389
|
if (backupPath) {
|
|
2966
|
-
console.log(import_chalk3.default.gray(` Backed up to: ${backupPath}`));
|
|
3390
|
+
console.log(import_chalk3.default.gray(` Backed up to: "${backupPath}"`));
|
|
2967
3391
|
}
|
|
2968
3392
|
}
|
|
2969
3393
|
await (0, import_promises6.writeFile)(outputFilePath, outputTasks.join("\n"), "utf-8");
|
|
2970
|
-
console.log(import_chalk3.default.green(`\u2713 Enhanced file saved: ${outputFilePath}`));
|
|
3394
|
+
console.log(import_chalk3.default.green(`\u2713 Enhanced file saved: "${outputFilePath}"`));
|
|
2971
3395
|
} catch (error) {
|
|
2972
3396
|
console.error(
|
|
2973
|
-
import_chalk3.default.red(`Error processing file ${file}:`),
|
|
3397
|
+
import_chalk3.default.red(`Error processing file "${file}":`),
|
|
2974
3398
|
error instanceof Error ? error.message : String(error)
|
|
2975
3399
|
);
|
|
2976
3400
|
}
|
|
@@ -2992,9 +3416,98 @@ var init_impl3 = __esm({
|
|
|
2992
3416
|
}
|
|
2993
3417
|
});
|
|
2994
3418
|
|
|
2995
|
-
// src/commands/
|
|
3419
|
+
// src/commands/labelStudioOutputToPPOCR/impl.ts
|
|
2996
3420
|
var impl_exports4 = {};
|
|
2997
3421
|
__export(impl_exports4, {
|
|
3422
|
+
labelStudioOutputToPPOCR: () => labelStudioOutputToPPOCR
|
|
3423
|
+
});
|
|
3424
|
+
async function labelStudioOutputToPPOCR(flags, ...inputDirs) {
|
|
3425
|
+
const {
|
|
3426
|
+
outDir,
|
|
3427
|
+
fileName = DEFAULT_PPOCR_FILE_NAME,
|
|
3428
|
+
backup = DEFAULT_BACKUP,
|
|
3429
|
+
recursive = DEFAULT_RECURSIVE,
|
|
3430
|
+
filePattern = void 0,
|
|
3431
|
+
removeBaseImageDir = DEFAULT_LABEL_STUDIO_OUTPUT_IMAGE_BASE_DIR
|
|
3432
|
+
} = flags;
|
|
3433
|
+
console.log(import_chalk4.default.blue("Finding files..."));
|
|
3434
|
+
const filePaths = await findFiles(inputDirs, filePattern, recursive);
|
|
3435
|
+
if (filePaths.length === 0) {
|
|
3436
|
+
console.log(import_chalk4.default.yellow("No files found matching the pattern."));
|
|
3437
|
+
return;
|
|
3438
|
+
}
|
|
3439
|
+
console.log(import_chalk4.default.blue(`Found ${filePaths.length} files to process
|
|
3440
|
+
`));
|
|
3441
|
+
let masterOutputTasks = [];
|
|
3442
|
+
for (const filePath of filePaths) {
|
|
3443
|
+
console.log(import_chalk4.default.gray(`Processing file: "${filePath}"`));
|
|
3444
|
+
const fileData = await (0, import_promises7.readFile)(filePath, "utf-8");
|
|
3445
|
+
const labelStudioData = JSON.parse(fileData);
|
|
3446
|
+
const [outputTask] = await outputLabelStudioToPPOCRConverters(
|
|
3447
|
+
[labelStudioData],
|
|
3448
|
+
filePath
|
|
3449
|
+
);
|
|
3450
|
+
masterOutputTasks = masterOutputTasks.concat([
|
|
3451
|
+
{
|
|
3452
|
+
...outputTask,
|
|
3453
|
+
imagePath: outputTask.imagePath.replace(removeBaseImageDir, "")
|
|
3454
|
+
}
|
|
3455
|
+
]);
|
|
3456
|
+
}
|
|
3457
|
+
const groupTaskByImagePath = (0, import_es_toolkit4.groupBy)(
|
|
3458
|
+
masterOutputTasks,
|
|
3459
|
+
(task) => (0, import_path9.dirname)(task.imagePath)
|
|
3460
|
+
);
|
|
3461
|
+
for (const [baseOutputImageDir, tasks] of Object.entries(
|
|
3462
|
+
groupTaskByImagePath
|
|
3463
|
+
)) {
|
|
3464
|
+
const subImageDir = baseOutputImageDir.split("/").slice(-1)[0];
|
|
3465
|
+
const outputImageDir = (0, import_path9.resolve)(outDir, baseOutputImageDir);
|
|
3466
|
+
await (0, import_promises7.mkdir)(outputImageDir, { recursive: true });
|
|
3467
|
+
const outputPath = (0, import_path9.join)(outputImageDir, `${fileName}`);
|
|
3468
|
+
const outputLines = [];
|
|
3469
|
+
for (const task of tasks) {
|
|
3470
|
+
const imagePath = removeBaseImageDir ? task.imagePath.replace(removeBaseImageDir, "") : task.imagePath;
|
|
3471
|
+
const imageFileName = (0, import_path9.basename)(imagePath);
|
|
3472
|
+
PPOCRLabelSchema.parse(task.data);
|
|
3473
|
+
const jsonArray = JSON.stringify(task.data);
|
|
3474
|
+
outputLines.push(`${subImageDir}/${imageFileName} ${jsonArray}`);
|
|
3475
|
+
console.log(
|
|
3476
|
+
import_chalk4.default.green(
|
|
3477
|
+
`\u2713 Saved image group: "${imagePath}" to "${outputPath}"`
|
|
3478
|
+
)
|
|
3479
|
+
);
|
|
3480
|
+
}
|
|
3481
|
+
if (backup) {
|
|
3482
|
+
const backupPath = await backupFileIfExists(outputPath);
|
|
3483
|
+
if (backupPath) {
|
|
3484
|
+
console.log(import_chalk4.default.gray(` Backed up to: "${backupPath}"`));
|
|
3485
|
+
}
|
|
3486
|
+
}
|
|
3487
|
+
await (0, import_promises7.writeFile)(outputPath, outputLines.join("\n"), "utf-8");
|
|
3488
|
+
}
|
|
3489
|
+
console.log(import_chalk4.default.green("\n\u2713 Conversion completed!"));
|
|
3490
|
+
}
|
|
3491
|
+
var import_promises7, import_path9, import_chalk4, import_es_toolkit4;
|
|
3492
|
+
var init_impl4 = __esm({
|
|
3493
|
+
"src/commands/labelStudioOutputToPPOCR/impl.ts"() {
|
|
3494
|
+
"use strict";
|
|
3495
|
+
init_cjs_shims();
|
|
3496
|
+
import_promises7 = require("fs/promises");
|
|
3497
|
+
import_path9 = require("path");
|
|
3498
|
+
import_chalk4 = __toESM(require("chalk"), 1);
|
|
3499
|
+
import_es_toolkit4 = require("es-toolkit");
|
|
3500
|
+
init_constants();
|
|
3501
|
+
init_lib();
|
|
3502
|
+
init_lib();
|
|
3503
|
+
init_backup_utils();
|
|
3504
|
+
init_file_utils();
|
|
3505
|
+
}
|
|
3506
|
+
});
|
|
3507
|
+
|
|
3508
|
+
// src/commands/toLabelStudio/impl.ts
|
|
3509
|
+
var impl_exports5 = {};
|
|
3510
|
+
__export(impl_exports5, {
|
|
2998
3511
|
convertToLabelStudio: () => convertToLabelStudio
|
|
2999
3512
|
});
|
|
3000
3513
|
async function convertToLabelStudio(flags, ...inputDirs) {
|
|
@@ -3003,6 +3516,7 @@ async function convertToLabelStudio(flags, ...inputDirs) {
|
|
|
3003
3516
|
fileName,
|
|
3004
3517
|
backup = DEFAULT_BACKUP,
|
|
3005
3518
|
copyImages = DEFAULT_COPY_IMAGES,
|
|
3519
|
+
imageBaseDir = DEFAULT_IMAGE_BASE_DIR,
|
|
3006
3520
|
defaultLabelName = DEFAULT_LABEL_NAME,
|
|
3007
3521
|
toFullJson = DEFAULT_LABEL_STUDIO_FULL_JSON,
|
|
3008
3522
|
createFilePerImage = DEFAULT_CREATE_FILE_PER_IMAGE,
|
|
@@ -3014,7 +3528,7 @@ async function convertToLabelStudio(flags, ...inputDirs) {
|
|
|
3014
3528
|
normalizeShape = DEFAULT_SHAPE_NORMALIZE,
|
|
3015
3529
|
widthIncrement = DEFAULT_WIDTH_INCREMENT,
|
|
3016
3530
|
heightIncrement = DEFAULT_HEIGHT_INCREMENT,
|
|
3017
|
-
adaptResize =
|
|
3531
|
+
adaptResize = DEFAULT_ADAPT_RESIZE,
|
|
3018
3532
|
adaptResizeThreshold = DEFAULT_ADAPT_RESIZE_THRESHOLD,
|
|
3019
3533
|
adaptResizeMargin = DEFAULT_ADAPT_RESIZE_MARGIN,
|
|
3020
3534
|
adaptResizeMinComponentSize = DEFAULT_ADAPT_RESIZE_MIN_COMPONENT_SIZE,
|
|
@@ -3029,38 +3543,38 @@ async function convertToLabelStudio(flags, ...inputDirs) {
|
|
|
3029
3543
|
} = flags;
|
|
3030
3544
|
if (outputMode !== DEFAULT_OUTPUT_MODE && !toFullJson) {
|
|
3031
3545
|
console.log(
|
|
3032
|
-
|
|
3546
|
+
import_chalk5.default.red(
|
|
3033
3547
|
"Error: --outputMode can only be used with --toFullJson (Full JSON format). Min JSON format does not support annotations/predictions distinction."
|
|
3034
3548
|
)
|
|
3035
3549
|
);
|
|
3036
3550
|
return;
|
|
3037
3551
|
}
|
|
3038
|
-
console.log(
|
|
3552
|
+
console.log(import_chalk5.default.blue("Finding files..."));
|
|
3039
3553
|
const filePaths = await findFiles(inputDirs, filePattern, recursive);
|
|
3040
3554
|
if (filePaths.length === 0) {
|
|
3041
|
-
console.log(
|
|
3555
|
+
console.log(import_chalk5.default.yellow("No files found matching the pattern."));
|
|
3042
3556
|
return;
|
|
3043
3557
|
}
|
|
3044
|
-
console.log(
|
|
3558
|
+
console.log(import_chalk5.default.blue(`Found ${filePaths.length} files to process
|
|
3045
3559
|
`));
|
|
3046
|
-
const resolvedOutDir = outDir ? (0,
|
|
3560
|
+
const resolvedOutDir = outDir ? (0, import_path10.resolve)(outDir) : void 0;
|
|
3047
3561
|
let fileListPath = null;
|
|
3048
3562
|
if (createFileListForServing && resolvedOutDir) {
|
|
3049
|
-
fileListPath = (0,
|
|
3050
|
-
await (0,
|
|
3051
|
-
await (0,
|
|
3563
|
+
fileListPath = (0, import_path10.join)(resolvedOutDir, fileListName);
|
|
3564
|
+
await (0, import_promises8.mkdir)(resolvedOutDir, { recursive: true });
|
|
3565
|
+
await (0, import_promises8.writeFile)(fileListPath, "", "utf-8");
|
|
3052
3566
|
}
|
|
3053
|
-
const baseDir = inputDirs.length > 0 ? (0,
|
|
3567
|
+
const baseDir = inputDirs.length > 0 ? (0, import_path10.resolve)(inputDirs[0]) : process.cwd();
|
|
3054
3568
|
for (const filePath of filePaths) {
|
|
3055
|
-
const file = (0,
|
|
3056
|
-
const relativePath = (0,
|
|
3057
|
-
const relativeDir = (0,
|
|
3058
|
-
console.log(
|
|
3569
|
+
const file = (0, import_path10.basename)(filePath);
|
|
3570
|
+
const relativePath = (0, import_path10.relative)(baseDir, filePath);
|
|
3571
|
+
const relativeDir = (0, import_path10.dirname)(relativePath);
|
|
3572
|
+
console.log(import_chalk5.default.gray(`Processing file: "${filePath}"`));
|
|
3059
3573
|
try {
|
|
3060
|
-
const fileData = await (0,
|
|
3574
|
+
const fileData = await (0, import_promises8.readFile)(filePath, "utf-8");
|
|
3061
3575
|
const trimmedData = fileData.trim();
|
|
3062
3576
|
if (trimmedData === "") {
|
|
3063
|
-
console.log(
|
|
3577
|
+
console.log(import_chalk5.default.yellow(` Skipping empty file: "${filePath}"`));
|
|
3064
3578
|
continue;
|
|
3065
3579
|
}
|
|
3066
3580
|
const lines = trimmedData.split("\n");
|
|
@@ -3095,17 +3609,20 @@ async function convertToLabelStudio(flags, ...inputDirs) {
|
|
|
3095
3609
|
}
|
|
3096
3610
|
if (inputTasks.length === 0) {
|
|
3097
3611
|
console.log(
|
|
3098
|
-
|
|
3612
|
+
import_chalk5.default.yellow(` Skipping file with no valid data: "${filePath}"`)
|
|
3099
3613
|
);
|
|
3100
3614
|
continue;
|
|
3101
3615
|
}
|
|
3102
3616
|
let outputTasks = [];
|
|
3103
|
-
const converterOutputDir = resolvedOutDir ? (0,
|
|
3617
|
+
const converterOutputDir = resolvedOutDir ? (0, import_path10.join)(resolvedOutDir, relativeDir) : (0, import_path10.dirname)(filePath);
|
|
3104
3618
|
const convertParams = {
|
|
3105
3619
|
defaultLabelName,
|
|
3106
3620
|
baseServerUrl,
|
|
3621
|
+
outputMode,
|
|
3107
3622
|
outDir: converterOutputDir,
|
|
3108
|
-
copyImages: resolvedOutDir ? copyImages : false
|
|
3623
|
+
copyImages: resolvedOutDir ? copyImages : false,
|
|
3624
|
+
inputBaseDir: baseDir,
|
|
3625
|
+
outputRootDir: resolvedOutDir
|
|
3109
3626
|
};
|
|
3110
3627
|
const enhanceParams = {
|
|
3111
3628
|
sortVertical,
|
|
@@ -3121,7 +3638,8 @@ async function convertToLabelStudio(flags, ...inputDirs) {
|
|
|
3121
3638
|
adaptResizeOutlierPercentile,
|
|
3122
3639
|
adaptResizeMorphologySize,
|
|
3123
3640
|
adaptResizeMaxHorizontalExpansion,
|
|
3124
|
-
precision
|
|
3641
|
+
precision,
|
|
3642
|
+
imageBaseDir
|
|
3125
3643
|
};
|
|
3126
3644
|
if (toFullJson) {
|
|
3127
3645
|
outputTasks = await ppocrToFullLabelStudioConverters(
|
|
@@ -3143,24 +3661,31 @@ async function convertToLabelStudio(flags, ...inputDirs) {
|
|
|
3143
3661
|
);
|
|
3144
3662
|
}
|
|
3145
3663
|
if (resolvedOutDir && copyImages) {
|
|
3146
|
-
const taskFileDir = (0,
|
|
3147
|
-
const outputSubDir2 = (0,
|
|
3664
|
+
const taskFileDir = (0, import_path10.dirname)(filePath);
|
|
3665
|
+
const outputSubDir2 = (0, import_path10.join)(resolvedOutDir, relativeDir);
|
|
3148
3666
|
for (const task of inputTasks) {
|
|
3149
3667
|
try {
|
|
3150
3668
|
const parts = task.imagePath.split("/");
|
|
3151
3669
|
const folderName = parts.length > 1 ? parts[0] : "";
|
|
3152
3670
|
const fileName2 = parts.length > 1 ? parts.slice(1).join("/") : task.imagePath;
|
|
3153
|
-
const sourceImagePath = folderName ? (0,
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3671
|
+
const sourceImagePath = folderName ? (0, import_path10.resolve)((0, import_path10.dirname)(taskFileDir), folderName, fileName2) : (0, import_path10.resolve)(taskFileDir, fileName2);
|
|
3672
|
+
let destImagePath;
|
|
3673
|
+
if (imageBaseDir === IMAGE_BASE_DIR_INPUT_DIR) {
|
|
3674
|
+
const relativeFromInput = (0, import_path10.relative)(baseDir, sourceImagePath);
|
|
3675
|
+
destImagePath = (0, import_path10.join)(resolvedOutDir, relativeFromInput);
|
|
3676
|
+
} else {
|
|
3677
|
+
const relativeFromTask = (0, import_path10.relative)(taskFileDir, sourceImagePath);
|
|
3678
|
+
destImagePath = (0, import_path10.join)(outputSubDir2, relativeFromTask);
|
|
3679
|
+
}
|
|
3680
|
+
await (0, import_promises8.mkdir)((0, import_path10.dirname)(destImagePath), { recursive: true });
|
|
3681
|
+
await (0, import_promises8.copyFile)(sourceImagePath, destImagePath);
|
|
3157
3682
|
console.log(
|
|
3158
|
-
|
|
3683
|
+
import_chalk5.default.gray(` \u2713 Copied image: "${(0, import_path10.basename)(sourceImagePath)}"`)
|
|
3159
3684
|
);
|
|
3160
3685
|
} catch (error) {
|
|
3161
3686
|
console.warn(
|
|
3162
|
-
|
|
3163
|
-
` \u26A0 Failed to copy image ${task.imagePath}: ${error instanceof Error ? error.message : error}`
|
|
3687
|
+
import_chalk5.default.yellow(
|
|
3688
|
+
` \u26A0 Failed to copy image "${task.imagePath}": ${error instanceof Error ? error.message : error}`
|
|
3164
3689
|
)
|
|
3165
3690
|
);
|
|
3166
3691
|
}
|
|
@@ -3170,22 +3695,24 @@ async function convertToLabelStudio(flags, ...inputDirs) {
|
|
|
3170
3695
|
for await (const taskOutput of outputTasks) {
|
|
3171
3696
|
const imageFilePath = toFullJson ? taskOutput.data.ocr : taskOutput.ocr;
|
|
3172
3697
|
const imageBaseName = imageFilePath.split("/").pop().replace(/\//g, "_").replace(/\.[^.]+$/, "");
|
|
3173
|
-
const outputSubDir2 = resolvedOutDir ? (0,
|
|
3174
|
-
await (0,
|
|
3175
|
-
const individualOutputPath = (0,
|
|
3698
|
+
const outputSubDir2 = resolvedOutDir ? (0, import_path10.join)(resolvedOutDir, relativeDir) : (0, import_path10.dirname)(filePath);
|
|
3699
|
+
await (0, import_promises8.mkdir)(outputSubDir2, { recursive: true });
|
|
3700
|
+
const individualOutputPath = (0, import_path10.join)(
|
|
3176
3701
|
outputSubDir2,
|
|
3177
3702
|
`${imageBaseName}_${toFullJson ? "full" : "min"}.json`
|
|
3178
3703
|
);
|
|
3179
|
-
await (0,
|
|
3704
|
+
await (0, import_promises8.writeFile)(
|
|
3180
3705
|
individualOutputPath,
|
|
3181
3706
|
JSON.stringify(taskOutput, null, 2),
|
|
3182
3707
|
"utf-8"
|
|
3183
3708
|
);
|
|
3184
3709
|
console.log(
|
|
3185
|
-
|
|
3710
|
+
import_chalk5.default.gray(
|
|
3711
|
+
` \u2713 Created individual file: "${individualOutputPath}"`
|
|
3712
|
+
)
|
|
3186
3713
|
);
|
|
3187
3714
|
if (fileListPath) {
|
|
3188
|
-
await (0,
|
|
3715
|
+
await (0, import_promises8.writeFile)(fileListPath, `${imageFilePath}
|
|
3189
3716
|
`, {
|
|
3190
3717
|
encoding: "utf-8",
|
|
3191
3718
|
flag: "a"
|
|
@@ -3194,41 +3721,41 @@ async function convertToLabelStudio(flags, ...inputDirs) {
|
|
|
3194
3721
|
}
|
|
3195
3722
|
}
|
|
3196
3723
|
const baseName = fileName || file.replace(".txt", "");
|
|
3197
|
-
const outputSubDir = resolvedOutDir ? (0,
|
|
3198
|
-
await (0,
|
|
3199
|
-
const outputPath = (0,
|
|
3724
|
+
const outputSubDir = resolvedOutDir ? (0, import_path10.join)(resolvedOutDir, relativeDir) : (0, import_path10.dirname)(filePath);
|
|
3725
|
+
await (0, import_promises8.mkdir)(outputSubDir, { recursive: true });
|
|
3726
|
+
const outputPath = (0, import_path10.join)(
|
|
3200
3727
|
outputSubDir,
|
|
3201
3728
|
fileName ? `${fileName}.json` : `${baseName}_${toFullJson ? "full" : "min"}.json`
|
|
3202
3729
|
);
|
|
3203
3730
|
if (backup) {
|
|
3204
3731
|
const backupPath = await backupFileIfExists(outputPath);
|
|
3205
3732
|
if (backupPath) {
|
|
3206
|
-
console.log(
|
|
3733
|
+
console.log(import_chalk5.default.gray(` \u2713 Created backup: ${backupPath}`));
|
|
3207
3734
|
}
|
|
3208
3735
|
}
|
|
3209
|
-
await (0,
|
|
3736
|
+
await (0, import_promises8.writeFile)(
|
|
3210
3737
|
outputPath,
|
|
3211
3738
|
JSON.stringify(outputTasks, null, 2),
|
|
3212
3739
|
"utf-8"
|
|
3213
3740
|
);
|
|
3214
|
-
console.log(
|
|
3741
|
+
console.log(import_chalk5.default.green(`\u2713 Converted "${file}" -> "${outputPath}"`));
|
|
3215
3742
|
} catch (error) {
|
|
3216
3743
|
console.error(
|
|
3217
|
-
|
|
3744
|
+
import_chalk5.default.red(`\u2717 Failed to process "${file}":`),
|
|
3218
3745
|
error instanceof Error ? error.message : error
|
|
3219
3746
|
);
|
|
3220
3747
|
}
|
|
3221
3748
|
}
|
|
3222
|
-
console.log(
|
|
3749
|
+
console.log(import_chalk5.default.green("\n\u2713 Conversion completed!"));
|
|
3223
3750
|
}
|
|
3224
|
-
var
|
|
3225
|
-
var
|
|
3751
|
+
var import_promises8, import_path10, import_chalk5;
|
|
3752
|
+
var init_impl5 = __esm({
|
|
3226
3753
|
"src/commands/toLabelStudio/impl.ts"() {
|
|
3227
3754
|
"use strict";
|
|
3228
3755
|
init_cjs_shims();
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3756
|
+
import_promises8 = require("fs/promises");
|
|
3757
|
+
import_path10 = require("path");
|
|
3758
|
+
import_chalk5 = __toESM(require("chalk"), 1);
|
|
3232
3759
|
init_constants();
|
|
3233
3760
|
init_lib();
|
|
3234
3761
|
init_backup_utils();
|
|
@@ -3238,15 +3765,15 @@ var init_impl4 = __esm({
|
|
|
3238
3765
|
|
|
3239
3766
|
// src/bin/bash-complete.ts
|
|
3240
3767
|
init_cjs_shims();
|
|
3241
|
-
var
|
|
3768
|
+
var import_core7 = require("@stricli/core");
|
|
3242
3769
|
|
|
3243
3770
|
// src/app.ts
|
|
3244
3771
|
init_cjs_shims();
|
|
3245
3772
|
var import_auto_complete = require("@stricli/auto-complete");
|
|
3246
|
-
var
|
|
3773
|
+
var import_core6 = require("@stricli/core");
|
|
3247
3774
|
|
|
3248
3775
|
// package.json
|
|
3249
|
-
var version = "1.
|
|
3776
|
+
var version = "1.5.0";
|
|
3250
3777
|
var description = "Convert between Label Studio OCR format and PPOCRLabelv2 format";
|
|
3251
3778
|
|
|
3252
3779
|
// src/commands/enhance-labelstudio/command.ts
|
|
@@ -3337,14 +3864,61 @@ var enhancePPOCRCommand = (0, import_core2.buildCommand)({
|
|
|
3337
3864
|
}
|
|
3338
3865
|
});
|
|
3339
3866
|
|
|
3340
|
-
// src/commands/
|
|
3867
|
+
// src/commands/labelStudioOutputToPPOCR/commands.ts
|
|
3341
3868
|
init_cjs_shims();
|
|
3342
3869
|
var import_core3 = require("@stricli/core");
|
|
3870
|
+
var import_es_toolkit5 = require("es-toolkit");
|
|
3343
3871
|
init_constants();
|
|
3344
3872
|
init_lib();
|
|
3345
|
-
var
|
|
3873
|
+
var labelStudioOutputToPPOCRCommand = (0, import_core3.buildCommand)({
|
|
3346
3874
|
loader: async () => {
|
|
3347
|
-
const {
|
|
3875
|
+
const { labelStudioOutputToPPOCR: labelStudioOutputToPPOCR2 } = await Promise.resolve().then(() => (init_impl4(), impl_exports4));
|
|
3876
|
+
return labelStudioOutputToPPOCR2;
|
|
3877
|
+
},
|
|
3878
|
+
parameters: {
|
|
3879
|
+
positional: {
|
|
3880
|
+
kind: "array",
|
|
3881
|
+
parameter: {
|
|
3882
|
+
brief: "Input directories containing Label Studio files",
|
|
3883
|
+
parse: String
|
|
3884
|
+
},
|
|
3885
|
+
minimum: 1
|
|
3886
|
+
},
|
|
3887
|
+
flags: {
|
|
3888
|
+
...(0, import_es_toolkit5.pick)(baseFileIOFlagOptions, ["recursive", "backup", "filePattern"]),
|
|
3889
|
+
outDir: {
|
|
3890
|
+
kind: "parsed",
|
|
3891
|
+
brief: "Output directory.",
|
|
3892
|
+
parse: String,
|
|
3893
|
+
optional: false
|
|
3894
|
+
},
|
|
3895
|
+
fileName: {
|
|
3896
|
+
kind: "parsed",
|
|
3897
|
+
brief: `Output PPOCR file name. Default: "${DEFAULT_PPOCR_FILE_NAME}"`,
|
|
3898
|
+
parse: String,
|
|
3899
|
+
optional: true
|
|
3900
|
+
},
|
|
3901
|
+
removeBaseImageDir: {
|
|
3902
|
+
kind: "parsed",
|
|
3903
|
+
parse: String,
|
|
3904
|
+
brief: `Remove base image directory from image paths in output. Default: "${DEFAULT_LABEL_STUDIO_OUTPUT_IMAGE_BASE_DIR}"`,
|
|
3905
|
+
optional: true
|
|
3906
|
+
}
|
|
3907
|
+
}
|
|
3908
|
+
},
|
|
3909
|
+
docs: {
|
|
3910
|
+
brief: "Convert Label Studio output files to PPOCRLabel format"
|
|
3911
|
+
}
|
|
3912
|
+
});
|
|
3913
|
+
|
|
3914
|
+
// src/commands/toLabelStudio/command.ts
|
|
3915
|
+
init_cjs_shims();
|
|
3916
|
+
var import_core4 = require("@stricli/core");
|
|
3917
|
+
init_constants();
|
|
3918
|
+
init_lib();
|
|
3919
|
+
var toLabelStudioCommand = (0, import_core4.buildCommand)({
|
|
3920
|
+
loader: async () => {
|
|
3921
|
+
const { convertToLabelStudio: convertToLabelStudio2 } = await Promise.resolve().then(() => (init_impl5(), impl_exports5));
|
|
3348
3922
|
return convertToLabelStudio2;
|
|
3349
3923
|
},
|
|
3350
3924
|
parameters: {
|
|
@@ -3419,10 +3993,10 @@ var toLabelStudioCommand = (0, import_core3.buildCommand)({
|
|
|
3419
3993
|
|
|
3420
3994
|
// src/commands/toPPOCR/commands.ts
|
|
3421
3995
|
init_cjs_shims();
|
|
3422
|
-
var
|
|
3996
|
+
var import_core5 = require("@stricli/core");
|
|
3423
3997
|
init_constants();
|
|
3424
3998
|
init_lib();
|
|
3425
|
-
var toPPOCRCommand = (0,
|
|
3999
|
+
var toPPOCRCommand = (0, import_core5.buildCommand)({
|
|
3426
4000
|
loader: async () => {
|
|
3427
4001
|
const { convertToPPOCR: convertToPPOCR2 } = await Promise.resolve().then(() => (init_impl(), impl_exports));
|
|
3428
4002
|
return convertToPPOCR2;
|
|
@@ -3465,12 +4039,13 @@ var toPPOCRCommand = (0, import_core4.buildCommand)({
|
|
|
3465
4039
|
});
|
|
3466
4040
|
|
|
3467
4041
|
// src/app.ts
|
|
3468
|
-
var routes = (0,
|
|
4042
|
+
var routes = (0, import_core6.buildRouteMap)({
|
|
3469
4043
|
routes: {
|
|
3470
4044
|
toLabelStudio: toLabelStudioCommand,
|
|
3471
4045
|
toPPOCR: toPPOCRCommand,
|
|
3472
4046
|
"enhance-labelstudio": enhanceLabelStudioCommand,
|
|
3473
4047
|
"enhance-ppocr": enhancePPOCRCommand,
|
|
4048
|
+
"label-studio-output-to-ppocr": labelStudioOutputToPPOCRCommand,
|
|
3474
4049
|
install: (0, import_auto_complete.buildInstallCommand)("label-studio-converter", {
|
|
3475
4050
|
bash: "__label-studio-converter_bash_complete"
|
|
3476
4051
|
}),
|
|
@@ -3484,7 +4059,7 @@ var routes = (0, import_core5.buildRouteMap)({
|
|
|
3484
4059
|
}
|
|
3485
4060
|
}
|
|
3486
4061
|
});
|
|
3487
|
-
var app = (0,
|
|
4062
|
+
var app = (0, import_core6.buildApplication)(routes, {
|
|
3488
4063
|
name: "label-studio-converter",
|
|
3489
4064
|
versionInfo: {
|
|
3490
4065
|
currentVersion: version
|
|
@@ -3511,9 +4086,9 @@ function buildContext(process2) {
|
|
|
3511
4086
|
if (process.env.COMP_LINE?.endsWith(" ")) {
|
|
3512
4087
|
inputs.push("");
|
|
3513
4088
|
}
|
|
3514
|
-
await (0,
|
|
4089
|
+
await (0, import_core7.proposeCompletions)(app, inputs, buildContext(process));
|
|
3515
4090
|
try {
|
|
3516
|
-
for (const { completion } of await (0,
|
|
4091
|
+
for (const { completion } of await (0, import_core7.proposeCompletions)(
|
|
3517
4092
|
app,
|
|
3518
4093
|
inputs,
|
|
3519
4094
|
buildContext(process)
|