我已经计算了索贝尔梯度的大小和方向。但我一直不知道如何进一步使用它来进行形状检测。
图像>灰度>索贝尔过滤>索贝尔梯度和方向计算>下一步?
使用的 Sobel 内核是:
Kx = ([[1, 0, -1],[2, 0, -2],[1, 0, -1]])
Ky = ([[1, 2, 1],[0, 0, 0],[-1, -2, -1]])
(我只能使用 Numpy,不能使用其他 Python 语言的库。)
import numpy as np
def classify(im):
#Convert to grayscale
gray = convert_to_grayscale(im/255.)
#Sobel kernels as numpy arrays
Kx = np.array([[1, 0, -1],[2, 0, -2],[1, 0, -1]])
Ky = np.array([[1, 2, 1],[0, 0, 0],[-1, -2, -1]])
Gx = filter_2d(gray, Kx)
Gy = filter_2d(gray, Ky)
G = np.sqrt(Gx**2+Gy**2)
G_direction = np.arctan2(Gy, Gx)
#labels = ['brick', 'ball', 'cylinder']
#Let's guess randomly! Maybe we'll get lucky.
#random_integer = np.random.randint(low = 0, high = 3)
return labels[random_integer]
def filter_2d(im, kernel):
'''
Filter an image by taking the dot product of each
image neighborhood with the kernel matrix.
'''
M = kernel.shape[0]
N = kernel.shape[1]
H = im.shape[0]
W = im.shape[1]
filtered_image = np.zeros((H-M+1, W-N+1), dtype = 'float64')
for i in range(filtered_image.shape[0]):
for j in range(filtered_image.shape[1]):
image_patch = im[i:i+M, j:j+N]
filtered_image[i, j] = np.sum(np.multiply(image_patch, kernel))
return filtered_image
def convert_to_grayscale(im):
'''
Convert color image to grayscale.
'''
return np.mean(im, axis = 2)
最佳答案
您可以使用形状的以下独特特征:
一 block 砖有几个直边(从四到六个,具体取决于视角);
球体有一个弯曲的边缘;
圆柱体有两个弯曲边缘和两个直边缘(尽管它们可以完全隐藏)。
使用二值化(基于亮度和/或饱和度)并提取轮廓。然后找到直线部分,可能使用 Douglas-Peucker 简化算法。最后分析直边和弯边的顺序。
<小时/>解决最终分类任务的一种可能方法是将轮廓表示为一串 block ,无论是直的还是弯曲的,并粗略地指示长度(短/中/长)。由于分割不完善,每个形状都会对应一组模式。
您可以通过训练阶段来学习最多的模式,然后使用字符串匹配(其中字符串被视为循环)。可能会有需要仲裁的关系。另一种选择是近似字符串匹配。
关于python - 如何使用 Sobel 算子在图像中查找基本形状(砖 block 、圆柱体、球体)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52266119/