如何使用Sobel运算符在图像中找到基本形状(砖,圆柱,球体)?

时间:2018-09-10 22:05:12

标签: python computer-vision edge-detection sobel

Sample 1- Brick Sample 2- Sphere

我已经计算出了Sobel梯度的大小和方向。但是我仍然坚持如何将其进一步用于形状检测。

图像>灰度>索贝尔过滤>索贝尔梯度和方向计算>接下来?

使用的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)

1 个答案:

答案 0 :(得分:0)

您可以使用以下形状的鲜明特征:

  • 一块砖有几个笔直的边缘(从四个角度到六个角度,具体取决于角度);

  • 一个球体具有单个弯曲的边缘;

  • 一个圆柱体有两个弯曲的边缘和直的边缘(尽管它们可以完全隐藏)。

使用二值化(基于亮度和/或饱和度)并提取轮廓。然后找到直线段,可能使用Douglas-Peucker简化算法。最后,分析直线和弯曲边缘的顺序。


解决最终分类任务的一种可能方法是将轮廓表示为一串直或弯曲的块,并粗略地指示出长度(短/中/长)。如果分割不完美,每个形状将对应一组图案。

您可以在培训阶段学习最多的模式,然后使用字符串匹配(其中字符串被视为循环)。可能会有联系要仲裁。另一种选择是近似字符串匹配。