算法刷题笔记

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()
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()

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()

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()

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()

第 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()
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()          
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() 
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()

第 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()
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()

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()

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()

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()

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()


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()

第 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()
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()

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()

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()

# 导入所需的库
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()

第 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()
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()
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()
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()
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()
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()
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()
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()

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()

第 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()
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()
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()
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()

第 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()

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)
上一篇下一篇

猜你喜欢

热点阅读