1)使用高斯滤波器,以平滑图像,滤除噪声
2)计算图像中每个像素点的梯度强度和方向
3)应用非极大值抑制,以消除边缘检测带来的杂散响应
4)应用双阈值检测来确定真实的和潜在的边缘
5)通过抑制孤立的弱边缘最终完成边缘检测
1.高斯滤波器
2.梯度和方向
3.非极大值抑制
4.双阈值检测
import cv2
import numpy as np
def cv_show(im, name):
cv2.imshow(name, im)
cv2.waitKey(0)
cv2.destroyAllWindows()
img = cv2.imread('data/test2.jpg', cv2.IMREAD_GRAYSCALE)
img = cv2.resize(img, (400, 400))
v1 = cv2.Canny(img, 80, 150)
v2 = cv2.Canny(img, 50, 100)
res = np.hstack((img, v1, v2))
cv_show(res, 'res')
结论:区间值越大,检测的边界越少;区间值越少,检测的边界越多。
高斯金字塔
拉普拉斯金字塔
高斯金字塔:向下采样方法(缩小)
高斯金字塔:向上采样方法(放大)
import cv2
import numpy as np
def cv_show(im, name):
cv2.imshow(name, im)
cv2.waitKey(0)
cv2.destroyAllWindows()
img = cv2.imread('data/dog.jpg')
img = cv2.resize(img, (400, 400))
up = cv2.pyrUp(img)
cv_show(up, 'up')
down = cv2.pyrDown(img)
cv_show(down, 'down')
reset = cv2.pyrUp(down)
res = np.hstack([img, reset])
cv_show(res, 'res')
上采样的结果
下采样的结果
原图和先上采样再下采样的图
拉普拉斯金字塔
import cv2
import numpy as np
def cv_show(im, name):
cv2.imshow(name, im)
cv2.waitKey(0)
cv2.destroyAllWindows()
img = cv2.imread('data/dog.jpg')
img = cv2.resize(img, (400, 400))
up = cv2.pyrUp(img)
down = cv2.pyrDown(img)
reset = cv2.pyrUp(down)
res = np.hstack([img, reset, img - reset])
cv_show(res, 'res')
cv2.findContours(img, mode, method)
mode:轮廓检索模式
method:轮廓逼近方法
模板匹配和卷积原理很像,模板在原图像上从原点开始滑动,计算模板与(图像被模板覆盖的地方)的差别程度,这个差别程度的计算方法在opencv中有六种,将每次计算的结果放入一个矩阵里,作为结果输出。假如原图像是AxB大小,而模板是axb大小,则输出的结果矩阵是(A-a+1)x(B-b+1)
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('data/lena.png', cv2.IMREAD_GRAYSCALE)
template = cv2.imread('data/face.png', cv2.IMREAD_GRAYSCALE)
w, h = template.shape[0], template.shape[1]
methods = ['cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED', 'cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_SQDIFF',
'cv2.TM_SQDIFF_NORMED']
for meth in methods:
img2 = img.copy()
method = eval(meth)
print(method)
res = cv2.matchTemplate(img, template, method)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
# 如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED取最小值
if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
top_left = min_loc
else:
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
# 画矩形
cv2.rectangle(img2, top_left, bottom_right, 255, 2)
plt.subplot(121), plt.imshow(res, cmap='gray')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img2, cmap='gray')
plt.xticks([]), plt.yticks([])
plt.suptitle(meth)
plt.show()
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('data/lena.png', cv2.IMREAD_GRAYSCALE)
res = cv2.calcHist(images=[img], channels=[0], mask=None, histSize=[256], ranges=[0, 256])
print(res.shape) # (256, 1)
plt.hist(img.ravel(), 256)
plt.show()
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('data/lena.png')
color = ('b', 'g', 'r')
for i, col in enumerate(color):
histr = cv2.calcHist([img], [i], None, [256], [0, 256])
plt.plot(histr, color=col)
plt.xlim([0, 256])
plt.show()
傅里叶变换的作用
滤波
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('data/lena.png', cv2.IMREAD_GRAYSCALE)
img_float32 = np.float32(img)
dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
# 得到灰度图能表示的形式
magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('magnitude spectrum'), plt.xticks([]), plt.yticks([])
plt.show()
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('data/lena.png', cv2.IMREAD_GRAYSCALE)
img_float32 = np.float32(img)
dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
rows, cols = img.shape
c_row, c_col = int(rows / 2), int(cols / 2) # 中心位置
# 低通滤波器
mask = np.zeros((rows, cols, 2), np.uint8)
mask[c_row - 30:c_row + 30, c_col - 30:c_col + 30] = 1
# IDFT
f_shift = dft_shift * mask
f_ishift = np.fft.ifftshift(f_shift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img_back, cmap='gray')
plt.title('Result'), plt.xticks([]), plt.yticks([])
plt.show()
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('data/lena.png', cv2.IMREAD_GRAYSCALE)
img_float32 = np.float32(img)
dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
rows, cols = img.shape
c_row, c_col = int(rows / 2), int(cols / 2) # 中心位置
# 高通滤波器
mask = np.ones((rows, cols, 2), np.uint8)
mask[c_row - 30:c_row + 30, c_col - 30:c_col + 30] = 0
# IDFT
f_shift = dft_shift * mask
f_ishift = np.fft.ifftshift(f_shift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img_back, cmap='gray')
plt.title('Result'), plt.xticks([]), plt.yticks([])
plt.show()