Browse Source

Solved alphabet

Vsevolod Levitan 11 months ago
parent
commit
ce3a38cf58
3 changed files with 112 additions and 0 deletions
  1. BIN
      alphabet/alphabet.png
  2. 112 0
      alphabet/main.py
  3. BIN
      alphabet/symbols.png

BIN
alphabet/alphabet.png


+ 112 - 0
alphabet/main.py

@@ -0,0 +1,112 @@
+import os
+import matplotlib.pyplot as plt
+import numpy as np
+from skimage.filters import threshold_otsu
+from skimage.measure import label, regionprops
+from collections import defaultdict
+
+
+def filling_factor(arr):
+    return np.sum(arr) / arr.size
+
+
+def count_holes(arr):
+    labeled = label(np.logical_not(arr))
+    regions = regionprops(labeled)
+    holes = 0
+    for region in regions:
+        coords = np.transpose(region.coords, (1, 0))
+        ymin = np.min(coords[1])
+        ymax = np.max(coords[1])
+        xmin = np.min(coords[0])
+        xmax = np.max(coords[0])
+        if (
+            ymin == 0
+            or ymax == arr.shape[1] - 1
+            or xmin == 0
+            or xmax == arr.shape[0] - 1
+        ):
+            continue
+        holes += 1
+    return holes
+
+
+def count_holes_rame(arr):
+    labeled = label(np.logical_not(arr))
+    return np.max(labeled)
+
+
+def count_vline(arr):
+    return np.sum(arr.mean(0) == 1)
+
+
+def recognize(region):
+    if filling_factor(region.image) == 1.0:
+        return "-"
+    else:
+        holes = count_holes(region.image)
+        if holes == 2:  # B or 8
+            if count_vline(region.image) >= 3:
+                return "B"
+            else:
+                return "8"
+        elif holes == 1:  # A or 0
+            if count_vline(region.image) >= 2:
+                ecc = region.eccentricity
+                if ecc < 0.65:
+                    return "D"
+                else:
+                    return "P"
+            else:
+                if (
+                    abs(
+                        (region.local_centroid[0] / region.image.shape[0])
+                        - (region.local_centroid[1] / region.image.shape[1])
+                    )
+                    > 0.02
+                ):
+                    return "A"
+                else:
+                    return "0"
+        else:
+            if count_vline(region.image) >= 1:
+                return "1"
+            else:
+                ecc = region.eccentricity
+                if ecc < 0.4:
+                    return "*"
+                match count_holes_rame(region.image):
+                    case 2:
+                        return "/"
+                    case 4:
+                        return "X"
+                    case _:
+                        return "W"
+
+
+img = plt.imread("./symbols.png")
+
+img = np.mean(img, axis=2)
+thrash = threshold_otsu(img)
+img[img > 0] = 1
+
+regions = regionprops(label(img))
+
+result = {}
+
+path = "./res"
+if not os.path.exists(path):
+    os.mkdir(path)
+
+for i, region in enumerate(regions):
+    symbol = recognize(region)
+    if symbol in ["P", "D"]:
+        plt.clf()
+        plt.title(f"{symbol}")
+        plt.imshow(region.image)
+        plt.savefig(f"{path}/{i}")
+        if symbol not in result.keys():
+            result[symbol] = 0
+        result[symbol] += 1
+
+print(result, sum(result.values()))

BIN
alphabet/symbols.png