SZU 【图像处理】课堂练习
2024-06-09 本文已影响0人
Du1in9
第 1 周
from skimage import data, color
from matplotlib import pyplot as plt
img = data.coffee()
# 将图像转换为灰度图像
gray = color.rgb2gray(img)
plt.imshow(gray, cmap='gray')
plt.show()
# 将图像从RGB颜色空间转换为HSV颜色空间
hsv_img = color.convert_colorspace(img, 'RGB', 'HSV')
plt.imshow(hsv_img)
plt.show()
![](https://img.haomeiwen.com/i21107801/e42d5fd3f840dd2c.png)
from skimage import data
from matplotlib import pyplot as plt
import numpy as np
img = data.coffee()
# 创建用于存储灰度图像的数组
max_gray = np.zeros(img.shape[0:2], dtype='uint8')
ave_gray = np.zeros(img.shape[0:2], dtype='uint8')
weight_gray = np.zeros(img.shape[0:2], dtype='uint8')
# 遍历图像的每个像素
for i in range(img.shape[0]):
for j in range(img.shape[1]):
r, g, b = img[i, j, :]
# 最大值法:取像素的最大值作为灰度值
max_gray[i, j] = max(r, g, b)
# 平均值法:将红、绿、蓝三个通道的值相加后除以3
ave_gray[i, j] = (r + g + b) / 3.0
# 加权平均法:使用固定的权重将红、绿、蓝三个通道的值加权求和
weight_gray[i, j] = 0.30 * r + 0.59 * g + 0.11 * b
# 设置字体为中文黑体
plt.rcParams['font.sans-serif'] = ['SimHei']
# 创建子图并显示原始彩色图像以及三种灰度化结果
plt.subplot(221), plt.axis('off')
plt.imshow(img), plt.title('彩色图像')
plt.subplot(222), plt.axis('off')
plt.imshow(max_gray, cmap='gray'), plt.title('最大值法')
plt.subplot(223), plt.axis('off')
plt.imshow(ave_gray, cmap='gray'), plt.title('平均值法')
plt.subplot(224), plt.axis('off')
plt.imshow(weight_gray, cmap='gray'), plt.title('加权平均法')
plt.show()
![](https://img.haomeiwen.com/i21107801/501278e48473496c.png)
from skimage import io,color
from matplotlib import pyplot as plt
import numpy as np
image = io.imread('image\JJ.jpg')
r = image[:,:,0]
g = image[:,:,1]
b = image[:,:,2]
b_template = np.zeros(image.shape, dtype = 'uint8')
for i in range(b.shape[0]):
for j in range(b.shape[1]):
if b[i, j] <= 100:
b_template[i, j] = 1
image2 = image * b_template
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.subplot(221),plt.axis('off')
plt.imshow(image),plt.title('原始RGB图像')
plt.subplot(222),plt.axis('off')
plt.imshow(b, cmap='gray'),plt.title('B分量')
plt.subplot(223),plt.axis('off')
plt.imshow(color.rgb2gray(b_template), cmap='gray')
plt.title('蓝色通道模板')
plt.subplot(224),plt.axis('off')
plt.imshow(image2),plt.title('分割后的RGB图像')
plt.show()
第 2 周
import numpy as np
from skimage import data, color
from matplotlib import pyplot as plt
def cov2d(img, window):
# 获取窗口的尺寸
m, n = window.shape
# 获取图像的尺寸
h, w = img.shape
# 通过在边界填充0灰度值来扩展图像
img1 = np.zeros((h + m - 1, w + n - 1))
img1[(m-1)//2 : h+(m-1)//2, (n-1)//2 : (w+(n-1)//2)] = img
# 创建与原图像大小相同的零矩阵
img2 = np.zeros(img.shape)
# 对图像进行卷积操作
for i in range(img2.shape[0]):
for j in range(img2.shape[1]):
# 获取当前窗口区域
temp = img1[i: i + m, j: j + n]
# 计算窗口区域与卷积核的乘积并求和
img2[i, j] = np.sum(np.multiply(temp, window))
return img2
img = data.chelsea()
img = color.rgb2gray(img)
# 定义一个3x3的平均滤波器
window = np.ones((3, 3)) / (3 ** 2)
# 对图像进行卷积操作
new_img = cov2d(img, window)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.subplot(121), plt.axis('off')
plt.imshow(img, cmap='gray'), plt.title('原图像')
plt.subplot(122), plt.axis('off')
plt.imshow(new_img, cmap='gray'), plt.title('3核平滑卷积结果')
plt.show()
![](https://img.haomeiwen.com/i21107801/30bad2b009a101e8.png)
import numpy as np
from scipy import signal
from skimage import data
import matplotlib.pyplot as plt
# 定义二维灰度图像的空间滤波函数
def correl2d(img, window):
# 使用滤波器实现图像的空间相关
# mode='same' 表示输出尺寸等于输入尺寸
# boundary='fill' 表示滤波前,用常量值填充原图像的边缘,默认常量
s = signal.correlate2d(img, window, mode='same', boundary='fill')
return s
img = data.camera()
window1 = np.ones((3, 3)) / (3 ** 2)
window2 = np.ones((5, 5)) / (5 ** 2)
window3 = np.ones((9, 9)) / (9 ** 2)
new_img1 = correl2d(img, window1)
new_img2 = correl2d(img, window2)
new_img3 = correl2d(img, window3)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.subplot(221), plt.axis('off')
plt.imshow(img, cmap='gray'), plt.title('原图像')
plt.subplot(222), plt.axis('off')
plt.imshow(new_img1, cmap='gray'), plt.title('3*3')
plt.subplot(223), plt.axis('off')
plt.imshow(new_img2, cmap='gray'), plt.title('5*5')
plt.subplot(224), plt.axis('off')
plt.imshow(new_img3, cmap='gray'), plt.title('9*9')
plt.show()
![](https://img.haomeiwen.com/i21107801/fa2b399f0d615de0.png)
from scipy import ndimage
from skimage import data, color, util
from matplotlib import pyplot as plt
img = color.rgb2gray(data.astronaut())
noise_img = util.random_noise(img, mode='s&p',seed=None,clip=True) # 对图像加入椒盐噪声
new_img= ndimage.median_filter(noise_img,(3, 3)) # 中值滤波
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.subplot(131),plt.axis('off')
plt.imshow(img, cmap = 'gray'),plt.title('原图像')
plt.subplot(132),plt.axis('off')
plt.imshow(noise_img, cmap = 'gray'),plt.title('加噪图像')
plt.subplot(133),plt.axis('off')
plt.imshow(new_img, cmap = 'gray'),plt.title('中值滤波')
plt.show()
![](https://img.haomeiwen.com/i21107801/10193b0e22a0b0cf.png)
第 3 周
import numpy as np
from scipy import signal
from skimage import data
from matplotlib import pyplot as plt
#定义二维灰度图像的空间滤波函数
def cov2d(img, window):
s= signal.correlate2d(img, window, mode ='same',boundary ='fill')
return s
# img为原始图像
img = data.camera()
window = np.ones((7,7))
img_blur = cov2d(img, window)
img_edge = img - img_blur
img_enhance = img + img_edge
# plt.rcParams['font.sans-serif'] = ['SimHei']
# plt.subplot(221),plt.axis('off')
# plt.imshow(img, cmap = 'gray'),plt.title('原图像')
# plt.subplot(222),plt.axis('off')
# plt.imshow(img_blur, cmap = 'gray'),plt.title('模糊图像')
# plt.subplot(223),plt.axis('off')
# plt.imshow(img_edge, cmap = 'gray'),plt.title('差值图像')
# plt.subplot(224),plt.axis('off')
# plt.imshow(img_enhance, cmap = 'gray'),plt.title('锐化增强')
# plt.show()
plt.rcParams['font.sans-serif'] = ['SimHei']
k = [1, 2, 3, 4]
for r in k:
img_enhance = img + r * img_edge
plt.subplot(2, 2, r),plt.axis('off')
plt.imshow(img_enhance, cmap = 'gray'),plt.title(u'权重系数为{}'.format(r))
plt.show()
![](https://img.haomeiwen.com/i21107801/0baa782611d85029.png)
import math
import numpy as np
from scipy import signal
from skimage import data
from matplotlib import pyplot as plt
# 定义二维灰度图像的空间滤波函数
def cov2d(img, window):
return signal.correlate2d(img, window, mode ='same',boundary ='fill')
img = data.camera()
window1 = np.array([[-1, 0], [1, 0]])
window2 = np.array([[-1, 1], [0, 0]])
img_h= cov2d(img, window1)
img_v= cov2d(img, window2)
img_hv= np.zeros(img.shape)
for i in range(img.shape[0]):
for j in range(img.shape[1]):
img_hv[i, j] = math.sqrt(img_h[i, j] ** 2 + img_v[i, j] ** 2)
plt.rcParams['font.sans-serif'] = ['SimHei']
c = [img, img_h, img_v, img_hv]
s = ['原图像', '水平边缘图像', '竖直边缘图像', '梯度图像']
for r in range(4):
plt.subplot(2, 2, r + 1),plt.axis('off')
plt.imshow(c[r], cmap = 'gray'),plt.title(s[r])
plt.show()
![](https://img.haomeiwen.com/i21107801/ff7fd6d605ef5800.png)
from skimage import data
import numpy as np
from matplotlib import pyplot as plt
img = data.camera()
ft = abs(np.fft.fft2(img)) # 快速傅里叶变换算法得到频率分布
log = np.log(ft) # 对数显示
shift = abs(np.fft.fftshift(ft)) # 将ft后的频谱图像平移
log_shift = np.log(shift) # 频移后对数显示
plt.rcParams['font.sans-serif'] = ['SimHei']
c = [ft, log, shift, log_shift]
s = ['傅里叶变换', '对数显示', '频谱图像平移', '频移后对数显示']
for i in range(4):
plt.subplot(2, 2, i + 1)
plt.imshow(c[i], 'gray')
plt.title(s[i])
plt.show()
![](https://img.haomeiwen.com/i21107801/49bfbe22bedd976a.png)
import numpy as np
import matplotlib.pyplot as plt
#实现圆孔低通滤波器
m,n = 256,256
mid_m, mid_n = int(m/2),int(n/2) #找到傅里叶频谱图的中心点
LowpassMask = np.zeros((m,n),np.uint8) #生成空矩阵,数据格式为uint8
rd = [10, 20, 50, 100]
c = 1
for r in rd:
for i in range(m):
for j in range(n):
d = np.sqrt((i-mid_m)**2 + (j-mid_n)**2)
if d <= r:
# 将距离频谱中心小于D的部分低通信息设置为1,属于低通滤波
LowpassMask[i,j] = 1
plt.subplot(2, 2, c), plt.title('r={}'.format(r))
plt.imshow(LowpassMask,cmap='gray'),
c += 1
plt.show()
![](https://img.haomeiwen.com/i21107801/c56bf7fb990cd78b.png)
第 4 周
import numpy as np
from skimage import data, exposure
import matplotlib.pyplot as plt
# 从skimage加载咖啡图像,并提取其第一个通道(灰度图像)
img = data.coffee()[:, :, 0]
# 计算灰度图像的直方图的函数
def histogram(grayfig):
x = grayfig.shape[0]
y = grayfig.shape[1]
ret = np.zeros(256) # 初始化一个数组,用于存储每个灰度级别的直方图计数
for i in range(x):
for j in range(y):
ret[grayfig[i][j]] += 1 # 增加对应灰度级别的计数
return ret
# 使用自定义函数计算图像的直方图
GrayHist_1 = histogram(img)
# 使用skimage的内置函数计算图像的直方图
GrayHist_2, bins = exposure.histogram(img)
plt.figure()
plt.subplot(311), plt.imshow(img, cmap='gray')
plt.subplot(312), plt.plot(GrayHist_1)
plt.subplot(313), plt.plot(GrayHist_2)
plt.show()
![](https://img.haomeiwen.com/i21107801/e5a66a855693c0e4.png)
from skimage import data, exposure
import matplotlib.pyplot as plt
img = data.coffee()[:, :, 0]
img_hist, bins = exposure.histogram(img)
plt.figure(figsize=(4,6))
plt.subplot(311), plt.plot(bins, img_hist)
plt.subplot(312), plt.bar(bins, img_hist)
plt.subplot(313), plt.hist(img.flatten())
plt.show()
![](https://img.haomeiwen.com/i21107801/eccc67d979653613.png)
from skimage import data
import matplotlib.pyplot as plt
img = data.coffee()
img_r = img[:,:,0]
img_g = img[:,:,1]
img_b = img[:,:,2]
arr = img.flatten()
arr_r = img_r.flatten()
arr_g = img_g.flatten()
arr_b = img_b.flatten()
plt.figure(figsize=(6, 8)) # 调整图像大小
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False # 修正参数名
plt.subplot(421), plt.axis('off'), plt.imshow(img), plt.title('原彩色图像')
plt.subplot(422), plt.hist(arr, bins=256) # 修改直方图的颜色
plt.subplot(423), plt.axis('off'), plt.imshow(img_r, cmap='gray'), plt.title('R通道')
plt.subplot(425), plt.axis('off'), plt.imshow(img_g, cmap='gray'), plt.title('G通道')
plt.subplot(427), plt.axis('off'), plt.imshow(img_b, cmap='gray'), plt.title('B通道')
plt.subplot(424), plt.hist(arr_r, bins=256, color='red')
plt.subplot(426), plt.hist(arr_g, bins=256, color='green')
plt.subplot(428), plt.hist(arr_b, bins=256, color='blue')
plt.show()
![](https://img.haomeiwen.com/i21107801/596881a67f935b03.png)
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
# 绘制直方图
def histogram(grayfig):
x = grayfig.shape[0] # 获取图像的高度
y = grayfig.shape[1] # 获取图像的宽度
ret = np.zeros(256) # 初始化直方图数组,包含256个灰度级
for i in range(x): # 遍历图像的每一行
for j in range(y): # 遍历图像的每一列
k = grayfig[i][j] # 获取像素点的灰度值
ret[k] = ret[k] + 1 # 统计对应灰度级的像素数量
return ret # 返回直方图数组
# 绘制累积直方图
def histogram_sum(grayfig):
x = grayfig.shape[0]
y = grayfig.shape[1]
ret = np.zeros(256)
for i in range(x):
for j in range(y):
k = grayfig[i][j]
ret[k] = ret[k] + 1
for k in range(256): # 遍历所有灰度级
ret[k] = ret[k] + ret[k - 1] # 计算累积直方图,累加每个灰度级的像素数量
return ret
img_r = data.coffee()[:, :, 0] # 读取咖啡图像的红色通道
hist_r = histogram(img_r) # 计算咖啡图像红色通道的直方图
hist_r = hist_r / hist_r.max() # 归一化处理直方图
histSum_r = histogram_sum(img_r) # 计算咖啡图像红色通道的累积直方图
histSum_r = histSum_r / histSum_r.max() # 归一化处理累积直方图
plt.figure(figsize=(8, 4))
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.subplot(121), plt.title("普通直方图"), plt.bar(range(256), hist_r)
plt.subplot(122), plt.title("累积直方图"), plt.bar(range(256), histSum_r, color='y')
plt.show()
![](https://img.haomeiwen.com/i21107801/4c5d6c6222ebe4d3.png)
from skimage import data, exposure
import matplotlib.pyplot as plt
# 读取咖啡图像的红色通道
img_r = data.coffee()[:,:,0]
# 计算红色通道的直方图
hist_r, bins = exposure.histogram(img_r)
# 计算红色通道的累积直方图
hist_sum_r, bins = exposure.cumulative_distribution(img_r)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.subplot(221), plt.bar(bins, hist_r), plt.title("直方图")
plt.subplot(222), plt.bar(bins, hist_sum_r, color='y'), plt.title("累加直方图")
plt.subplot(223), plt.plot(bins, hist_r), plt.title("直方图")
plt.subplot(224), plt.plot(bins, hist_sum_r, color='y'), plt.title("累加直方图")
plt.show()
![](https://img.haomeiwen.com/i21107801/f585fc9f66eb76ca.png)
from skimage import data
import matplotlib.pyplot as plt
img_r = data.coffee()[:,:,0]
arr_r = img_r.flatten()
plt.figure(figsize=(8,4))
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.subplot(121), plt.title("直方图")
plt.hist(arr_r,
bins=256, # 指定直方图的组距
density=True, # 设置为频率直方图
# cumulative=True, # 积累直方图
# color='y', # 指定填充色
# edgecolor='w', # 指定直方图的边界色
# label='直方图' # 为直方图呈现标签
)
plt.subplot(122), plt.title("累加直方图")
plt.hist(arr_r, # 绘图数据
bins=256, # 指定直方图的组距
density=True, # 设置为频率直方图
cumulative=True, # 积累直方图
color='y', # 指定填充色
# edgecolor='w', # 指定直方图的边界色
# label='累加直方图' # 为直方图呈现标签
)
plt.show()
![](https://img.haomeiwen.com/i21107801/b917a421ff4355b5.png)
import matplotlib.pyplot as plt
from skimage import data, exposure
reference = data.coffee() # 参考图像
image = data.chelsea() # 待匹配图像
# 对待匹配图像进行直方图匹配,使其与参考图像的直方图相匹配
matched = exposure.match_histograms(image, reference, multichannel=True)
# 创建绘图窗口和子图
fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3, figsize=(8, 3), sharex=True, sharey=True)
# 遍历子图并设置坐标轴关闭
for aa in (ax1, ax2, ax3):
aa.set_axis_off()
ax1.imshow(image), ax1.set_title('源图像')
ax2.imshow(reference), ax2.set_title('参考图像')
ax3.imshow(matched), ax3.set_title('匹配后图像')
# 调整布局并显示绘图
plt.tight_layout(), plt.show()
![](https://img.haomeiwen.com/i21107801/ae9b0525eda261eb.png)
第 5 周
import matplotlib.pyplot as plt
from skimage import data
from skimage.feature import graycomatrix, graycoprops
image = data.camera()
PATCH_SIZE=50
# 选择图像中的天空区域块
sky_locations =[(54,48),(21,233),(90,380),(55,330)]
sky_patches =[]
for loc in sky_locations:
sky_patches.append(image[loc[0]:loc[0]+ PATCH_SIZE,loc[1]:loc[1]+ PATCH_SIZE])
#选择图像中的草地区域块
grass_locations =[(387,186),(348,372),(330,447),(462,443)]
grass_patches = []
for loc in grass_locations:
grass_patches.append(image[loc[0]:loc[0]+ PATCH_SIZE,loc[1]:loc[1]+ PATCH_SIZE])
# plt.figure()
plt.imshow(image, cmap='gray')
for (y, x)in grass_locations:
plt.plot(x, y, 'gs')
for (y, x)in sky_locations:
plt.plot(x, y, 'bs')
plt.show()
![](https://img.haomeiwen.com/i21107801/4488ddedddcc9c2c.png)
import matplotlib.pyplot as plt
from skimage import data
from skimage.feature import graycomatrix, graycoprops
# 载入示例图像
image = data.camera()
# 定义采样区域大小
PATCH_SIZE = 50
# 天空区域位置
sky_locations = [(54, 48), (21, 233), (90, 380), (55, 330)]
sky_patches = []
for loc in sky_locations:
sky_patches.append(image[loc[0]:loc[0] + PATCH_SIZE, loc[1]:loc[1] + PATCH_SIZE])
# 草地区域位置
grass_locations = [(387, 186), (348, 372), (330, 447), (462, 443)]
grass_patches = []
for loc in grass_locations:
grass_patches.append(image[loc[0]:loc[0] + PATCH_SIZE, loc[1]:loc[1] + PATCH_SIZE])
# 创建画布
plt.figure(figsize=(8, 5))
# 绘制天空区域
for i, patch in enumerate(sky_patches):
plt.subplot(2, len(sky_patches), i + 1)
plt.imshow(patch, cmap=plt.cm.gray, interpolation='nearest', vmin=0, vmax=255)
plt.title('Sky %d' % (i + 1))
# 绘制草地区域
for i, patch in enumerate(grass_patches):
plt.subplot(2, len(grass_patches), len(grass_patches) * 1 + i + 1)
plt.imshow(patch, cmap=plt.cm.gray, interpolation='nearest', vmin=0, vmax=255)
plt.title('Grass %d' % (i + 1))
# 显示图像
plt.show()
![](https://img.haomeiwen.com/i21107801/6f14ff56c27a7960.png)
import matplotlib.pyplot as plt
from skimage import data
from skimage.feature import graycomatrix, graycoprops
# 载入示例图像
image = data.camera()
# 定义采样区域大小
PATCH_SIZE = 50
# 天空区域位置和草地区域位置
sky_locations = [(54, 48), (21, 233), (90, 380), (55, 330)]
grass_locations = [(387, 186), (348, 372), (330, 447), (462, 443)]
# 提取天空和草地区域
sky_patches, grass_patches = [], []
for loc in sky_locations:
sky_patches.append(image[loc[0]:loc[0] + PATCH_SIZE, loc[1]:loc[1] + PATCH_SIZE])
for loc in grass_locations:
grass_patches.append(image[loc[0]:loc[0] + PATCH_SIZE, loc[1]:loc[1] + PATCH_SIZE])
# 计算天空区域的灰度共生矩阵属性
xs, ys = [], []
for patch in sky_patches:
glcm = graycomatrix(patch, [5], [0], 256, symmetric=True, normed=True)
xs.append(graycoprops(glcm, 'dissimilarity')[0, 0])
ys.append(graycoprops(glcm, 'correlation')[0, 0])
# 计算草地区域的灰度共生矩阵属性
xg, yg = [], []
for patch in grass_patches:
glcm = graycomatrix(patch, [5], [0], 256, symmetric=True, normed=True)
xg.append(graycoprops(glcm, 'dissimilarity')[0, 0])
yg.append(graycoprops(glcm, 'correlation')[0, 0])
# 绘制散点图
plt.figure()
plt.plot(xs, ys, 'bo', label='Sky')
plt.plot(xg, yg, 'go', label='Grass')
plt.xlabel('GLCM Dissimilarity')
plt.ylabel('GLCM Correlation')
plt.legend()
plt.show()
![](https://img.haomeiwen.com/i21107801/570b9fc1cb57f478.png)
from skimage import io, color
import skimage.feature
import matplotlib.pyplot as plt
# image = data.coffee()
# image = io.imread('brick.jpg')
# image = io.imread('image/face.jpg')
image = io.imread('../image/face2.jpg')
# 将图像转换为灰度图
img = color.rgb2gray(image)
# 计算局部二值模式特征
texture = skimage.feature.local_binary_pattern(img, 8, 1.0, method='default')
# 绘制图像和特征图
plt.figure()
plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title('灰度图像')
plt.subplot(122), plt.imshow(texture, cmap='gray'), plt.title('纹理图像')
plt.show()
![](https://img.haomeiwen.com/i21107801/68fbdd4b74bb93e7.png)
# 导入所需的库
from skimage import io, color, exposure, feature
import matplotlib.pyplot as plt
# 读取图像并将其转换为灰度图像
image = io.imread('../image/face.jpg')
img = color.rgb2gray(image)
# 提取图像的局部二值模式特征,使用不同的方法
texture1 = feature.local_binary_pattern(img, 8, 1.0, method='default')
texture2 = feature.local_binary_pattern(img, 8, 1.0, method='ror')
texture3 = feature.local_binary_pattern(img, 8, 1.0, method='uniform')
# 计算各个特征的直方图
textureHist1, bins = exposure.histogram(texture1)
textureHist1 = textureHist1 / textureHist1.max()
textureHist2, bins = exposure.histogram(texture2)
textureHist2 = textureHist2 / textureHist2.max()
textureHist3, bins = exposure.histogram(texture3)
textureHist3 = textureHist3 / textureHist3.max()
# 绘制图像和特征的直方图
plt.figure(figsize=(6, 7))
plt.subplot(321), plt.imshow(texture1, cmap='gray')
plt.subplot(322), plt.plot(bins, textureHist1)
plt.subplot(323), plt.imshow(texture2, cmap='gray')
plt.subplot(324), plt.plot(bins, textureHist2)
plt.subplot(325), plt.imshow(texture3, cmap='gray')
plt.subplot(326), plt.plot(bins, textureHist3)
plt.show()
![](https://img.haomeiwen.com/i21107801/115472d0e88d06b8.png)
第 6 周
import cv2
imgFile="../image/circle.jpg"#读取文件的路径
img = cv2.imread(imgFile)
imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 彩色转灰度
t, binary = cv2.threshold(imgGray, 127,255, cv2.THRESH_BINARY) # 二值化
# 检测图像中出现的所有轮廓,记录轮廓的每一个点
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
#绘制所有轮廓,宽度为5,颜色为红色
cv2.drawContours(img, contours, -1,(0, 0, 255),3)
cv2.imshow("Demo",img)
cv2.waitKey()
cv2.destroyAllindows()
![](https://img.haomeiwen.com/i21107801/8f588b3c778e01fb.png)
import cv2
import numpy as np
from skimage import data,color
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('../image/test_img2.jpg')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255,0)
contours,hierarchy= cv2.findContours(thresh,1,2)
cv2.drawContours(img, contours, -1,(0, 255, 0), 2)
cnt = contours[0]
M= cv2.moments(cnt)
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])
print(cx,cy)
plt.imshow(img)
plt.plot(cx,cy,'rs')
plt.show()
![](https://img.haomeiwen.com/i21107801/7c721b2625c619ef.png)
import cv2
import numpy as np
from skimage import data,color
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('../image/test_img.jpg')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255,0)
contours,hierarchy= cv2.findContours(thresh,1,2)
cv2.drawContours(img, contours, -1,(0, 255, 0), 2)
cnt = contours[0]
M= cv2.moments(cnt)
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])
area = cv2.contourArea(cnt)
# area = M['m00']
perimeter= cv2.arcLength(cnt,True)
print('面积:', area)
print('周长:', perimeter)
plt.imshow(img, cmap='gray')
plt.plot(cx,cy,'rs')
plt.show()
![](https://img.haomeiwen.com/i21107801/447356194a4b79e7.png)
import cv2
img = cv2.imread('../image/test_img.jpg')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127,255,0)
contours,hierarchy= cv2.findContours(thresh,1,2)
cv2.drawContours(img,contours,-1,(0,255,0),2)
cnt=contours[0]
#(x,y)为矩形左上角的坐标,(w,h)是矩形的宽和高
x,y,w,h=cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),2)
cv2.imshow('1', img)
cv2.waitKey()
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i21107801/52c27d51180f46e4.png)
import cv2
import numpy as np
img = cv2.imread('../image/test_img.jpg')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127,255,0)
contours,hierarchy = cv2.findContours(thresh,1,2)
cv2.drawContours(img, contours, -1,(0, 255, 0), 2)
cnt=contours[0]
rect =cv2.minAreaRect(cnt)#找面积最小的矩形
box=cv2.boxPoints(rect)# 得到最小矩形的坐标
box=np.int0(box)# 标准化坐标到整数
cv2.drawContours(img, [box],0,(0,0,255),2)#画出边界
cv2.imshow('1', img)
cv2.waitKey()
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i21107801/7216ee97f3769bf9.png)
import cv2
img = cv2.imread('../image/test_img.jpg')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
contours,hierarchy = cv2.findContours(thresh,1,2)
cv2.drawContours(img,contours,-1,(0,255,0),2)
cnt=contours[0]
(x,y),radius = cv2.minEnclosingCircle(cnt)
center =(int(x),int(y))
radius = int(radius)
img = cv2.circle(img,center,radius,(0,0,255),2)
cv2.imshow('1', img)
cv2.waitKey()
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i21107801/698b5d186e7e3631.png)
import cv2
# reading image
img = cv2.imread('../image/shapes.jpg')
#converting image into grayscale image
gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# setting threshold of gray image
_, threshold = cv2.threshold(gray, 127,255, cv2.THRESH_BINARY)
# using a findContours() function
contours,_= cv2.findContours(threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img, contours, -1,(0,0, 255),2)
cv2.imshow('window', img)
cv2.waitKey()
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i21107801/00fa544179b60941.png)
import cv2
# reading image
img = cv2.imread('../image/shapes.jpg')
# converting image into grayscale image
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# setting threshold of gray image
_, threshold = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# using a findContours() function
contours, _ = cv2.findContours(
threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
i = 0
# list for storing names of shapes
for contour in contours:
# here we are ignoring first counter because
# findcontour function detects whole image as shape
if i == 0:
i = 1
continue
# cv2.approxPloyDP() function to approximate the shape
approx = cv2.approxPolyDP(
contour, 0.01 * cv2.arcLength(contour, True), True)
# using drawContours() function
cv2.drawContours(img, [contour], 0, (0, 0, 255), 2)
# finding center point of shape
M = cv2.moments(contour)
if M['m00'] != 0.0:
x = int(M['m10'] / M['m00'])
y = int(M['m01'] / M['m00'])
# putting shape name at center of each shape
if len(approx) == 3:
cv2.putText(img, 'Triangle', (x, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 0), 2)
elif len(approx) == 4:
cv2.putText(img, 'Quadrilateral', (x, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 0), 2)
elif len(approx) == 5:
cv2.putText(img, 'Pentagon', (x, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 0), 2)
elif len(approx) == 6:
cv2.putText(img, 'Hexagon', (x, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 0), 2)
else:
cv2.putText(img, 'circle', (x, y),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 0), 2)
# displaying the image after drawing contours
cv2.imshow('shapes', img)
cv2.waitKey()
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i21107801/fd6f8747efa9b78f.png)
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('../image/bird.jpg')
edges = cv.Canny(img, 10, 50)
edges2= cv.Canny(img, 50, 100)
edges3 = cv.Canny(img, 100, 200)
plt.figure(figsize=(8,8))
plt.subplot(221),plt.imshow(img)
plt.title('Original lmage'), plt.xticks([]), plt.yticks([])
plt.subplot(222),plt.imshow(edges,cmap = 'gray')
plt.title('Edge lmage'), plt.xticks([]), plt.yticks([])
plt.subplot(223),plt.imshow(edges2,cmap = 'gray')
plt.title('Edge lmage'), plt.xticks([]), plt.yticks([])
plt.subplot(224),plt.imshow(edges3,cmap = 'gray')
plt.title('Edge lmage'), plt.xticks([]), plt.yticks([])
plt.show()
![](https://img.haomeiwen.com/i21107801/4fd9f94713e8f0a9.png)
第 7 周
import cv2
import numpy as np
img = cv2.imread("../image/bird.jpg")
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化处理
_, imgBinary = cv2.threshold(imgray, 127, 255, cv2.THRESH_BINARY)
# 定义一个5x5的卷积核
kernel = np.ones((5, 5), np.uint8)
# 对二值化图像进行腐蚀操作
erosion = cv2.erode(imgBinary, kernel)
# 显示原始图像、二值化图像和腐蚀后的图像
cv2.imshow('Original Image', img)
cv2.imshow('Binary Image', imgBinary)
cv2.imshow('Eroded Image', erosion)
# 等待按键,然后关闭所有窗口
cv2.waitKey()
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i21107801/5c14f698b83e123a.png)
import cv2
import numpy as np
img = cv2.imread('../image/bird.jpg')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, imgBinary = cv2.threshold(imgray, 127, 255, cv2.THRESH_BINARY)
kernel = np.ones((9, 9), np.uint8)
erosion = cv2.erode(imgBinary, kernel)
erosion2 = cv2.dilate(imgBinary, kernel)
erosion3 = erosion2 - erosion
cv2.imshow('fig1', erosion)
cv2.imshow('fig2', erosion2)
cv2.imshow('fig3', erosion3)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i21107801/96ce97a95f457059.png)
import cv2
img = cv2.imread('../image/bird.jpg')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gaussian =cv2.GaussianBlur(imgray,(3,3),0,0, cv2.BORDER_DEFAULT)
median =cv2.medianBlur(gaussian,5)
sobel =cv2.Sobel(median,cv2.CV_8U,1,0,ksize=3)
ret, binary = cv2.threshold(sobel,170,255,cv2.THRESH_BINARY)
cv2.imshow('window',binary)
cv2.waitKey()
cv2.destroyAllwindows()
![](https://img.haomeiwen.com/i21107801/ab3c0223c572ee06.png)
import cv2
import numpy as np
def GetRegion(img):
regions = []
# 寻找轮廓
contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
area = cv2.contourArea(contour)
if area < 2000:
continue
# 近似轮廓以减少点的数量
eps = 0.1 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, eps, True)
# 获取最小外接矩形
rect = cv2.minAreaRect(contour)
box = cv2.boxPoints(rect)
box = np.int0(box)
height = abs(box[0][1] - box[2][1])
width = abs(box[0][0] - box[2][0])
# 计算宽高比
ratio = float(width) / float(height)
# 检查宽高比是否在一定范围内
if 1.8 < ratio < 5:
regions.append(box)
return regions
img = cv2.imread('../image/bird.jpg')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 进行膨胀操作
prc = cv2.dilate(imgray, None, iterations=2)
# 获取感兴趣区域
regions = GetRegion(prc)
# 在原始图像上显示感兴趣的区域(矩形框)
for box in regions:
cv2.drawContours(img, [box], 0, (0, 255, 0), 2)
# 显示带有感兴趣区域的图像
cv2.imshow('window', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i21107801/195dc9d11cc78d49.png)
第 8 周
import cv2 # 导入 OpenCV 库
import numpy as np # 导入 NumPy 库
# 读取待检测物体图像和模板图像
img = cv2.imread("../image/face.jpg") # 读取待检测物体图像
template = cv2.imread("../image/eyes.jpg") # 读取模板图像
# 获取模板图像的宽度和高度
w, h = template.shape[:2][::-1]
# 在待检测物体图像中进行模板匹配
res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)
# 设定匹配阈值
threshold = 0.9
# 寻找匹配结果中大于等于阈值的位置
loc = np.where(res >= threshold)
# 遍历所有匹配的位置,并在待检测物体图像中绘制矩形框
for i in zip(*loc[::-1]):
cv2.rectangle(img, i, (i[0] + w, i[1]+ h), (0,0,255), 1)
# 显示模板图像和带有检测结果的待检测物体图像
cv2.imshow('template', template) # 显示模板图像
cv2.imshow('img', img) # 显示带有检测结果的待检测物体图像
# 等待按键,并关闭所有图像窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
![](https://img.haomeiwen.com/i21107801/c1330a26f41dcd3c.png)
from PIL import Image
# from skimage import io
# img = io.imread('images-D9/lena.jpg')
img = Image.open('images-D9/lena.jpg')
img2 = img.rotate(45) # 逆时针旋转45
img2.save("lena_rot45.jpg")
img2.show()
"""
图像匹配——SIFT点特征匹配实现步骤:
(1)读取图像;
(2)定义sift算子;
(3)通过sift算子对需要匹配的图像进行特征点获取;
a.可获取各匹配图像经过sift算子的特征点数目
(4)可视化特征点(在原图中标记为圆圈);
a.为方便观察,可将匹配图像横向排列
(5)图像匹配(特征点匹配);
a.通过调整ratio获取需要进行图像匹配的特征点数量(ratio值越大,匹配的线条越密集,但错误匹配点也会增多)
b.通过索引ratio选择固定的特征点进行图像匹配
(6)将待匹配图像通过旋转、变换等方式将其与目标图像对齐
"""
import cv2 # opencv版本需为3.4.2.16
import numpy as np # 矩阵运算库
import time # 时间库
original_lena = cv2.imread('lena.jpg') # 读取lena原图
lena_rot45 = cv2.imread('lena_rot45.jpg') # 读取lena旋转45图
sift = cv2.xfeatures2d.SIFT_create(100)
# 获取各个图像的特征点及sift特征向量
# 返回值kp包含sift特征的方向、位置、大小等信息;des的shape为(sift_num, 128), sift_num表示图像检测到的sift特征数量
(kp1, des1) = sift.detectAndCompute(original_lena, None)
(kp2, des2) = sift.detectAndCompute(lena_rot45, None)
# 特征点数目显示
print("=========================================")
print("=========================================")
print('lena 原图 特征点数目:', des1.shape[0])
print('lena 旋转图 特征点数目:', des2.shape[0])
print("=========================================")
print("=========================================")
# 举例说明kp中的参数信息
for i in range(2):
print("关键点", i)
print("数据类型:", type(kp1[i]))
print("关键点坐标:", kp1[i].pt)
print("邻域直径:", kp1[i].size)
print("方向:", kp1[i].angle)
print("所在的图像金字塔的组:", kp1[i].octave)
print("=========================================")
print("=========================================")
"""
首先对原图和旋转图进行特征匹配,即图original_lena和图lena_rot45
"""
# 绘制特征点,并显示为红色圆圈
sift_original_lena = cv2.drawKeypoints(original_lena, kp1, original_lena, color=(0, 255, 0))
sift_lena_rot45 = cv2.drawKeypoints(lena_rot45, kp2, lena_rot45, color=(0, 255, 0))
sift_cat1 = np.hstack((sift_original_lena, sift_lena_rot45)) # 对提取特征点后的图像进行横向拼接
cv2.imwrite("sift_cat1.png", sift_cat1)
print('原图与旋转图 特征点绘制图像已保存')
cv2.imshow("sift_point1", sift_cat1)
cv2.waitKey()
# 特征点匹配
# K近邻算法求取在空间中距离最近的K个数据点,并将这些数据点归为一类
start = time.time() # 计算匹配点匹配时间
bf = cv2.BFMatcher()
matches1 = bf.knnMatch(des1, des2, k=2)
print('用于 原图和旋转图 图像匹配的所有特征点数目:', len(matches1))
# 调整ratio
# ratio=0.4:对于准确度要求高的匹配;
# ratio=0.6:对于匹配点数目要求比较多的匹配;
# ratio=0.5:一般情况下。
ratio1 = 0.5
good1 = []
for m1, n1 in matches1:
# 如果最接近和次接近的比值大于一个既定的值,那么我们保留这个最接近的值,认为它和其匹配的点为good_match
if m1.distance < ratio1 * n1.distance:
good1.append([m1])
end = time.time()
print("匹配点匹配运行时间:%.4f秒" % (end - start))
# 通过对good值进行索引,可以指定固定数目的特征点进行匹配,如good[:20]表示对前20个特征点进行匹配
match_result1 = cv2.drawMatchesKnn(original_lena, kp1, lena_rot45, kp2, good1[:20], None, flags=2)
cv2.imwrite("match_result1.png", match_result1)
print('原图与旋转图 特征点匹配图像已保存')
print("=========================================")
print("=========================================")
print("原图与旋转图匹配对的数目:", len(good1))
for i in range(2):
print("匹配", i)
print("数据类型:", type(good1[i][0]))
print("描述符之间的距离:", good1[i][0].distance)
print("查询图像中描述符的索引:", good1[i][0].queryIdx)
print("目标图像中描述符的索引:", good1[i][0].trainIdx)
print("=========================================")
print("=========================================")
cv2.imshow("original_lena and lena_rot45 feature matching result", match_result1)
cv2.waitKey()
# 将待匹配图像通过旋转、变换等方式将其与目标图像对齐,这里使用单应性矩阵。
# 单应性矩阵有八个参数,如果要解这八个参数的话,需要八个方程,由于每一个对应的像素点可以产生2个方程(x一个,y一个),那么总共只需要四个像素点就能解出这个单应性矩阵。
if len(good1) > 4:
ptsA = np.float32([kp1[m[0].queryIdx].pt for m in good1]).reshape(-1, 1, 2)
ptsB = np.float32([kp2[m[0].trainIdx].pt for m in good1]).reshape(-1, 1, 2)
ransacReprojThreshold = 4
# RANSAC算法选择其中最优的四个点
H, status = cv2.findHomography(ptsA, ptsB, cv2.RANSAC, ransacReprojThreshold)
imgout = cv2.warpPerspective(lena_rot45, H, (original_lena.shape[1], original_lena.shape[0]),
flags=cv2.INTER_LINEAR + cv2.WARP_INVERSE_MAP)
cv2.imwrite("imgout.png", imgout)
cv2.imshow("lena_rot45's result after transformation", imgout)
cv2.waitKey()
import cv2
import numpy as np
def sift_kp(image):
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d.SIFT_create(100)
#SIFT算子实例化
kp, des = sift.detectAndCompute(image, None)
# sift.detectAndComputer(gray, None)
# 计算出图像的关键点和sift特征向量
kp_image = cv2.drawKeypoints(gray_image, kp, None)
#ret = cv2.drawKeypoints(gray, kp, img) 在图中画出关键点
#参数说明:gray表示输入图片, kp表示关键点,img表示输出的图片
return kp_image, kp, des
def get_good_match(des1, des2):
bf = cv2.BFMatcher()
#对两个匹配选择最佳的匹配
matches = bf.knnMatch(des1, des2, k=2)
# des1为模板图,des2为匹配图
matches = sorted(matches, key=lambda x: x[0].distance / x[1].distance)
good = []
for m, n in matches:
if m.distance < 0.75 * n.distance:
good.append(m)
return good
img1 = cv2.imread('lena.jpg')
img2 = cv2.imread('lena_rot45.jpg')
kpimg1, kp1, des1 = sift_kp(img1)
kpimg2, kp2, des2 = sift_kp(img2)
print('descriptor1:', des1.shape, 'descriptor2', des2.shape)
#输出特征点(描述子)的维度
cv2.imshow('img1',np.hstack((img1,kpimg1)))
cv2.waitKey()
cv2.imshow('img2',np.hstack((img2,kpimg2)))
cv2.waitKey()
goodMatch = get_good_match(des1, des2)
all_goodmatch_img= cv2.drawMatches(img1, kp1, img2, kp2, goodMatch, None, flags=2)
#drawMatches(图1,图1特征点,图2,图2特征点,图1的特征点匹配图2的特征点(所有),颜色都是默认,flags表示有几个图像)
# goodmatch_img自己设置前多少个goodMatch[:50]
goodmatch_img = cv2.drawMatches(img1, kp1, img2, kp2, goodMatch[:10], None, flags=2)
cv2.imshow('all_goodmatch_img', all_goodmatch_img)
cv2.waitKey()
cv2.imshow('goodmatch_img', goodmatch_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2
import numpy as np
def cv_show(name, image):
cv2.imshow(name, image)
cv2.waitKey(0)
cv2.destroyAllWindows()
def detectAndCompute(image):
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
sift = cv2.xfeatures2d.SIFT_create(500)
(kps, features) = sift.detectAndCompute(image, None)
kps = np.float32([kp.pt for kp in kps]) # 得到的点需要进一步转换才能使用
return (kps, features)
def matchKeyPoints(kpsA, kpsB, featuresA, featuresB, ratio = 0.5, reprojThresh = 4.0):
# ratio是最近邻匹配的推荐阈值
# reprojThresh是随机取样一致性的推荐阈值
matcher = cv2.BFMatcher()
rawMatches = matcher.knnMatch(featuresA, featuresB, 2)
matches = []
for m in rawMatches:
if len(m) == 2 and m[0].distance < ratio * m[1].distance:
matches.append((m[0].queryIdx, m[0].trainIdx))
kpsA = np.float32([kpsA[m[0]] for m in matches]) # 使用np.float32转化列表
kpsB = np.float32([kpsB[m[1]] for m in matches])
(M, status) = cv2.findHomography(kpsA, kpsB, cv2.RANSAC, reprojThresh)
return (M, matches, status) # 并不是所有的点都有匹配解,它们的状态存在status中
def stich(imgA, imgB, M):
result = cv2.warpPerspective(imgA, M, (imgA.shape[1] + imgB.shape[1], imgA.shape[0]))
result[0:imageA.shape[0], 0:imageB.shape[1]] = imageB
cv_show('result', result)
def drawMatches(imgA, imgB, kpsA, kpsB, matches, status):
(hA, wA) = imgA.shape[0:2]
(hB, wB) = imgB.shape[0:2]
# 注意这里的3通道和uint8类型
drawImg = np.zeros((max(hA, hB), wA + wB, 3), 'uint8')
drawImg[0:hB, 0:wB] = imageB
drawImg[0:hA, wB:] = imageA
for ((queryIdx, trainIdx),s) in zip(matches, status):
if s == 1:
# 注意将float32 --> int
pt1 = (int(kpsB[trainIdx][0]), int(kpsB[trainIdx][1]))
pt2 = (int(kpsA[trainIdx][0]) + wB, int(kpsA[trainIdx][1]))
cv2.line(drawImg, pt1, pt2, (0, 0, 255))
cv_show("drawImg", drawImg)
# 读取图像
imageA = cv2.imread('sztu2.jpg')
imageA = cv2.resize(imageA,(540,398))
cv_show("imageA", imageA)
imageB = cv2.imread('sztu1.jpg')
imageB = cv2.resize(imageB,(540,398))
cv_show("imageB", imageB)
# 计算SIFT特征点和特征向量
(kpsA, featuresA) = detectAndCompute(imageA)
(kpsB, featuresB) = detectAndCompute(imageB)
# 基于最近邻和随机取样一致性得到一个单应性矩阵
(M, matches, status) = matchKeyPoints(kpsA, kpsB, featuresA, featuresB)
# 绘制匹配结果
drawMatches(imageA, imageB, kpsA, kpsB, matches, status)
# 拼接
stich(imageA, imageB, M)
import cv2
target = cv2.imread('image/lena.jpg')
img = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
template = cv2.imread('image/lena_face.jpg')
h, w= template.shape[:2]
# 相关系数匹配方法: cv2.TM_CCOEFF
result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc=cv2.minMaxLoc(result)
left_top=max_loc #左上角
right_bottom=(left_top[0]+w, left_top[1]+h)#右下角
cv2.rectangle(target, left_top, right_bottom,(0,0,255),2)#画出矩形位置
cv2.imshow('temp', template)
cv2.imshow('result', target)
cv2.waitKey(0)