检测或分割网格中的图标

rib*_*ynn 2 opencv image-processing edge-detection

我正在为智能手机游戏编写第三方工具应用程序。在这个游戏中,有一个页面在网格中显示图标:

截屏

我想做一个可以检测并拆分这些图标的功能。我尝试了很多东西,比如数独检测检测图像中的网格。通过遵循这些教程,我得到的最好结果是这样的:

在此输入图像描述 在此输入图像描述

这不是一个好的结果,我不知道接下来我可以做什么来处理它。我认为困难的原因是:

  • 背景颜色太强烈了。
  • 图标内的内容比它们之间的分隔符丰富得多。
  • 实际上,没有分隔线,只有图标周围的框架。

那么有没有什么算法可以模糊地检测正方形呢?或者有其他方法/建议来解决这个问题吗?

Bil*_*lal 5

我建议考虑一下图标的边框颜色几乎是白色的,并且图标包含在网格中。

因此,适当的阈值将导致您遇到这样的情况:

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
Run Code Online (Sandbox Code Playgroud)

th

之后你需要找到角点

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)
Run Code Online (Sandbox Code Playgroud)

角落

之后,您可以自由地使用任何方法来检测您的图像,因为您有图标的角点,这里我使用形态膨胀来处理角点,并标记

SE = np.ones((16,16))
dilated = cv2.dilate(mask, SE)
dilated [...,1:3] = 0

from skimage.measure import label

labelled = label(1-dilated [...,0])
Run Code Online (Sandbox Code Playgroud)

面具

现在你有了面具,因此你可以检测你的图像:

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)
Run Code Online (Sandbox Code Playgroud)

结果