Примечания к руководству по машинному обучению — обработка изображений

Python

Профессионал и работа в этом не участвуют, это чисто для понимания, изучайте заметки, нарушение можно удалить

Загружать, конвертировать, сохранять, изменять размер, обрезать изображения

При вызове метода imread программа преобразует данные изображения в хорошо знакомый нам тип данных — массивы NumPy.

import cv2
import numpy as np
from matplotlib import pyplot as plt
# 把图像导入成灰度图
image = cv2.imread("E:/sim_data-master/images/plane.jpg", cv2.IMREAD_GRAYSCALE) 

# 以彩色模式加载图像
#每个元素包含三个值,分别对应蓝色、绿色和红色分量( BGR)
image_bgr = cv2.imread("E:/sim_data-master/images/plane.jpg", cv2.IMREAD_COLOR) 

# 转换为 RGB 格式
#OpenCV 默认使用 BGR 格式,需要先将颜色转换为 RGB 格式
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)

# 保存图像
cv2.imwrite("plane_new.jpg", image)

# 将图片尺寸调整为 50x50 像素
#在机器学习中常见的图像规格有 : 32× 32、64× 64、 96× 96 和 256× 256
image_50x50 = cv2.resize(image, (50, 50))

#裁剪 选择所有的行和前 128 列
image_cropped = image[:,:128]

Сглаживание и резкость изображений

Чтобы сгладить изображение, нужно преобразовать значение каждого пикселя в среднее значение соседних пикселей. При повышении резкости мы используем ядро, которое подсвечивает сам пиксель. Повышение резкости может сделать края изображения более четкими.

#平滑
image_blurry = cv2.blur(image, (5,5))
#这个核的大小决定了平滑的程度,核越大,产生的图像就越平滑。
#手动平滑
kernel = np.ones((5,5)) / 25.0
image_kernel = cv2.filter2D(image, -1, kernel)

#锐化
kernel = np.array([[0, -1, 0],[-1, 5,-1],[0, -1, 0]])
image_sharp = cv2.filter2D(image, -1, kernel)

Улучшить изображение

#灰度图
image_enhanced = cv2.equalizeHist(image) 

# 彩色图像bgr转为YUV:Y 表示亮度,U 和 V 表示颜色
image_yuv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2YUV)
# 对图像应用直方图均衡:会转换图像,使像素强度的分布范围更广
image_yuv[:, :, 0] = cv2.equalizeHist(image_yuv[:, :, 0])
# 转换成 RGB 格式
image_rgb = cv2.cvtColor(image_yuv, cv2.COLOR_YUV2RGB)

цветоделение

# 将 BGR 格式转换成 HSV 格式(H、 S、 V 分别代表色调、饱和度、亮度)。
image_hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV)
# 定义 HSV 格式中蓝色分量的区间,定义要分离的一系列值
lower_blue = np.array([50,100,50])
upper_blue = np.array([130,255,255])
# 创建掩模
mask = cv2.inRange(image_hsv, lower_blue, upper_blue)
# 应用掩模
image_bgr_masked = cv2.bitwise_and(image_bgr, image_bgr, mask=mask)
# 从 BGR 格式转换成 RGB 格式
image_rgb = cv2.cvtColor(image_bgr_masked, cv2.COLOR_BGR2RGB)

Бинаризация изображения (черно-белая обработка)

image_grey = cv2.imread("E:/sim_data-master/images/plane_256x256.jpg", cv2.IMREAD_GRAYSCALE)
# 应用自适应阈值处理
max_output_value = 255 #用于确定输出像素的最大强度
neighborhood_size = 99
subtract_from_mean = 10
image_binarized = cv2.adaptiveThreshold(image_grey,max_output_value,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                        cv2.THRESH_BINARY,neighborhood_size,subtract_from_mean)
#参数 cv2.ADAPTIVE_THRESH_GAUSSIAN_C 将像素的阈值设置为相邻像素强度的加权和,其权重由高斯窗口确定。
#参数 neighborhood_size 块大小(用于确定像素阈值的邻域大小)
#参数 subtract_from_mean 一个用来手动调整阈值的常数(从计算出的阈值中减去该常数)

#我们可以将该参数设置为 cv2.ADAPTIVE_THRESH_MEAN_C, 使用相邻像素的平均值作为阈值 :
# 使用 cv2.ADAPTIVE_THRESH_MEAN_C
image_mean_threshold = cv2.adaptiveThreshold(image_grey,max_output_value,cv2.ADAPTIVE_THRESH_MEAN_C,                                     cv2.THRESH_BINARY,neighborhood_size,subtract_from_mean)

удалить фон

# 加载图像,并将其转换为 RGB 格式
image_bgr = cv2.imread('images/plane_256x256.jpg')
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
# 矩形的值 :左上角的 x 坐标,左上角的 y 坐标,宽、高
rectangle = (0, 56, 256, 150)
# 创建初始掩模
mask = np.zeros(image_rgb.shape[:2], np.uint8)
# 创建 grabCut 函数需要的临时数组
bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)
# 执行 grabCut 函数
cv2.grabCut(image_rgb, # 图像
mask, # 掩模
rectangle, # 矩形
bgdModel, # 背景的临时数组
fgdModel, # 前景的临时数组
5, # 迭代次数
cv2.GC_INIT_WITH_RECT) # 使用定义的矩形初始化
# 创建一个掩模,将确定或很可能是背景的部分设置为 0,其余部分设置为 1
mask_2 = np.where((mask==2) | (mask==0), 0, 1).astype('uint8')
# 将图像与掩模相乘以除去背景
image_rgb_nobg = image_rgb * mask_2[:, :, np.newaxis]
# 显示图像
plt.imshow(image_rgb_nobg), plt.axis("off")

обнаружение края

Обнаружение краев может помочь нам удалить области с низким содержанием информации и отделить наиболее информативные области от исходного изображения. Детектор Харриса ищет окно (также называемое окрестностью), в котором небольшие движения (подумайте о встряхивании окна) вызывают большие изменения значений пикселей внутри окна.

# 计算像素强度的中位数
image_gray = cv2.imread("E:/sim_data-master/images/plane_256x256.jpg", cv2.IMREAD_GRAYSCALE)
median_intensity = np.median(image_gray)
# 设置阈值
lower_threshold = int(max(0, (1.0 - 0.33) * median_intensity))
upper_threshold = int(min(255, (1.0 + 0.33) * median_intensity))
# 应用 Canny 边缘检测器
image_canny = cv2.Canny(image_gray, lower_threshold, upper_threshold)

Обнаружение угла

# 设置角点检测器的参数
block_size = 2 #代表角点检测中窗口的尺寸
aperture = 29 #代表 Sobel 算子的尺寸
free_parameter = 0.04 #用于控制对角点检测的严格程度,这个值越大,可以识别的角点越平滑
# 检测角点
detector_responses = cv2.cornerHarris(image_gray,block_size,aperture,free_parameter)
# 放大角点标志
detector_responses = cv2.dilate(detector_responses, None)
# 只保留大于阈值的检测结果,并把它们标记成白色
threshold = 0.02
image_bgr[detector_responses >threshold *detector_responses.max()] = [255,255,255]
# 转换成灰度图
image_gray = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2GRAY)

Преобразование матрицы изображения в данные 1D

# 以灰度图格式加载图像
image = cv2.imread("E:/sim_data-master/images/plane_256x256.jpg", cv2.IMREAD_GRAYSCALE)
# 将图像尺寸转换成 10× 10
image_10x10 = cv2.resize(image, (10, 10))
# 将图像数据转换成一维向量
image_10x10.flatten()

кодировать средние значения цвета в функции

# 以 BGR 格式加载图像
image_bgr = cv2.imread("E:/sim_data-master/images/plane_256x256.jpg", cv2.IMREAD_COLOR)
# 计算每个通道的平均值
channels = cv2.mean(image_bgr)
# 交换红色和蓝色通道,将图像从 BGR 格式转换成 RGB 格式
observation = np.array([(channels[2], channels[1], channels[0])])
# 显示每个颜色通道的平均值
observation

Кодируйте цветовые гистограммы в функции

# 将图像转换成 RGB 格式
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
# 创建一个特征列表
features = []
# 为每一个颜色通道计算直方图
colors = ("r","g","b")
# 为每一个通道计算直方图并把它加入特征列表中
for i, channel in enumerate(colors):
    histogram = cv2.calcHist([image_rgb], # 图像
                             [i], # 颜色通道的序号
                             None, # 不使用掩模
                             [256], # 直方图尺寸
                             [0,256]) # 范围
    
    features.extend(histogram)
# 将样本的特征值展开成一维数组
observation = np.array(features).flatten()
# 显示样本的前 5 个特征值
observation[0:5]

# 计算每个颜色通道的直方图
colors = ("r","g","b")
# 对每个通道绘制直方图
for i, channel in enumerate(colors):
    histogram = cv2.calcHist([image_rgb], # 图像
            [i], # 颜色通道的序号
            None, # 不使用掩模
            [256], # 直方图尺寸
            [0,256]) # 范围
    plt.plot(histogram, color = channel)
    plt.xlim([0,256])
# 显示图
plt.show()