我在关注这个 视频 我想弄明白他是如何找到对应于特定线条的矩阵的。他说垂直边缘检测矩阵是。
[1 0 -1
1 0 -1
1 0 -1]
我怎么才能找到矩阵能给我什么样的角度线呢? 比如说,如果我在找一条水平线,或者4530度的线,我怎么才能找到矩阵?
更新。 我测试了aminrd的函数,如下所示 形象 使用3个不同的角度。45、90和180度
#Convolve function for convolving a filter on an image
# import the necessary packages
from skimage.exposure import rescale_intensity
import numpy as np
import argparse
import cv2
def convolve(image, kernel):
# grab the spatial dimensions of the image, along with
# the spatial dimensions of the kernel
(iH, iW) = image.shape[:2]
(kH, kW) = kernel.shape[:2]
# allocate memory for the output image, taking care to
# "pad" the borders of the input image so the spatial
# size (i.e., width and height) are not reduced
pad = (kW - 1) // 2
image = cv2.copyMakeBorder(image, pad, pad, pad, pad,
cv2.BORDER_REPLICATE)
output = np.zeros((iH, iW), dtype="float32")
# loop over the input image, "sliding" the kernel across
# each (x, y)-coordinate from left-to-right and top to
# bottom
for y in np.arange(pad, iH + pad):
for x in np.arange(pad, iW + pad):
# extract the ROI of the image by extracting the
# *center* region of the current (x, y)-coordinates
# dimensions
roi = image[y - pad:y + pad + 1, x - pad:x + pad + 1]
# perform the actual convolution by taking the
# element-wise multiplicate between the ROI and
# the kernel, then summing the matrix
k = (roi * kernel).sum()
# store the convolved value in the output (x,y)-
# coordinate of the output image
output[y - pad, x - pad] = k
# rescale the output image to be in the range [0, 255]
output = rescale_intensity(output, in_range=(0, 255))
output = (output * 255).astype("uint8")
# return the output image
return output
import matplotlib.pyplot as plt
#original image
image = cv2.imread('circle.jpg')
plt.figure(figsize=(10,10))
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
# as opencv loads in BGR format by default, we want to show it in RGB.
plt.show()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
new_img= convolve(gray, create_filter(1, 180))
plt.figure(figsize=(10,10))
plt.imshow(new_img, cmap='Greys_r')
plt.show()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
new_img= convolve(gray, create_filter(1, 90))
plt.figure(figsize=(10,10))
plt.imshow(new_img, cmap='Greys_r')
plt.show()
45度角的输出图像看起来是一样的。我用几张图片试了一下,似乎也是一样的。所以我不知道是不是我遗漏了什么,但是这个功能似乎45度、90度和180度角的输出结果都差不多。
考虑一个黑白图像。什么是线呢,当你放大一条垂直线时,从左到右(或从右到左)有一个对比。
因此,在图像中的实心区域(没有边缘的地方),这个卷积滤波器会产生0(因为1和-1会相互抵消)。但当滤波器到达线条时,卷积会产生一个很大的正值或负值。
可以应用它来检测水平线,使用其中一个滤波器(假设滤波器的大小是3x3)。
[1 1 1
0 0 0
-1 -1 -1]
#OR
[-1 -1 -1
0 0 0
1 1 1]
为了推广这个概念,a 3x3
窗口对其他度数来说不够大。对于其他度数的卷积滤波器,最好是放大这个卷积滤波器的大小。例如,对于一个尺寸为5的45度卷积滤波器,你可以使用。
0 0 0 1 0
0 0 1 0 -1
0 1 0 -1 0
1 0 -1 0 0
0 -1 0 0 0
要创建随机度数的滤波器,你可以使用以下功能:
import numpy as np
def create_filter(filter_size, degree):
filter = np.zeros((2*filter_size+1, 2*filter_size+1))
tetha = (degree / 180) * np.pi
for x in range(-filter_size, filter_size+1):
y = int(x * np.tan(tetha))
if np.abs(y) + 1 <= filter_size and np.abs(y) - 1 <= filter_size:
filter[x + filter_size][y + filter_size + 1] = 1
filter[x + filter_size][y + filter_size - 1] = -1
return filter
create_filter(6, 30)
# Output:
# array([[ 0., 0., -1., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
# [ 0., 0., 0., -1., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
# [ 0., 0., 0., -1., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
# [ 0., 0., 0., 0., -1., 0., 1., 0., 0., 0., 0., 0., 0.],
# [ 0., 0., 0., 0., -1., 0., 1., 0., 0., 0., 0., 0., 0.],
# [ 0., 0., 0., 0., 0., -1., 0., 1., 0., 0., 0., 0., 0.],
# [ 0., 0., 0., 0., 0., -1., 0., 1., 0., 0., 0., 0., 0.],
# [ 0., 0., 0., 0., 0., -1., 0., 1., 0., 0., 0., 0., 0.],
# [ 0., 0., 0., 0., 0., 0., -1., 0., 1., 0., 0., 0., 0.],
# [ 0., 0., 0., 0., 0., 0., -1., 0., 1., 0., 0., 0., 0.],
# [ 0., 0., 0., 0., 0., 0., 0., -1., 0., 1., 0., 0., 0.],
# [ 0., 0., 0., 0., 0., 0., 0., -1., 0., 1., 0., 0., 0.],
# [ 0., 0., 0., 0., 0., 0., 0., 0., -1., 0., 1., 0., 0.]])