边缘梯度 Python
Gradient of edges Python
我有一个包含两个 类 图像的数据集:Cityscape 和 Landscape。我想要做的是计算每个图像边缘的梯度(方向)并显示城市景观图像比风景图像具有更多 vertical/horizontal 边缘。
我所做的是计算垂直、水平、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 度)。所以你可以计算 theta
的元素数量
abs(theta) < pi/12
(横向)
或 abs(theta) > pi-pi/12
(水平)
或 pi/2 - pi/12 < abs(theta) < pi/2+pi/12
(垂直)
您在 v
和 h
中存储的是每个点的梯度的垂直和水平分量,您需要比较 v
和 v
的值h
来确定每个点的梯度向量是水平的还是垂直的。比较 theta
可能是最直观的方法。
为了获得满足特定条件的 theta 元素的数量,我建议使用 generator expression:
sum(1 for i in theta if (abs(i)<pi/12) or (abs(i)>pi-pi/12))
例如会给你水平边缘像素的数量。
如果你想计算或控制图像中有多少线性特征,我认为 Hough 变换更适合你的需要,你可以计算每个特定方向有多少线性特征(在 hough space).一旦您开始使用 Python,this and this link 可能会有帮助!
我有一个包含两个 类 图像的数据集:Cityscape 和 Landscape。我想要做的是计算每个图像边缘的梯度(方向)并显示城市景观图像比风景图像具有更多 vertical/horizontal 边缘。
我所做的是计算垂直、水平、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 度)。所以你可以计算 theta
的元素数量
abs(theta) < pi/12
(横向)
或 abs(theta) > pi-pi/12
(水平)
或 pi/2 - pi/12 < abs(theta) < pi/2+pi/12
(垂直)
您在 v
和 h
中存储的是每个点的梯度的垂直和水平分量,您需要比较 v
和 v
的值h
来确定每个点的梯度向量是水平的还是垂直的。比较 theta
可能是最直观的方法。
为了获得满足特定条件的 theta 元素的数量,我建议使用 generator expression:
sum(1 for i in theta if (abs(i)<pi/12) or (abs(i)>pi-pi/12))
例如会给你水平边缘像素的数量。
如果你想计算或控制图像中有多少线性特征,我认为 Hough 变换更适合你的需要,你可以计算每个特定方向有多少线性特征(在 hough space).一旦您开始使用 Python,this and this link 可能会有帮助!