检测或拆分网格中的图标
Detect or split icons in a grid
我正在为智能手机游戏编写第三方工具应用程序。在这个游戏中,有一个页面显示网格中的图标:
我想做一个可以检测并拆分出这些图标的功能。
我尝试了很多东西,比如 Sudoku detection, Detecting grids in images。
按照这些教程,我得到的最好结果是这样的:
这不是一个好的结果,我不知道接下来我能做些什么来处理它。
我觉得难的原因是:
- 底色好浓
- 图标内的内容比它们之间的分隔符要丰富得多。
- 其实没有分隔线,只有图标周围的边框。
那么有没有什么算法可以模糊检测正方形呢?或者任何其他 approach/suggestion 来解决这个问题?
我建议考虑一下你的图标的边框颜色几乎是白色的,图标包含在一个网格中。
因此,适当的 阈值 将引导您进入这样的状态:
import cv2
BGR = cv2.imread('input.jpg')
Cpy = BGR.copy()
# Thresholding
Cpy[Cpy[...,0]!=Cpy[...,1]]=0
Cpy[Cpy[...,2]<200]=0
Cpy[Cpy>0]= 1
之后你需要找到角:
import numpy as np
rowSum = Cpy[...,0].sum(axis=0)
colSum = Cpy[...,0].sum(axis=1)
rows = np.zeros_like(Cpy)
cols = np.zeros_like(Cpy)
mask = np.zeros_like(Cpy)
# Not sure if these values will work always
rows[:, rowSum>100] = 1
cols[colSum>200, :] = 1
mask = rows*cols
y0 = np.min(np.nonzero(mask.sum(axis=1))[0])
y1 = np.max(np.nonzero(mask.sum(axis=1))[0])
x0 = np.min(np.nonzero(mask.sum(axis=0))[0])
x1 = np.max(np.nonzero(mask.sum(axis=0))[0])
mask[y0:y1, x0:x1] = 1
mask1 = mask*rows
mask2 = mask*cols
mask = np.maximum(mask1, mask2)
之后,你可以随意使用任何方法来检测你的图像,因为你的图标有角,这里我使用形态膨胀来处理角,并且标签:
SE = np.ones((16,16))
dilated = cv2.dilate(mask, SE)
dilated [...,1:3] = 0
from skimage.measure import label
labelled = label(1-dilated [...,0])
现在你有了你的面具,因此你可以检测你的图像:
labelled[labelled==1] = 0
labelled[labelled >0] = 1
labelled = labelled.astype(np.uint8)
res = cv2.bitwise_and(BGR,BGR,mask = labelled)
cv2.namedWindow('Splitted Images', cv2.WINDOW_NORMAL)
cv2.imshow('Splitted Images', res)
cv2.waitKey(0)
我正在为智能手机游戏编写第三方工具应用程序。在这个游戏中,有一个页面显示网格中的图标:
我想做一个可以检测并拆分出这些图标的功能。 我尝试了很多东西,比如 Sudoku detection, Detecting grids in images。 按照这些教程,我得到的最好结果是这样的:
这不是一个好的结果,我不知道接下来我能做些什么来处理它。 我觉得难的原因是:
- 底色好浓
- 图标内的内容比它们之间的分隔符要丰富得多。
- 其实没有分隔线,只有图标周围的边框。
那么有没有什么算法可以模糊检测正方形呢?或者任何其他 approach/suggestion 来解决这个问题?
我建议考虑一下你的图标的边框颜色几乎是白色的,图标包含在一个网格中。
因此,适当的 阈值 将引导您进入这样的状态:
import cv2
BGR = cv2.imread('input.jpg')
Cpy = BGR.copy()
# Thresholding
Cpy[Cpy[...,0]!=Cpy[...,1]]=0
Cpy[Cpy[...,2]<200]=0
Cpy[Cpy>0]= 1
之后你需要找到角:
import numpy as np
rowSum = Cpy[...,0].sum(axis=0)
colSum = Cpy[...,0].sum(axis=1)
rows = np.zeros_like(Cpy)
cols = np.zeros_like(Cpy)
mask = np.zeros_like(Cpy)
# Not sure if these values will work always
rows[:, rowSum>100] = 1
cols[colSum>200, :] = 1
mask = rows*cols
y0 = np.min(np.nonzero(mask.sum(axis=1))[0])
y1 = np.max(np.nonzero(mask.sum(axis=1))[0])
x0 = np.min(np.nonzero(mask.sum(axis=0))[0])
x1 = np.max(np.nonzero(mask.sum(axis=0))[0])
mask[y0:y1, x0:x1] = 1
mask1 = mask*rows
mask2 = mask*cols
mask = np.maximum(mask1, mask2)
之后,你可以随意使用任何方法来检测你的图像,因为你的图标有角,这里我使用形态膨胀来处理角,并且标签:
SE = np.ones((16,16))
dilated = cv2.dilate(mask, SE)
dilated [...,1:3] = 0
from skimage.measure import label
labelled = label(1-dilated [...,0])
现在你有了你的面具,因此你可以检测你的图像:
labelled[labelled==1] = 0
labelled[labelled >0] = 1
labelled = labelled.astype(np.uint8)
res = cv2.bitwise_and(BGR,BGR,mask = labelled)
cv2.namedWindow('Splitted Images', cv2.WINDOW_NORMAL)
cv2.imshow('Splitted Images', res)
cv2.waitKey(0)