Python 边缘梯度

Python 边缘梯度,python,image-processing,canny-operator,Python,Image Processing,Canny Operator,我有一个包含两类图像的数据集:城市景观和景观。我想做的是计算每个图像边缘的梯度(方向),并显示城市景观的图像比景观图像具有更多的垂直/水平边缘 我所做的是计算垂直、水平、45度和135度边缘。我对图像应用了Canny过滤器,计算了x、y梯度,还对图像应用了阈值,显示了高于该阈值的边缘。该阈值的结果如下所示: 这是我处理图像以及计算渐变的代码: def gradient(image): # Step 1 img = image gray = cv2.cvtColo

我有一个包含两类图像的数据集:城市景观和景观。我想做的是计算每个图像边缘的梯度(方向),并显示城市景观的图像比景观图像具有更多的垂直/水平边缘

我所做的是计算垂直、水平、45度和135度边缘。我对图像应用了Canny过滤器,计算了x、y梯度,还对图像应用了阈值,显示了高于该阈值的边缘。该阈值的结果如下所示:

这是我处理图像以及计算渐变的代码:

def gradient(image):    

    # Step 1
    img = image
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    # Step 2
    bi = cv2.bilateralFilter(gray, 15, 75, 75)

    # Step 3
    dst = cv2.Canny(bi, 100, 200)
    #print(np.count_nonzero(dst))  #--> make sure it's not all zeroes

    # Step 4
    #--- create a black image to see where those edges occur ---
    mask = np.zeros_like(gray)

    #--- applying a threshold and turning those pixels above the threshold to white ---           
    mask[dst > 0.1 * dst.max()] = 255

    # Step 5
    img[dst > 0.1 * dst.max()] = [255, 0, 0]   #--- [255, 0, 0] --> Red ---

    Gx = cv2.Sobel(mask,cv2.CV_64F,1,0,ksize=5)
    Gy = cv2.Sobel(mask,cv2.CV_64F,0,1,ksize=5)

    #orientation of the edges
    theta = np.arctan2(Gy, Gx)

    #magnitude
    M = np.sqrt(Gx*Gx + Gy*Gy)

    #Vertical edges: 
    v = abs(Gy)

    #Horizontal edges: 
    h = abs(Gx)

    #45 Degree edges: 
    deg45 = M*abs(np.cos(theta - np.pi/4))

    #135 Degree edges: 
    deg135 = M*abs(np.cos(theta - 3*np.pi/4))

    print('Vertical:')
    #print(v)
    print(np.count_nonzero(v))
    print('Horizontal:')
    #print(h)
    print(np.count_nonzero(h))
我想要的是计算上图中显示为红色的边的
v,h,deg45,deg135
(步骤5)。如果不可能,则对具有白色边缘的图像执行该操作(步骤4)。有人能帮忙吗


编辑:为了避免混淆,我要做的是获得给定图像中垂直、水平等边缘的数量,以便我可以比较城市景观和景观图像的这些数字。

如果您想要的是包含水平和垂直边缘的像素总数,我建议为水平与垂直(比如15度)定义一些阈值。因此,您可以计算
θ
的元素数
abs(θ)
(水平) 或
abs(θ)>pi/12
(水平) 或
pi/2-pi/12
(垂直)

您在
v
h
中存储的是每个点处梯度的垂直和水平分量,您需要的是比较
v
h
的值,以确定每个点的梯度向量应计为水平还是垂直。比较θ可能是最直观的方法

为了得到满足特定条件的θ元素数,我建议使用:

sum(θif中的i为1(abs(i)pi/12))

例如,将为您提供水平边缘像素的数量。

我认为Hough变换更适合您的需要如果您想计算或控制图像中的线性特征数量,您可以计算每个特定方向(在Hough空间中)的线性特征数量。一旦您使用Python,链接可能会有所帮助

你能解释一下“计算边缘的v,h,deg45,deg135”是什么意思吗?我有垂直,水平,45度和135度角梯度的公式。我想做的是对图像中的每个红色边缘,找到边缘的梯度,然后计算垂直、水平等的数量。对于每个图像,垂直、水平等梯度是什么意思?梯度是一个向量,不应该随方向而改变。你想要梯度在(0,1)、(1,0)、(1,1)和(1,-1)方向上的投影吗?你是对的。我的意思是,我想计算一幅图像中有多少条垂直边。(如果这更清楚的话)垂直边是否需要精确的水平渐变?水平方向在+/-5度以内?15度?您是否已经定义了边或仅定义了像素级渐变?您是否更关心垂直边的总长度或垂直边的总数量(总长度非常简单,但总数量可能需要您运行某种聚类算法)?谢谢您的回答。我将如何应用此阈值?我会使用if条件来应用上面定义的条件吗?有很多方法。您可以在θ上循环并使用if语句。您可以放弃if语句,只需将布尔表达式的结果添加到计数器(1表示true,0表示false)。你也可以使用生成器表达式,我认为这是最快的方法。我对答案进行了编辑,加入了这种方法的一个例子。你能解释一下为什么要计算θ来获得水平/垂直边缘吗?另外,在你写的生成器表达式中,如果i满足条件,你要做的是得到1,然后遍历θ中的所有值,并求和这些1?我计算属于水平或垂直边的像素,因此最终你会得到水平或垂直边的总长度(或很好的近似值)。如果你想计算边的数量而不考虑长度,那么你必须以某种方式将像素分组成边。一旦你这样做了,你可以用上面相同的方法来计算它们,你只需要使用θ,即每边对每像素。
sum(1 for i in theta if (abs(i)<pi/12) or (abs(i)>pi-pi/12))