Loading ballontranslator/data/pkusegscores.json 0 → 100644 +1 −0 Original line number Diff line number Diff line {"n": {"n": 0.0622, "t": 0, "s": 0, "f": 0.0405, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.1921, "a": 0, "z": 0, "d": 0.0891, "p": 0.0258, "c": 0.0228, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "t": {"n": 0.0736, "t": 1, "s": 0, "f": 0.027, "m": 0, "q": 0, "b": 0, "r": 0.172, "v": 0.2027, "a": 0, "z": 0, "d": 0.1426, "p": 0.0384, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "s": {"n": 0.0578, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.3442, "a": 0, "z": 0, "d": 0.102, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "f": {"n": 0.0501, "t": 0, "s": 0, "f": 0, "m": 0.0305, "q": 0, "b": 0, "r": 0.0302, "v": 0.2821, "a": 0, "z": 0, "d": 0.0829, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "m": {"n": 0.2381, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0.4929, "b": 0, "r": 0, "v": 0.0675, "a": 0.0355, "z": 0, "d": 0.0297, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "q": {"n": 0.4815, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0.0329, "v": 0.0943, "a": 0.0826, "z": 0, "d": 0.0447, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "b": {"n": 0.3708, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.026, "a": 0, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0.0207, "vx": 0, "ad": 0, "an": 0}, "r": {"n": 0.1064, "t": 0, "s": 0, "f": 0, "m": 0.0341, "q": 0, "b": 0, "r": 0.0441, "v": 0.2954, "a": 0.027, "z": 0, "d": 0.1562, "p": 0.0429, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "v": {"n": 0.1081, "t": 0, "s": 0, "f": 0, "m": 0.0432, "q": 0, "b": 0, "r": 0.1591, "v": 0.1757, "a": 0.0224, "z": 0, "d": 0.036, "p": 0.0421, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "a": {"n": 0.1464, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.0333, "a": 0.0281, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "z": {"n": 0.0737, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.1117, "a": 0.0306, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "d": {"n": 0, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0.0313, "v": 0.5905, "a": 0.1047, "z": 0, "d": 0.1317, "p": 0.0626, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "p": {"n": 0.2263, "t": 0.0201, "s": 0.034, "f": 0, "m": 0.0314, "q": 0, "b": 0, "r": 0.4427, "v": 0.0835, "a": 0.0232, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0.0318, "ns": 0.0314, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "c": {"n": 0.1367, "t": 0, "s": 0, "f": 0, "m": 0.0253, "q": 0, "b": 0, "r": 0.2692, "v": 0.2089, "a": 0.0321, "z": 0, "d": 0.108, "p": 0.0514, "c": 0.0296, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0.0274, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "u": {"n": 0.5251, "t": 0, "s": 0, "f": 0, "m": 0.043, "q": 0, "b": 0, "r": 0.0581, "v": 0.0781, "a": 0.0424, "z": 0, "d": 0.0276, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0.0414, "vx": 0, "ad": 0, "an": 0}, "y": {"n": 0, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0, "a": 0, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "e": {"n": 0, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0, "a": 0, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "o": {"n": 0, "t": 0, "s": 0, "f": 0, "m": 0.0412, "q": 0, "b": 0, "r": 0, "v": 0.1031, "a": 0, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "i": {"n": 0, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.0205, "a": 0, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "l": {"n": 0.0289, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.0433, "a": 0, "z": 0, "d": 0.0409, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "j": {"n": 0.2866, "t": 0, "s": 0, "f": 0.0258, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.0789, "a": 0, "z": 0, "d": 0.0304, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0.1251, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0.1348, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "h": {"n": 0.5789, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0.0351, "v": 0.0526, "a": 0.1228, "z": 0, "d": 0.0526, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0.0351, "vx": 0, "ad": 0, "an": 0}, "k": {"n": 0.0236, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0.0236, "v": 0.2505, "a": 0, "z": 0, "d": 0.1234, "p": 0.0526, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "g": {}, "x": {}, "w": {"n": 0.0859, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0.2504, "v": 0.1699, "a": 0, "z": 0, "d": 0.1199, "p": 0.0597, "c": 0.1215, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0.0376, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "nr": {"n": 0.1627, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.1824, "a": 0, "z": 0, "d": 0.0654, "p": 0.0393, "c": 0.0417, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0.1234, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "ns": {"n": 0.2905, "t": 0, "s": 0.0305, "f": 0.0397, "m": 0.0257, "q": 0, "b": 0, "r": 0, "v": 0.1452, "a": 0, "z": 0, "d": 0.0317, "p": 0, "c": 0.0274, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0.03, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "nt": {"n": 0.2051, "t": 0, "s": 0, "f": 0.0897, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.2436, "a": 0, "z": 0, "d": 0, "p": 0.0385, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0.0256, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0.0513, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "nx": {"n": 1.0, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0, "a": 0, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "nz": {"n": 0.3944, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.0646, "a": 0, "z": 0, "d": 0.0347, "p": 0, "c": 0.0221, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "vd": {"n": 0, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.7857, "a": 0, "z": 0, "d": 0.119, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "vn": {"n": 0.2322, "t": 0, "s": 0, "f": 0.0323, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.0619, "a": 0, "z": 0, "d": 0.0467, "p": 0, "c": 0.033, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0.0201, "vx": 0, "ad": 0, "an": 0}, "vx": {"n": 0.0396, "t": 0, "s": 0, "f": 0, "m": 0.0223, "q": 0, "b": 0, "r": 0.1609, "v": 0, "a": 0.052, "z": 0, "d": 0.0223, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0.4728, "vx": 0, "ad": 0, "an": 0.047}, "ad": {"n": 0, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.844, "a": 0.0336, "z": 0, "d": 0.0519, "p": 0.0528, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "an": {"n": 0, "t": 0, "s": 0, "f": 0.0246, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.1258, "a": 0, "z": 0, "d": 0.0912, "p": 0, "c": 0.0629, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}} No newline at end of file ballontranslator/data/testpacks/manga/original3.jpg 0 → 100644 +1.48 MiB Loading image diff... ballontranslator/dl/ocr/model_32px.py +5 −1 Original line number Diff line number Diff line Loading @@ -571,7 +571,11 @@ class OCR32pxModel: for blk_idx, textblk in enumerate(textblk_lst): for ii in range(len(textblk)): textblk_lst_indices.append(blk_idx) regions.append(textblk.get_transformed_region(img, ii, self.text_height)) region = textblk.get_transformed_region(img, ii, self.text_height) h, w = region.shape[:2] if w > 3064: # positional embedding requires width <= 3072 region = region[:, :3064] regions.append(region) region_idx += 1 # regions = [textblk.get_transformed_region(img, idx, self.text_height) for idx in range(len(textblk))] perm = range(len(regions)) Loading ballontranslator/dl/textdetector/textblock.py +55 −27 Original line number Diff line number Diff line Loading @@ -3,9 +3,10 @@ import numpy as np from shapely.geometry import Polygon import math import copy from utils.imgproc_utils import union_area, xywh2xyxypoly, rotate_polygons import cv2 from utils.imgproc_utils import union_area, xywh2xyxypoly, rotate_polygons, color_difference LANG_LIST = ['eng', 'ja', 'unknown'] LANGCLS2IDX = {'eng': 0, 'ja': 1, 'unknown': 2} Loading Loading @@ -34,14 +35,14 @@ class TextBlock(object): bold: bool = False, underline: bool = False, italic: bool = False, alignment: int = -1, _alignment: int = -1, alpha: float = 255, rich_text: str = "", _bounding_rect: List = None, accumulate_color = True, default_stroke_width = 0.2, font_weight = 50, target_lang: str = "", _target_lang: str = "", **kwargs) -> None: self.xyxy = [int(num) for num in xyxy] # boundingbox of textblock self.lines = [] if lines is None else lines # polygons of textlines Loading Loading @@ -77,9 +78,8 @@ class TextBlock(object): self.alpha = alpha self.rich_text = rich_text self.line_spacing = line_spacing # self.alignment = alignment self._alignment = alignment self._target_lang = target_lang self._alignment = _alignment self._target_lang = _target_lang self._bounding_rect = _bounding_rect self.default_stroke_width = default_stroke_width Loading Loading @@ -116,16 +116,20 @@ class TextBlock(object): norm_h = np.linalg.norm(middle_pnts[:, 1] - middle_pnts[:, 3]) return norm_v / norm_h def center(self): def center(self) -> np.ndarray: xyxy = np.array(self.xyxy) return (xyxy[:2] + xyxy[2:]) / 2 def min_rect(self, rotate_back=True): def unrotated_polygons(self) -> np.ndarray: angled = self.angle != 0 center = self.center() polygons = self.lines_array().reshape(-1, 8) if angled: polygons = rotate_polygons(center, polygons, self.angle) return angled, center, polygons def min_rect(self, rotate_back=True) -> List[int]: angled, center, polygons = self.unrotated_polygons() min_x = polygons[:, ::2].min() min_y = polygons[:, 1::2].min() max_x = polygons[:, ::2].max() Loading @@ -135,8 +139,17 @@ class TextBlock(object): min_bbox = rotate_polygons(center, min_bbox, -self.angle) return min_bbox.reshape(-1, 4, 2) def normalizd_width_list(self) -> List[float]: angled, center, polygons = self.unrotated_polygons() width_list = [] for polygon in polygons: width_list.append((polygon[[2, 4]] - polygon[[0, 6]]).sum()) width_list = np.array(width_list) width_list = width_list / np.sum(width_list) return width_list.tolist() # equivalent to qt's boundingRect, ignore angle def bounding_rect(self): def bounding_rect(self) -> List[int]: if self._bounding_rect is None: # if True: min_bbox = self.min_rect(rotate_back=False)[0] Loading Loading @@ -166,13 +179,6 @@ class TextBlock(object): direction = 'v' if self.vertical else 'h' src_pts = np.array(self.lines[idx], dtype=np.float64) if self.language == 'eng' or (self.language == 'unknown' and not self.vertical): e_size = self.font_size / 3 src_pts[..., 0] += np.array([-e_size, e_size, e_size, -e_size]) src_pts[..., 1] += np.array([-e_size, -e_size, e_size, e_size]) src_pts[..., 0] = np.clip(src_pts[..., 0], 0, im_w) src_pts[..., 1] = np.clip(src_pts[..., 1], 0, im_h) middle_pnt = (src_pts[[1, 2, 3, 0]] + src_pts) / 2 vec_v = middle_pnt[2] - middle_pnt[0] # vertical vectors of textlines vec_h = middle_pnt[1] - middle_pnt[3] # horizontal vectors of textlines Loading @@ -198,7 +204,14 @@ class TextBlock(object): def get_text(self): if isinstance(self.text, str): return self.text return ' '.join(self.text).strip() text = '' for t in self.text: if text and t: if text[-1].isalpha() and t[0].isalpha(): text += ' ' text += t return text.strip() def set_font_colors(self, frgb, srgb, accumulate=True): self.accumulate_color = accumulate Loading Loading @@ -239,11 +252,8 @@ class TextBlock(object): return 0 lines = self.lines_array() if len(lines) == 1: return 0 angled = self.angle != 0 polygons = lines.reshape(-1, 8) if angled: polygons = rotate_polygons((0, 0), polygons, self.angle) return 1 angled, center, polygons = self.unrotated_polygons() polygons = polygons.reshape(-1, 4, 2) left_std = np.std(polygons[:, 0, 0]) Loading @@ -259,10 +269,8 @@ class TextBlock(object): @property def stroke_width(self): var = np.array([self.fg_r, self.fg_g, self.fg_b]) \ - np.array([self.bg_r, self.bg_g, self.bg_b]) var = np.abs(var).sum() if var > 40: diff = color_difference(*self.get_font_colors()) if diff > 15: return self.default_stroke_width return 0 Loading Loading @@ -331,6 +339,8 @@ def examine_textblk(blk: TextBlock, im_w: int, im_h: int, eval_orientation: bool blk.angle = rotation_angle if vertical: blk.angle -= 90 if abs(blk.angle) < 3: blk.angle = 0 blk.font_size = font_size if eval_orientation: blk.vertical = vertical Loading Loading @@ -479,6 +489,24 @@ def group_output(blks, lines, im_w, im_h, mask=None, sort_blklist=True) -> List[ final_blk_list += merge_textlines(scattered_lines['ver']) if sort_blklist: final_blk_list = sort_textblk_list(final_blk_list, im_w, im_h) for blk in final_blk_list: if blk.language == 'eng': num_lines = len(blk.lines) if num_lines == 0: continue # blk.line_spacing = blk.bounding_rect()[3] / num_lines / blk.font_size resize_ratio = 1.1 expand_size = max(int(blk.font_size * 0.1), 2) rad = np.deg2rad(blk.angle) shifted_vec = np.array([[[-1, -1],[1, -1],[1, 1],[-1, 1]]]) shifted_vec = shifted_vec * np.array([[[np.sin(rad), np.cos(rad)]]]) * expand_size lines = blk.lines_array() + shifted_vec lines[..., 0] = np.clip(lines[..., 0], 0, im_w-1) lines[..., 1] = np.clip(lines[..., 1], 0, im_h-1) blk.lines = lines.astype(np.int64).tolist() blk.font_size += expand_size return final_blk_list def visualize_textblocks(canvas, blk_list: List[TextBlock]): Loading ballontranslator/ui/canvas.py +4 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ class Canvas(QGraphicsScene): finish_erasing = Signal(StrokeItem) delete_textblks = Signal() format_textblks = Signal() layout_textblks = Signal() begin_scale_tool = Signal(QPointF) scale_tool = Signal(QPointF) Loading Loading @@ -401,11 +402,14 @@ class Canvas(QGraphicsScene): menu = QMenu() delete_act = menu.addAction(self.tr("Delete")) format_act = menu.addAction(self.tr("Apply font formatting")) layout_act = menu.addAction(self.tr("Auto layout")) rst = menu.exec_(event.screenPos()) if rst == delete_act: self.delete_textblks.emit() elif rst == format_act: self.format_textblks.emit() elif rst == layout_act: self.layout_textblks.emit() def on_hide_canvas(self): self.alt_pressed = False Loading Loading
ballontranslator/data/pkusegscores.json 0 → 100644 +1 −0 Original line number Diff line number Diff line {"n": {"n": 0.0622, "t": 0, "s": 0, "f": 0.0405, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.1921, "a": 0, "z": 0, "d": 0.0891, "p": 0.0258, "c": 0.0228, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "t": {"n": 0.0736, "t": 1, "s": 0, "f": 0.027, "m": 0, "q": 0, "b": 0, "r": 0.172, "v": 0.2027, "a": 0, "z": 0, "d": 0.1426, "p": 0.0384, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "s": {"n": 0.0578, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.3442, "a": 0, "z": 0, "d": 0.102, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "f": {"n": 0.0501, "t": 0, "s": 0, "f": 0, "m": 0.0305, "q": 0, "b": 0, "r": 0.0302, "v": 0.2821, "a": 0, "z": 0, "d": 0.0829, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "m": {"n": 0.2381, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0.4929, "b": 0, "r": 0, "v": 0.0675, "a": 0.0355, "z": 0, "d": 0.0297, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "q": {"n": 0.4815, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0.0329, "v": 0.0943, "a": 0.0826, "z": 0, "d": 0.0447, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "b": {"n": 0.3708, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.026, "a": 0, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0.0207, "vx": 0, "ad": 0, "an": 0}, "r": {"n": 0.1064, "t": 0, "s": 0, "f": 0, "m": 0.0341, "q": 0, "b": 0, "r": 0.0441, "v": 0.2954, "a": 0.027, "z": 0, "d": 0.1562, "p": 0.0429, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "v": {"n": 0.1081, "t": 0, "s": 0, "f": 0, "m": 0.0432, "q": 0, "b": 0, "r": 0.1591, "v": 0.1757, "a": 0.0224, "z": 0, "d": 0.036, "p": 0.0421, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "a": {"n": 0.1464, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.0333, "a": 0.0281, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "z": {"n": 0.0737, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.1117, "a": 0.0306, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "d": {"n": 0, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0.0313, "v": 0.5905, "a": 0.1047, "z": 0, "d": 0.1317, "p": 0.0626, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "p": {"n": 0.2263, "t": 0.0201, "s": 0.034, "f": 0, "m": 0.0314, "q": 0, "b": 0, "r": 0.4427, "v": 0.0835, "a": 0.0232, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0.0318, "ns": 0.0314, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "c": {"n": 0.1367, "t": 0, "s": 0, "f": 0, "m": 0.0253, "q": 0, "b": 0, "r": 0.2692, "v": 0.2089, "a": 0.0321, "z": 0, "d": 0.108, "p": 0.0514, "c": 0.0296, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0.0274, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "u": {"n": 0.5251, "t": 0, "s": 0, "f": 0, "m": 0.043, "q": 0, "b": 0, "r": 0.0581, "v": 0.0781, "a": 0.0424, "z": 0, "d": 0.0276, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0.0414, "vx": 0, "ad": 0, "an": 0}, "y": {"n": 0, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0, "a": 0, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "e": {"n": 0, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0, "a": 0, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "o": {"n": 0, "t": 0, "s": 0, "f": 0, "m": 0.0412, "q": 0, "b": 0, "r": 0, "v": 0.1031, "a": 0, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "i": {"n": 0, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.0205, "a": 0, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "l": {"n": 0.0289, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.0433, "a": 0, "z": 0, "d": 0.0409, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "j": {"n": 0.2866, "t": 0, "s": 0, "f": 0.0258, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.0789, "a": 0, "z": 0, "d": 0.0304, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0.1251, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0.1348, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "h": {"n": 0.5789, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0.0351, "v": 0.0526, "a": 0.1228, "z": 0, "d": 0.0526, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0.0351, "vx": 0, "ad": 0, "an": 0}, "k": {"n": 0.0236, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0.0236, "v": 0.2505, "a": 0, "z": 0, "d": 0.1234, "p": 0.0526, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "g": {}, "x": {}, "w": {"n": 0.0859, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0.2504, "v": 0.1699, "a": 0, "z": 0, "d": 0.1199, "p": 0.0597, "c": 0.1215, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0.0376, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "nr": {"n": 0.1627, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.1824, "a": 0, "z": 0, "d": 0.0654, "p": 0.0393, "c": 0.0417, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0.1234, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "ns": {"n": 0.2905, "t": 0, "s": 0.0305, "f": 0.0397, "m": 0.0257, "q": 0, "b": 0, "r": 0, "v": 0.1452, "a": 0, "z": 0, "d": 0.0317, "p": 0, "c": 0.0274, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0.03, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "nt": {"n": 0.2051, "t": 0, "s": 0, "f": 0.0897, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.2436, "a": 0, "z": 0, "d": 0, "p": 0.0385, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0.0256, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0.0513, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "nx": {"n": 1.0, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0, "a": 0, "z": 0, "d": 0, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "nz": {"n": 0.3944, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.0646, "a": 0, "z": 0, "d": 0.0347, "p": 0, "c": 0.0221, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "vd": {"n": 0, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.7857, "a": 0, "z": 0, "d": 0.119, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "vn": {"n": 0.2322, "t": 0, "s": 0, "f": 0.0323, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.0619, "a": 0, "z": 0, "d": 0.0467, "p": 0, "c": 0.033, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0.0201, "vx": 0, "ad": 0, "an": 0}, "vx": {"n": 0.0396, "t": 0, "s": 0, "f": 0, "m": 0.0223, "q": 0, "b": 0, "r": 0.1609, "v": 0, "a": 0.052, "z": 0, "d": 0.0223, "p": 0, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0.4728, "vx": 0, "ad": 0, "an": 0.047}, "ad": {"n": 0, "t": 0, "s": 0, "f": 0, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.844, "a": 0.0336, "z": 0, "d": 0.0519, "p": 0.0528, "c": 0, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}, "an": {"n": 0, "t": 0, "s": 0, "f": 0.0246, "m": 0, "q": 0, "b": 0, "r": 0, "v": 0.1258, "a": 0, "z": 0, "d": 0.0912, "p": 0, "c": 0.0629, "u": 1, "y": 1, "e": 0, "o": 0, "i": 0, "l": 0, "j": 0, "h": 0, "k": 0, "g": 0, "x": 0, "w": 1, "nr": 0, "ns": 0, "nt": 0, "nx": 0, "nz": 0, "vd": 0, "vn": 0, "vx": 0, "ad": 0, "an": 0}} No newline at end of file
ballontranslator/dl/ocr/model_32px.py +5 −1 Original line number Diff line number Diff line Loading @@ -571,7 +571,11 @@ class OCR32pxModel: for blk_idx, textblk in enumerate(textblk_lst): for ii in range(len(textblk)): textblk_lst_indices.append(blk_idx) regions.append(textblk.get_transformed_region(img, ii, self.text_height)) region = textblk.get_transformed_region(img, ii, self.text_height) h, w = region.shape[:2] if w > 3064: # positional embedding requires width <= 3072 region = region[:, :3064] regions.append(region) region_idx += 1 # regions = [textblk.get_transformed_region(img, idx, self.text_height) for idx in range(len(textblk))] perm = range(len(regions)) Loading
ballontranslator/dl/textdetector/textblock.py +55 −27 Original line number Diff line number Diff line Loading @@ -3,9 +3,10 @@ import numpy as np from shapely.geometry import Polygon import math import copy from utils.imgproc_utils import union_area, xywh2xyxypoly, rotate_polygons import cv2 from utils.imgproc_utils import union_area, xywh2xyxypoly, rotate_polygons, color_difference LANG_LIST = ['eng', 'ja', 'unknown'] LANGCLS2IDX = {'eng': 0, 'ja': 1, 'unknown': 2} Loading Loading @@ -34,14 +35,14 @@ class TextBlock(object): bold: bool = False, underline: bool = False, italic: bool = False, alignment: int = -1, _alignment: int = -1, alpha: float = 255, rich_text: str = "", _bounding_rect: List = None, accumulate_color = True, default_stroke_width = 0.2, font_weight = 50, target_lang: str = "", _target_lang: str = "", **kwargs) -> None: self.xyxy = [int(num) for num in xyxy] # boundingbox of textblock self.lines = [] if lines is None else lines # polygons of textlines Loading Loading @@ -77,9 +78,8 @@ class TextBlock(object): self.alpha = alpha self.rich_text = rich_text self.line_spacing = line_spacing # self.alignment = alignment self._alignment = alignment self._target_lang = target_lang self._alignment = _alignment self._target_lang = _target_lang self._bounding_rect = _bounding_rect self.default_stroke_width = default_stroke_width Loading Loading @@ -116,16 +116,20 @@ class TextBlock(object): norm_h = np.linalg.norm(middle_pnts[:, 1] - middle_pnts[:, 3]) return norm_v / norm_h def center(self): def center(self) -> np.ndarray: xyxy = np.array(self.xyxy) return (xyxy[:2] + xyxy[2:]) / 2 def min_rect(self, rotate_back=True): def unrotated_polygons(self) -> np.ndarray: angled = self.angle != 0 center = self.center() polygons = self.lines_array().reshape(-1, 8) if angled: polygons = rotate_polygons(center, polygons, self.angle) return angled, center, polygons def min_rect(self, rotate_back=True) -> List[int]: angled, center, polygons = self.unrotated_polygons() min_x = polygons[:, ::2].min() min_y = polygons[:, 1::2].min() max_x = polygons[:, ::2].max() Loading @@ -135,8 +139,17 @@ class TextBlock(object): min_bbox = rotate_polygons(center, min_bbox, -self.angle) return min_bbox.reshape(-1, 4, 2) def normalizd_width_list(self) -> List[float]: angled, center, polygons = self.unrotated_polygons() width_list = [] for polygon in polygons: width_list.append((polygon[[2, 4]] - polygon[[0, 6]]).sum()) width_list = np.array(width_list) width_list = width_list / np.sum(width_list) return width_list.tolist() # equivalent to qt's boundingRect, ignore angle def bounding_rect(self): def bounding_rect(self) -> List[int]: if self._bounding_rect is None: # if True: min_bbox = self.min_rect(rotate_back=False)[0] Loading Loading @@ -166,13 +179,6 @@ class TextBlock(object): direction = 'v' if self.vertical else 'h' src_pts = np.array(self.lines[idx], dtype=np.float64) if self.language == 'eng' or (self.language == 'unknown' and not self.vertical): e_size = self.font_size / 3 src_pts[..., 0] += np.array([-e_size, e_size, e_size, -e_size]) src_pts[..., 1] += np.array([-e_size, -e_size, e_size, e_size]) src_pts[..., 0] = np.clip(src_pts[..., 0], 0, im_w) src_pts[..., 1] = np.clip(src_pts[..., 1], 0, im_h) middle_pnt = (src_pts[[1, 2, 3, 0]] + src_pts) / 2 vec_v = middle_pnt[2] - middle_pnt[0] # vertical vectors of textlines vec_h = middle_pnt[1] - middle_pnt[3] # horizontal vectors of textlines Loading @@ -198,7 +204,14 @@ class TextBlock(object): def get_text(self): if isinstance(self.text, str): return self.text return ' '.join(self.text).strip() text = '' for t in self.text: if text and t: if text[-1].isalpha() and t[0].isalpha(): text += ' ' text += t return text.strip() def set_font_colors(self, frgb, srgb, accumulate=True): self.accumulate_color = accumulate Loading Loading @@ -239,11 +252,8 @@ class TextBlock(object): return 0 lines = self.lines_array() if len(lines) == 1: return 0 angled = self.angle != 0 polygons = lines.reshape(-1, 8) if angled: polygons = rotate_polygons((0, 0), polygons, self.angle) return 1 angled, center, polygons = self.unrotated_polygons() polygons = polygons.reshape(-1, 4, 2) left_std = np.std(polygons[:, 0, 0]) Loading @@ -259,10 +269,8 @@ class TextBlock(object): @property def stroke_width(self): var = np.array([self.fg_r, self.fg_g, self.fg_b]) \ - np.array([self.bg_r, self.bg_g, self.bg_b]) var = np.abs(var).sum() if var > 40: diff = color_difference(*self.get_font_colors()) if diff > 15: return self.default_stroke_width return 0 Loading Loading @@ -331,6 +339,8 @@ def examine_textblk(blk: TextBlock, im_w: int, im_h: int, eval_orientation: bool blk.angle = rotation_angle if vertical: blk.angle -= 90 if abs(blk.angle) < 3: blk.angle = 0 blk.font_size = font_size if eval_orientation: blk.vertical = vertical Loading Loading @@ -479,6 +489,24 @@ def group_output(blks, lines, im_w, im_h, mask=None, sort_blklist=True) -> List[ final_blk_list += merge_textlines(scattered_lines['ver']) if sort_blklist: final_blk_list = sort_textblk_list(final_blk_list, im_w, im_h) for blk in final_blk_list: if blk.language == 'eng': num_lines = len(blk.lines) if num_lines == 0: continue # blk.line_spacing = blk.bounding_rect()[3] / num_lines / blk.font_size resize_ratio = 1.1 expand_size = max(int(blk.font_size * 0.1), 2) rad = np.deg2rad(blk.angle) shifted_vec = np.array([[[-1, -1],[1, -1],[1, 1],[-1, 1]]]) shifted_vec = shifted_vec * np.array([[[np.sin(rad), np.cos(rad)]]]) * expand_size lines = blk.lines_array() + shifted_vec lines[..., 0] = np.clip(lines[..., 0], 0, im_w-1) lines[..., 1] = np.clip(lines[..., 1], 0, im_h-1) blk.lines = lines.astype(np.int64).tolist() blk.font_size += expand_size return final_blk_list def visualize_textblocks(canvas, blk_list: List[TextBlock]): Loading
ballontranslator/ui/canvas.py +4 −0 Original line number Diff line number Diff line Loading @@ -78,6 +78,7 @@ class Canvas(QGraphicsScene): finish_erasing = Signal(StrokeItem) delete_textblks = Signal() format_textblks = Signal() layout_textblks = Signal() begin_scale_tool = Signal(QPointF) scale_tool = Signal(QPointF) Loading Loading @@ -401,11 +402,14 @@ class Canvas(QGraphicsScene): menu = QMenu() delete_act = menu.addAction(self.tr("Delete")) format_act = menu.addAction(self.tr("Apply font formatting")) layout_act = menu.addAction(self.tr("Auto layout")) rst = menu.exec_(event.screenPos()) if rst == delete_act: self.delete_textblks.emit() elif rst == format_act: self.format_textblks.emit() elif rst == layout_act: self.layout_textblks.emit() def on_hide_canvas(self): self.alt_pressed = False Loading