|
@@ -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()))
|