计算机视觉方法
一、采用skimage的filters模块,实现高斯平滑滤波
1.1直接对原图像进行高斯平滑滤波
import matplotlib.pyplot as plt
from skimage import io, filters, exposure
import warnings
warnings.filterwarnings("ignore")
image1 = io.imread('D:\jupyterwork\labimage\children.jpg')
image2 = io.imread('D:\jupyterwork\labimage\kid.jpg')
image3 = io.imread('D:\jupyterwork\labimage\kitchen.jpg')
image4 = io.imread('D:\jupyterwork\labimage\sakura.jpg')
image = [image1, image2, image3, image4]
# 不同的sigma值,可以根据需要进行调整
sigma_values = [1, 5, 10, 15, 20]
plt.figure(figsize=(20, 8))
for i, img in enumerate(image):
for j, sigma in enumerate(sigma_values):
k = i * len(sigma_values) + j + 1
smoothed_image = filters.gaussian(img, sigma=sigma)
smoothed_image = exposure.rescale_intensity(smoothed_image, out_range=(0, 255))
plt.subplot(len(image), len(sigma_values), k)
plt.imshow(smoothed_image.astype(int))
plt.axis('off')
plt.show()
1.2在图像中添加高斯噪声
import numpy as np
from skimage import io
import matplotlib.pyplot as plt
from skimage import io, filters, exposure
plt.rcParams['font.sans-serif'] = 'SimHei'
image = io.imread('yang.jpg')
# 定义高斯噪声的参数
mean = 0 # 高斯噪声的均值
stddev = 0.5 # 高斯噪声的标准差
gaussian_noise = np.random.normal(mean, stddev, image.shape).astype(np.uint8)
noisy_image = np.clip(image + gaussian_noise, 0, 255).astype(np.uint8)
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.imshow(image)
plt.title('Original Image')
plt.axis('off')
plt.subplot(1, 2, 2)
plt.imshow(noisy_image)
plt.title('Image with Gaussian Noise')
plt.axis('off')
plt.show()
1.3对噪声图片进行高斯滤波
sigma_values = [1, 2, 3, 4]
plt.figure(figsize=(20, 8))
plt.subplot(1,5,1)
plt.imshow(noisy_image)
plt.title("高斯噪声图")
plt.axis('off')
for j, sigma in enumerate(sigma_values):
smoothed_image = filters.gaussian(noisy_image, sigma=sigma, channel_axis=-1)
plt.subplot(1, 5, j+2)
plt.imshow(smoothed_image)
plt.title("平滑-sigma=%d"%sigma)
plt.axis('off')
plt.show()
1.4在灰度图像中添加高斯噪声
import skimage
from skimage.color import rgb2gray
import numpy as np
import matplotlib.pyplot as plt
# 读取彩色图像
color_image = skimage.data.chelsea()
# 将彩色图像转为灰度图像
img1_gray = rgb2gray(color_image)
# 显示原始灰度图像
plt.figure(figsize=(12, 6))
plt.subplot(121)
plt.imshow(img1_gray, cmap='gray')
plt.axis('off')
# 定义高斯噪声的参数
mean = 0 # 高斯噪声的均值
stddev = 0.1 # 高斯噪声的标准差
# 生成与图像相同大小的随机高斯噪声
gaussian_noise = np.random.normal(mean, stddev, img1_gray.shape).astype(np.float64)
# 将噪声添加到图像上
noisy_image1 = np.clip(img1_gray + gaussian_noise, 0, 1) # 将结果限制在合法范围内(0到1之间)
plt.subplot(122)
plt.imshow(noisy_image1, cmap='gray')
plt.axis('off')
plt.show()
1.5在灰度图像中使用高斯平滑滤波
#噪声图片为:noisy_image1
sigma_values = [1, 2, 3, 4]
plt.figure(figsize=(20, 8))
plt.subplot(1,5,1)
plt.imshow(noisy_image1,cmap='gray')
plt.title("高斯噪声图")
plt.axis('off')
for j, sigma in enumerate(sigma_values):
smoothed_image = filters.gaussian(noisy_image1, sigma=sigma, channel_axis=-1)
plt.subplot(1, 5, j+2)
plt.imshow(smoothed_image, cmap='gray')
plt.title("平滑-sigma=%d"%sigma)
plt.axis('off')
plt.show()
二、采用skimage的filters模块以及feature模块,实现边缘检测中不同算子
2.1简单测试(边缘轮廓比较明显)
import matplotlib.pyplot as plt
from skimage import io, color, filters, feature
# 读取图像并转换为灰度图像
image = io.imread('yang.jpg')
gray_image = color.rgb2gray(image)
# 边缘检测算子
roberts = filters.roberts(gray_image)
prewitt = filters.prewitt(gray_image)
canny_sigma1 = feature.canny(gray_image, sigma=1)
canny_sigma2 = feature.canny(gray_image, sigma=2)
canny_sigma3 = feature.canny(gray_image, sigma=3)
outimg = [gray_image,roberts,prewitt,canny_sigma1,canny_sigma2,canny_sigma3]
outimgname = ['Original Image','Roberts Edge Detection','Prewitt Edge Detection','Canny (Sigma=1)','Canny (Sigma=2)','Canny (Sigma=3)']
plt.figure(figsize=(12, 6))
for i in range(1,7):
plt.subplot(2,3,i)
plt.imshow(outimg[i-1],cmap='gray')
plt.title(outimgname[i-1])
plt.axis('off')
plt.show()
2.2简单测试(边缘丰富)
import matplotlib.pyplot as plt
from skimage import io, color, filters, feature
import skimage
# 读取图像并转换为灰度图像
image = skimage.data.chelsea()
gray_image = color.rgb2gray(image)
# 边缘检测算子
roberts = filters.roberts(gray_image)
prewitt = filters.prewitt(gray_image)
canny_sigma1 = feature.canny(gray_image, sigma=1)
canny_sigma2 = feature.canny(gray_image, sigma=2)
canny_sigma3 = feature.canny(gray_image, sigma=3)
# 边缘检测算子
roberts = filters.roberts(gray_image)
prewitt = filters.prewitt(gray_image)
canny_sigma1 = feature.canny(gray_image, sigma=1)
canny_sigma2 = feature.canny(gray_image, sigma=2)
canny_sigma3 = feature.canny(gray_image, sigma=3)
outimg = [gray_image,roberts,prewitt,canny_sigma1,canny_sigma2,canny_sigma3]
outimgname = ['Original Image','Roberts Edge Detection','Prewitt Edge Detection','Canny (Sigma=1)','Canny (Sigma=2)','Canny (Sigma=3)']
plt.figure(figsize=(12, 5))
for i in range(1,7):
plt.subplot(2,3,i)
plt.imshow(outimg[i-1],cmap='gray')
plt.title(outimgname[i-1])
plt.axis('off')
plt.show()
三、熟悉Otsu算法实现阈值图像分割的基本原理,编程实现阈值图像分割,并改变其中参数值bins,分析阈值图像分割设置bins的意义
3.1熟悉Otsu算法 (基本原理)
-
遍历图像中的所有像素,并将像素的灰度值按照从0到255的范围进行分组。
-
对于每个可能的阈值(0到255),将图像分成两部分:低于阈值的部分和高于阈值的部分。
-
对于每个分组,计算其两部分的加权方差,其中权重是每个部分中像素数量的比例。
-
找到使加权方差最小的阈值,这个阈值将图像分成了两个具有最小内部方差的区域。
-
该阈值即为Otsu阈值,可用于二值化图像。
编程实现
3.1.1对猫咪图像进行Otsu算法找阈值
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from skimage.color import rgb2gray
from skimage.filters import threshold_otsu
image = data.chelsea()
gray_image = rgb2gray(image)
#print(gray_image)
bins_values = [2,4,8, 16, 32,64]
threshold_values = []
plt.figure(figsize=(20, 8))
for i, bins in enumerate(bins_values):
threshold = threshold_otsu(gray_image, nbins=bins)
threshold_values.append(threshold)
binary_image = gray_image > threshold
plt.subplot(2,3, i+1)
plt.imshow(binary_image, cmap='gray')
plt.title(f'Bins={bins}, Threshold={threshold}');plt.axis('off')
plt.show()
print(f"Threshold values for different bins: {threshold_values}")
[[0.48523098 0.48523098 0.47738784 ... 0.11692392 0.11692392 0.11692392]
[0.49699569 0.49307412 0.48523098 ... 0.12336824 0.1225349 0.1272898 ]
[0.50849255 0.50457098 0.49475569 ... 0.12336039 0.12728196 0.13120353]
...
[0.24786745 0.29884784 0.40501294 ... 0.58914824 0.58914824 0.58914824]
[0.38173647 0.42487373 0.39628392 ... 0.57403529 0.57403529 0.57795686]
[0.42487373 0.36883294 0.36042431 ... 0.55442745 0.55442745 0.55834902]]
Threshold values for different bins: [0.20024333333333333, 0.2928046078431372, 0.4316465196078431, 0.40850620098039214, 0.4432166789215686, 0.4374315992647059]
3.1.2对懒哥图像进行Otsu算法找阈值
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from skimage.color import rgb2gray
from skimage.filters import threshold_otsu
# 读取图像并转为灰度图
image = io.imread('yang.jpg')
gray_image = rgb2gray(image)
# 改变bins参数来观察效果
bins_values = [2,4,8, 16, 32,64]
threshold_values = []
plt.figure(figsize=(20, 8))
for i, bins in enumerate(bins_values):
# 使用Otsu算法找到阈值
threshold = threshold_otsu(gray_image, nbins=bins)
threshold_values.append(threshold)
# 二值化图像
binary_image = gray_image > threshold
# 绘制结果
plt.subplot(2,3, i+1)
plt.imshow(binary_image, cmap='gray')
plt.title(f'Bins={bins}, Threshold={threshold}')
plt.axis('off')
plt.show()
# 分析不同bins的意义
print(f"Threshold values for different bins: {threshold_values}")
Threshold values for different bins: [0.25, 0.375, 0.5625, 0.59375, 0.640625, 0.6484375]
3.1.3分析阈值图像分割设置Bin的意义
较低的bins值::
-
优点:当bins值较低时,Otsu算法对图像的灰度级别分布进行更粗略的估计,这可以降低计算的复杂性。
-
缺点:较低的bins值可能导致Otsu算法的阈值选择对图像中的噪声更为敏感,因为它无法捕获细微的灰度级别变化。
较高的bins值:
-
优点:当bins值较高时,Otsu算法能够更精细地捕获图像的灰度级别分布,从而更准确地选择阈值。
-
缺点:较高的bins值可能会增加计算的复杂性,尤其是对于具有大量灰度级别的图像。
-
选择适当的bins值通常取决于图像的特性和应用需求。如果图像具有较少的灰度级别或相对均匀的分布,可以使用较低的bins值以提高算法的效率。对于具有丰富灰度级别和复杂分布的图像,较高的bins值可能更有帮助。
四、采用skimage的morphology模块掌握膨胀与腐蚀的对图像处理的基本原理与作用
形态学滤波是图像处理中的一种基本技术,它使用膨胀(Dilation)和腐蚀(Erosion)等操作来改变图像的形状和结构。下面将解释膨胀、腐蚀、开运算和闭运算的基本原理以及它们的作用,并分析它们的显示效果。
膨胀(Dilation):
-
膨胀操作通过滑动一个结构元素(也称为内核)来增强图像中的明亮区域(前景物体)。
-
在膨胀中,内核的中心像素与图像中的每个像素相对应,如果内核覆盖的区域内有至少一个前景像素,则中心像素将变为前景。
-
膨胀可以用于扩大物体的大小,填充空洞,连接分离的物体等。
腐蚀(Erosion):
-
腐蚀操作通过滑动一个结构元素来缩小图像中的明亮区域。
-
在腐蚀中,内核的中心像素与图像中的每个像素相对应,只有当内核完全覆盖区域内的所有前景像素时,中心像素才保持前景,否则它变为背景。
-
腐蚀可用于去除噪声,分离接触的物体等。
开运算(Opening):
-
开运算是腐蚀操作后紧随着一个膨胀操作的组合,通常用来清除小的明亮区域(噪声)并打开物体之间的连接。
-
开运算可以平滑物体的边缘,去除小的干扰。
闭运算(Closing):
-
闭运算是膨胀操作后紧随着一个腐蚀操作的组合,通常用来关闭物体内的小空洞和连接接触的物体。
-
闭运算可以填充物体内的空洞,连接物体。
4.1简单测试一组图片
import matplotlib.pyplot as plt
from skimage import io, color, morphology
image = io.imread('data/6.jpg')
gray_image = color.rgb2gray(image) # 读取图像并转为灰度图
selem = morphology.disk(20) # 这里使用圆形结构元素 定义结构元素(内核)
dilated_image = morphology.dilation(gray_image, selem)# 膨胀操作
eroded_image = morphology.erosion(gray_image, selem)# 腐蚀操作
opened_image = morphology.opening(gray_image, selem)# 开运算
closed_image = morphology.closing(gray_image, selem)# 闭运算
plt.figure(figsize=(20, 8))
img = [image,gray_image,dilated_image,eroded_image,opened_image,closed_image]
imgname = ['原图','灰度图','膨胀操作','腐蚀操作','开运算','闭运算']
for i in range(1,7):
plt.subplot(2,3,i)
plt.imshow(img[i-1],cmap='gray')
plt.title(imgname[i-1])
plt.axis('off')
plt.show()
Output Image Size: 1152 x 648 pixels
Output Image Size: 1152 x 648 pixels
Output Image Size: 1152 x 648 pixels
Output Image Size: 1152 x 648 pixels
Output Image Size: 1152 x 648 pixels
Output Image Size: 1152 x 648 pixels
4.2测试不同半径的内核的效果
import matplotlib.pyplot as plt
from skimage import io, color, morphology
# 读取图像并转为灰度图
# image = skimage.data.cat()
# gray_image = color.rgb2gray(image)
image = io.imread('data/6.jpg')
img = []
imgname = ['膨胀操作','腐蚀操作','开运算','闭运算']
for R in [1,5,10,15,20]:
selem = morphology.disk(R)
dilated_image = morphology.dilation(gray_image, selem)
eroded_image = morphology.erosion(gray_image, selem)
opened_image = morphology.opening(gray_image, selem)
closed_image = morphology.closing(gray_image, selem)
tep = [dilated_image,eroded_image,opened_image,closed_image]
img.append(tep)
plt.figure(figsize=(30,20))
k = 1
r = [1,5,10,15,20]
for i in range(4):
for j in range(5):
plt.subplot(4,5,k)
plt.imshow(img[j][i],cmap = 'gray')
plt.title("%s R=%d"%(imgname[i],r[j]))
plt.axis('off')
k += 1
plt.show()
五、采用skimage的transform模块,编程实现霍夫线检测与霍夫圆检测
5.1霍夫线检测
import skimage.transform as st
import numpy as np
import matplotlib.pyplot as plt
image = np.zeros((100, 100))
idx = np.arange(25, 75)
image[idx[::-1], idx] = 255
image[idx, idx] = 255
# hough线变换
h, theta, d = st.hough_line(image)
fig, (ax0, ax1,ax2) = plt.subplots(1, 3, figsize=(8, 6))
plt.tight_layout()
#显示原始图片
ax0.imshow(image, plt.cm.gray)
ax0.set_title('Input image')
ax0.set_axis_off()
#显示hough变换所得数据
ax1.imshow(np.log(1 + h))
ax1.set_title('Hough transform')
ax1.set_xlabel('Angles (degrees)')
ax1.set_ylabel('Distance (pixels)')
ax1.axis('image')
#显示检测出的线条
ax2.imshow(image, plt.cm.gray)
row1, col1 = image.shape
for _, angle, dist in zip(*st.hough_line_peaks(h, theta, d)):
y0 = (dist - 0 * np.cos(angle)) / np.sin(angle)
y1 = (dist - col1 * np.cos(angle)) / np.sin(angle)
ax2.plot((0, col1), (y0, y1), '-r')
ax2.axis((0, col1, row1, 0))
ax2.set_title('Detected lines')
ax2.set_axis_off()
plt.show()
有两个交点说明有2条直线、下面使用canny算子提取边缘
import skimage.transform as st
import matplotlib.pyplot as plt
from skimage import data,feature
#使用Probabilistic Hough Transform.
img1 = io.imread("yang.jpg")
img1 = color.rgb2gray(img1)
img2 = skimage.data.camera()
img3 = skimage.data.cell()
img4 = skimage.data.binary_blobs()
img5 = skimage.data.cat()
img5 = color.rgb2gray(img5)
images = [img1, img2, img3, img4, img5]
plt.figure(figsize=(10,15))
cnt = 1
for image in images:
edges = feature.canny(image, sigma=1)
lines = st.probabilistic_hough_line(edges, threshold=10, line_length=5, line_gap=3
print("image通过hough检测的线条数:",len(lines))
plt.subplot(5,3,cnt)
plt.imshow(image, plt.cm.gray)
plt.title('Input image')
plt.axis("off")
cnt += 1
#显示canny边缘
plt.subplot(5,3,cnt)
plt.imshow(edges, plt.cm.gray)
plt.title('Canny edges')
plt.axis("off")
cnt += 1
#用plot绘制出所有的直线
plt.subplot(5,3,cnt)
plt.imshow(edges * 0)
for line in lines:
p0, p1 = line
plt.plot((p0[0], p1[0]), (p0[1], p1[1]))
row2, col2 = image.shape
plt.title('Probabilistic Hough')
plt.axis('off')
cnt += 1
plt.show()
image通过hough检测的线条数: 864
image通过hough检测的线条数: 2749
image通过hough检测的线条数: 45
image通过hough检测的线条数: 578
image通过hough检测的线条数: 1946
5.2霍夫圆检测
import numpy as np
import matplotlib.pyplot as plt
from skimage import draw,transform,feature
img = np.zeros((250, 250,3), dtype=np.uint8)
rr, cc = draw.circle_perimeter(60, 60, 50) #以半径50画一个圆
rr1, cc1 = draw.circle_perimeter(150, 150, 60) #以半径60画一个圆
img[cc, rr,:] =255
img[cc1, rr1,:] =255
fig, (ax0,ax1) = plt.subplots(1,2, figsize=(8, 5))
ax0.imshow(img) #显示原图
ax0.set_title('origin image')
hough_radii = np.arange(50, 80, 5) #半径范围
hough_res =transform.hough_circle(img[:,:,0], hough_radii) #圆变换
centers = [] #保存所有圆心点坐标
accums = [] #累积值
radii = [] #半径
for radius, h in zip(hough_radii, hough_res):
#每一个半径值,取出其中两个圆
num_peaks = 2
peaks =feature.peak_local_max(h, num_peaks=num_peaks) #取出峰值
centers.extend(peaks)
accums.extend(h[peaks[:, 0], peaks[:, 1]])
radii.extend([radius] * num_peaks)
image =np.copy(img)
for idx in np.argsort(accums)[::-1][:2]:
center_x, center_y = centers[idx]
radius = radii[idx]
cx, cy =draw.circle_perimeter(center_y, center_x, radius)
image[cy, cx] =(255,0,0)
ax1.imshow(image)
ax1.set_title('detected image')
Text(0.5, 1.0, 'detected image')
import numpy as np
import matplotlib.pyplot as plt
from skimage import data, color,draw,transform,feature,util
img1 = io.imread("yang.jpg")
img1 = color.rgb2gray(img1)
img2 = skimage.data.coins()
img3 = skimage.data.cell()
img4 = skimage.data.binary_blobs()
img5 = skimage.data.cat()
img5 = color.rgb2gray(img5)
images = [img1, img2, img3, img4, img5]
plt.figure(figsize=(15,20))
cnt = 1
for image in images:
image = util.img_as_ubyte(image)
edges =feature.canny(image, sigma=3) #检测canny边缘
plt.subplot(5,2,cnt)
plt.imshow(edges, plt.cm.gray) #显示canny边缘
plt.title('original iamge')
cnt +=1
hough_radii = np.arange(5, 100, 2) #半径范围
hough_res =transform.hough_circle(edges, hough_radii) #圆变换
centers = [] #保存中心点坐标
accums = [] #累积值
radii = [] #半径
for radius, h in zip(hough_radii, hough_res):
#每一个半径值,取出其中两个圆
num_peaks = 2
peaks =feature.peak_local_max(h, num_peaks=num_peaks) #取出峰值
centers.extend(peaks)
accums.extend(h[peaks[:, 0], peaks[:, 1]])
radii.extend([radius] * num_peaks)
image = color.gray2rgb(image)
for idx in np.argsort(accums)[::-1][:5]:
center_x, center_y = centers[idx]
radius = radii[idx]
cx, cy =draw.circle_perimeter(center_y, center_x, radius)
image[cy, cx] = (255,0,0)
plt.subplot(5,2,cnt)
plt.imshow(image)
plt.title('detected image')
cnt += 1
plt.show()
六、采用skimage的feature模块,自己制作模版,编程实现模版匹配。
6.1采用skimage的data.coin()图片来简单测试
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
from skimage.feature import match_template
from matplotlib.patches import Rectangle
image = data.coins() # 用自己的图像替换这里的示例图像
template = data.coins()[170:220, 75:130] # 使用适合你的模板的区域
# 执行模板匹配
result = match_template(image, template)
# 找到匹配结果的坐标
ij = np.unravel_index(np.argmax(result), result.shape)
x, y = ij[::-1]
# 绘制原始图像和匹配结果
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(15, 5))
ax1.imshow(image, cmap=plt.cm.gray)
ax1.set_title('Original Image')
ax1.axis('off')
ax2.imshow(template, cmap=plt.cm.gray)
ax2.set_title('Template')
ax2.axis('off')
ax3.imshow(image, cmap=plt.cm.gray)
ax3.set_title('Matching Result')
ax3.axis('off')
# 标记整个匹配区域
match_area = Rectangle((x, y), template.shape[1], template.shape[0], edgecolor='r', facecolor='none')
ax3.add_patch(match_area)
plt.show()
6.2对coin图片进行旋转30度、60度、90度、120度、150度、180度进行模板匹配
import numpy as np
import matplotlib.pyplot as plt
from skimage import data, transform
from skimage.feature import match_template
from matplotlib.patches import Rectangle
# 读取输入图像和模板图像
image = data.coins() # 用自己的图像替换这里的示例图像
template = data.coins()[170:220, 75:130] # 使用适合你的模板的区域
# 旋转整个图像并执行模板匹配
angles = [30, 60, 90, 120, 150, 180] # 指定旋转角度
fig, axes = plt.subplots(2, 3, figsize=(15, 6))
for angle, ax in zip(angles, axes.ravel()):
# 旋转整个图像
rotated_image = transform.rotate(image, angle)
# 执行模板匹配
result = match_template(rotated_image, template)
# 找到匹配结果的坐标
ij = np.unravel_index(np.argmax(result), result.shape)
x, y = ij[::-1]
# 绘制原始图像和匹配结果
ax.imshow(rotated_image, cmap=plt.cm.gray)
ax.set_title(f'旋转角度: {angle} degrees')
ax.axis('off')
# 标记整个匹配区域
match_area = Rectangle((x, y), template.shape[1], template.shape[0], edgecolor='r', facecolor='none')
ax.add_patch(match_area)
plt.show()
6.3对coin图片进行缩放并进行模板匹配(全错)
import numpy as np
import matplotlib.pyplot as plt
from skimage import data, transform
from skimage.feature import match_template
from matplotlib.patches import Rectangle
# 读取输入图像和模板图像
image = data.coins()
template = data.coins()[170:220, 75:130]
# 旋转整个图像并执行模板匹配
sizes = [(200, 200), (300, 300), (450, 450), (640, 640), (640, 320), (450, 800)] # 指定不同的尺寸
fig, axes = plt.subplots(2, 3, figsize=(15, 6))
for size, ax in zip(sizes, axes.ravel()):
# 调整图像大小
scaled_image = transform.resize(image, size)
# 执行模板匹配
result = match_template(scaled_image, template)
# 找到匹配结果的坐标
ij = np.unravel_index(np.argmax(result), result.shape)
x, y = ij[::-1]
# 绘制原始图像和匹配结果
ax.imshow(scaled_image, cmap=plt.cm.gray)
ax.set_title(f'缩放大小为: {size} pixels')
ax.axis('off')
# 标记整个匹配区域
match_area = Rectangle((x, y), template.shape[1], template.shape[0], edgecolor='r', facecolor='none')
ax.add_patch(match_area)
plt.show()
6.4对coin图片进调整亮度实现模板匹配,亮度值:0.8,1,1.5,2,2.5,3(全对)
import numpy as np
import matplotlib.pyplot as plt
from skimage import data, exposure
from skimage.feature import match_template
from matplotlib.patches import Rectangle
# 读取输入图像和模板图像
image = data.coins()
template = data.coins()[170:220, 75:130]
# 不同亮度值
brightness_values = [0.8, 1, 1.5, 2, 2.5, 3]
fig, axes = plt.subplots(2, 3, figsize=(15, 6))
for brightness, ax in zip(brightness_values, axes.ravel()):
# 调整图像亮度
brightened_image = exposure.adjust_gamma(image, gamma=brightness)
# 执行模板匹配
result = match_template(brightened_image, template)
# 找到匹配结果的坐标
ij = np.unravel_index(np.argmax(result), result.shape)
x, y = ij[::-1]
# 绘制原始图像和匹配结果
ax.imshow(brightened_image, cmap=plt.cm.gray)
ax.set_title(f'亮度调整为: {brightness}')
ax.axis('off')
# 标记整个匹配区域
match_area = Rectangle((x, y), template.shape[1], template.shape[0], edgecolor='r', facecolor='none')
ax.add_patch(match_area)
plt.show()
6.5对coin图片添加各种噪声实现模板匹配(全对)
import numpy as np
import matplotlib.pyplot as plt
from skimage import data, util, feature, color
from skimage.feature import match_template
from matplotlib.patches import Rectangle
# 读取输入图像和模板图像
image = data.coins()
template = data.coins()[170:220, 75:130]
# 添加不同类型的噪声并执行模板匹配
noise_types = ['gaussian', 'localvar', 'poisson', 'salt', 'pepper', 's&p']
fig, axes = plt.subplots(2, 3, figsize=(15, 6))
for noise_type, ax in zip(noise_types, axes.ravel()):
noisy_image = image.copy()
if noise_type == 'gaussian':
noisy_image = util.random_noise(noisy_image, mode='gaussian', var=0.05)
elif noise_type == 'localvar':
noisy_image = util.random_noise(noisy_image, mode='localvar', local_vars=np.ones_like(image) * 0.1)
elif noise_type == 'poisson':
noisy_image = util.random_noise(noisy_image, mode='poisson')
elif noise_type == 'salt':
noisy_image = util.random_noise(noisy_image, mode='salt', amount=0.05)
elif noise_type == 'pepper':
noisy_image = util.random_noise(noisy_image, mode='pepper', amount=0.05)
elif noise_type == 's&p':
noisy_image = util.random_noise(noisy_image, mode='s&p', amount=0.05)
# 执行模板匹配
result = match_template(noisy_image, template)
# 找到匹配结果的坐标
ij = np.unravel_index(np.argmax(result), result.shape)
x, y = ij[::-1]
# 绘制原始图像和匹配结果
ax.imshow(noisy_image, cmap=plt.cm.gray)
ax.set_title(f'噪声类型: {noise_type}')
ax.axis('off')
# 标记整个匹配区域
match_area = Rectangle((x, y), template.shape[1], template.shape[0], edgecolor='r', facecolor='none')
ax.add_patch(match_area)
plt.show()
6.6对图片进行仿射变换进行模板匹配(部分正确)
import numpy as np
import matplotlib.pyplot as plt
from skimage import data, transform
from skimage.feature import match_template
from matplotlib.patches import Rectangle
# 读取输入图像和模板图像
image = data.coins()
template = data.coins()[170:220, 75:130]
# 定义六种不同的仿射变换参数
transformations = [
{"rotation_angle": 0, "scale_factor": 1, "shear_factor": 0.1, "translation_x": -20, "translation_y": -30},
{"rotation_angle": -9, "scale_factor": 1, "shear_factor": 0.2, "translation_x": -10, "translation_y": -10},
{"rotation_angle": -45, "scale_factor": 1, "shear_factor": 0.01, "translation_x": -60, "translation_y": -30},
{"rotation_angle": -12, "scale_factor": 1, "shear_factor": 0.4, "translation_x": -70, "translation_y": -20},
{"rotation_angle": -27, "scale_factor": 1, "shear_factor": 0.6, "translation_x": 100, "translation_y": -30},
{"rotation_angle": -30, "scale_factor": 1, "shear_factor": 0.3, "translation_x": -30, "translation_y": 60}
]
fig, axes = plt.subplots(2, 3, figsize=(15, 6))
for transform_params, ax in zip(transformations, axes.ravel()):
# 创建仿射变换矩阵
tform = transform.AffineTransform(
rotation=np.deg2rad(transform_params["rotation_angle"]),
scale=(transform_params["scale_factor"], transform_params["scale_factor"]),
shear=transform_params["shear_factor"],
translation=(transform_params["translation_x"], transform_params["translation_y"])
)
# 对图像进行仿射变换
transformed_image = transform.warp(image, tform.inverse, output_shape=image.shape)
# 执行模板匹配
result = match_template(transformed_image, template)
# 找到匹配结果的坐标
ij = np.unravel_index(np.argmax(result), result.shape)
x, y = ij[::-1]
# 绘制变换后的图像
ax.imshow(transformed_image, cmap=plt.cm.gray)
ax.set_title(f'Rotation: {transform_params["rotation_angle"]}°')
ax.axis('off')
# 标记整个匹配区域
match_area = Rectangle((x, y), template.shape[1], template.shape[0], edgecolor='r', facecolor='none')
ax.add_patch(match_area)
plt.show()
6.7综合大对比
import numpy as np
import matplotlib.pyplot as plt
from skimage import data, transform
from skimage.feature import match_template
from matplotlib.patches import Rectangle
image = io.imread('yang.jpg')
gray_image = color.rgb2gray(image)
template = gray_image[375:432,260:345]
# 定义旋转角度
rotation_angles = [0, 30, 60, 90, 120, 150, 180]
# 1. 旋转并进行模板匹配
fig, axes = plt.subplots(1, 7, figsize=(20, 5))
for i, angle in enumerate(rotation_angles):
rotated_image = transform.rotate(gray_image, angle, resize=False, mode='constant', cval=1)
result = match_template(rotated_image, template)
ij = np.unravel_index(np.argmax(result), result.shape)
x, y = ij[::-1]
axes[i].imshow(rotated_image, cmap=plt.cm.gray)
axes[i].set_title(f'Rotation: {angle}°')
match_area = Rectangle((x, y), template.shape[1], template.shape[0], edgecolor='r', facecolor='none')
axes[i].add_patch(match_area)
axes[i].axis('off')
# 2. 缩放并进行模板匹配
sizes = [(200, 200), (300, 300), (450, 450), (640, 640), (640, 320), (450, 800)]
fig, axes = plt.subplots(1, 6, figsize=(20, 5))
for i, size in enumerate(sizes):
scaled_image = transform.resize(gray_image, size)
result = match_template(scaled_image, template)
ij = np.unravel_index(np.argmax(result), result.shape)
x, y = ij[::-1]
axes[i].imshow(scaled_image, cmap=plt.cm.gray)
axes[i].set_title(f'Size: {size}')
match_area = Rectangle((x, y), template.shape[1], template.shape[0], edgecolor='r', facecolor='none')
axes[i].add_patch(match_area)
axes[i].axis('off')
# 3. 亮度调整并进行模板匹配
brightness_factors = [0.8, 1, 1.5, 2, 2.5, 3]
fig, axes = plt.subplots(1, 6, figsize=(20, 5))
for i, factor in enumerate(brightness_factors):
adjusted_image = exposure.adjust_gamma(gray_image, gamma=factor)
result = match_template(adjusted_image, template)
ij = np.unravel_index(np.argmax(result), result.shape)
x, y = ij[::-1]
axes[i].imshow(adjusted_image, cmap=plt.cm.gray)
axes[i].set_title(f'Brightness: {factor}')
match_area = Rectangle((x, y), template.shape[1], template.shape[0], edgecolor='r', facecolor='none')
axes[i].add_patch(match_area)
axes[i].axis('off')
# 4. 噪声添加并进行模板匹配
noise_types = ['gaussian', 'localvar', 'poisson', 'salt', 'pepper', 's&p']
fig, axes = plt.subplots(1, 6, figsize=(20, 5))
for i, noise_type in enumerate(noise_types):
noisy_image = gray_image.copy()
if noise_type == 'gaussian':
noisy_image = util.random_noise(noisy_image, mode='gaussian', var=0.05)
elif noise_type == 'localvar':
noisy_image = util.random_noise(noisy_image, mode='localvar', local_vars=np.ones_like(gray_image) * 0.1)
elif noise_type == 'poisson':
noisy_image = util.random_noise(noisy_image, mode='poisson')
elif noise_type == 'salt':
noisy_image = util.random_noise(noisy_image, mode='salt', amount=0.05)
elif noise_type == 'pepper':
noisy_image = util.random_noise(noisy_image, mode='pepper', amount=0.05)
elif noise_type == 's&p':
noisy_image = util.random_noise(noisy_image, mode='s&p', amount=0.05)
result = match_template(noisy_image, template)
ij = np.unravel_index(np.argmax(result), result.shape)
x, y = ij[::-1]
axes[i].imshow(noisy_image, cmap=plt.cm.gray)
axes[i].set_title(f'Noise: {noise_type}')
match_area = Rectangle((x, y), template.shape[1], template.shape[0], edgecolor='r', facecolor='none')
axes[i].add_patch(match_area)
axes[i].axis('off')
# 5. 仿射变换并进行模板匹配
transformations = [
{"rotation_angle": 0, "scale_factor": 1, "shear_factor": 0.1, "translation_x": -20, "translation_y": -30},
{"rotation_angle": 9, "scale_factor": 1, "shear_factor": 0.2, "translation_x": -10, "translation_y": -10},
{"rotation_angle": -45, "scale_factor": 1, "shear_factor": 0.01, "translation_x": -60, "translation_y": -30},
{"rotation_angle": -12, "scale_factor": 1, "shear_factor": 0.4, "translation_x": -70, "translation_y": -20},
{"rotation_angle": -27, "scale_factor": 1, "shear_factor": 0.6, "translation_x": 100, "translation_y": -30},
{"rotation_angle": -30, "scale_factor": 1, "shear_factor": 0.3, "translation_x": -30, "translation_y": 60}
]
fig, axes = plt.subplots(1, 6, figsize=(20, 5))
for i, transform_params in enumerate(transformations):
tform = transform.AffineTransform(
rotation=np.deg2rad(transform_params["rotation_angle"]),
scale=(transform_params["scale_factor"], transform_params["scale_factor"]),
shear=transform_params["shear_factor"],
translation=(transform_params["translation_x"], transform_params["translation_y"])
)
transformed_image = transform.warp(gray_image, tform.inverse, output_shape=gray_image.shape)
result = match_template(transformed_image, template)
ij = np.unravel_index(np.argmax(result), result.shape)
x, y = ij[::-1]
axes[i].imshow(transformed_image, cmap=plt.cm.gray)
axes[i].set_title(f'Transformation: {i+1}')
match_area = Rectangle((x, y), template.shape[1], template.shape[0], edgecolor='r', facecolor='none')
axes[i].add_patch(match_area)
axes[i].axis('off')
plt.show()