1. 归一化
设计思路
归一化是将图像数据缩放到某个特定范围(通常是0到255)的过程,以便不同图像之间可以进行比较或进一步处理。
实现方法
- 找到图像中的最大和最小像素值。
- 使用最大和最小值将所有像素值线性缩放到0到255的范围内。
Matlab代码
matlab
function normalized_img = normalize_image(img)
% 将图像数据类型转换为double以进行计算
img_double = double(img);
% 归一化图像
normalized_img = (img_double - min(img_double(:))) / (max(img_double(:)) - min(img_double(:)));
end
效果
2. Gamma变换
设计思路
Gamma变换用于调整图像的亮度,通过非线性变换增强图像的暗部或亮部细节。
实现方法
- 对图像的每个像素值应用Gamma变换公式:O=I^γ,其中I是输入像素值,O是输出像素值,γ是Gamma值。
Matlab代码
matlab
function gamma_corrected_img = gamma_correction(img, gamma)
% 将图像转换为double类型
img_double = double(img) / 255;
% 应用gamma变换
gamma_corrected_img = img_double .^ gamma;
% 将结果缩放回原始的像素值范围
gamma_corrected_img = uint8(gamma_corrected_img * 255);
end
效果
3. 对数变换
设计思路
对数变换是一种增强图像中暗区域细节的方法,通过对每个像素值应用对数函数来实现。
实现方法
- 对图像的每个像素值应用对数变换公式:O=clog(1+I),其中I是输入像素值,O是输出像素值,c是常数。
Matlab代码
matlab
function log_transformed_img = log_transformation(img)
% 将图像转换为double类型
img_double = double(img);
% 应用对数变换
log_transformed_img = log(1 + img_double);
% 将结果缩放到[0, 255]范围
log_transformed_img = uint8(255 * (log_transformed_img - min(log_transformed_img(:))) / (max(log_transformed_img(:)) - min(log_transformed_img(:))));
end
效果
4. 直方图整体均衡化
设计思路
直方图整体均衡化通过重新分配图像的像素值,使得直方图更加均匀,从而增加整个图像的对比度。
实现方法
- 计算图像的直方图和累积分布函数(CDF)。
- 使用CDF重新映射图像的像素值。
Matlab代码
matlab
function equalized_img = histogram_equalization(img)
% 遍历图像像素值,统计不同像素灰度值的占比
[m, n] = size(img);
hist = zeros(1, 256);
for i = 1:m
for j = 1:n
hist(img(i, j) + 1) = hist(img(i, j) + 1) + 1;
end
end
hist = hist / (m * n);
% 计算累计分布函数
cdf = zeros(1, 256);
cdf(1) = hist(1);
for i = 2:256
cdf(i) = cdf(i - 1) + hist(i);
end
% 将累计分布函数值映射到0-255之间
cdf = round(cdf * 255);
% 对图像进行直方图均衡化
equalized_img = uint8(zeros(m, n));
for i = 1:m
for j = 1:n
equalized_img(i, j) = cdf(img(i, j) + 1);
end
end
end
效果
5. 直方图整体规定化
设计思路
直方图规定化(匹配)是将图像的直方图调整为符合特定分布(通常是另一张图像的直方图)的过程,用于图像增强和匹配。
实现方法
- 计算源图像和目标图像的直方图及其累积分布函数(CDF)。
- 使用源图像的CDF和目标图像的CDF之间的映射关系来调整源图像的像素值。
Matlab代码
matlab
function matched_img = histogram_matching(img, target_img)
% 计算原图像的累计分布函数
[om, on] = size(img);
ohist = zeros(1, 256);
for i = 1:om
for j = 1:on
ohist(img(i, j) + 1) = ohist(img(i, j) + 1) + 1;
end
end
ohist = ohist / (om * on);
ocdf = zeros(1, 256);
ocdf(1) = ohist(1);
for i = 2:256
ocdf(i) = ocdf(i - 1) + ohist(i);
end
% 计算目标图像的累计分布函数
[tm, tn] = size(target_img);
thist = zeros(1, 256);
for i = 1:tm
for j = 1:tn
thist(target_img(i, j) + 1) = thist(target_img(i, j) + 1) + 1;
end
end
thist = thist / (tm * tn);
tcdf = zeros(1, 256);
tcdf(1) = thist(1);
for i = 2:256
tcdf(i) = tcdf(i - 1) + thist(i);
end
% 计算原图像和目标图像的累计分布函数之间的映射关系
mapping = zeros(1, 256);
for i = 1:256
[~, index] = min(abs(ocdf(i) - tcdf));
mapping(i) = index - 1;
end
% 对原图像进行直方图匹配
matched_img = uint8(zeros(om, on));
for i = 1:om
for j = 1:on
matched_img(i, j) = mapping(img(i, j) + 1);
end
end
end
效果
6. 直方图自适应均衡化
设计思路
直方图自适应均衡化(AHE)通过对图像的局部区域应用直方图均衡化来增强局部对比度,而不是整个图像。这可以带来更好的细节增强效果。为了实现AHE,图像被分割成多个32x32大小的区块,每个区块独立进行直方图均衡化,然后将处理后的区块重新组合成完整的图像。
实现方法
- 将图像分割成32x32大小的小块。
- 对每个小块独立进行直方图均衡化。
- 将均衡化后的小块重新组合成整个图像。
Matlab代码
matlab
function ahe_img = adaptive_histogram_equalization(img, tile_size)
% 获取图像的大小
[rows, cols] = size(img);
% 初始化输出图像
ahe_img = zeros(size(img), 'uint8');
% 计算每个维度上的块数
num_tiles_row = ceil(rows / tile_size(1));
num_tiles_col = ceil(cols / tile_size(2));
% 循环处理每个块
for i = 1:num_tiles_row
for j = 1:num_tiles_col
% 计算当前块的边界
row_start = (i-1) * tile_size(1) + 1;
row_end = min(i * tile_size(1), rows);
col_start = (j-1) * tile_size(2) + 1;
col_end = min(j * tile_size(2), cols);
% 提取当前块
tile = img(row_start:row_end, col_start:col_end);
% 对当前块应用直方图均衡化
eq_tile = histogram_equalization(tile);
% 将均衡化后的块放回输出图像
ahe_img(row_start:row_end, col_start:col_end) = eq_tile;
end
end
% 转换输出图像为uint8类型
ahe_img = uint8(ahe_img);
end
效果
7. 同一机位不同时间拍摄的两张图片,图像相减
设计思路
图像相减是一种简单的图像处理技术,用于突出两张图像之间的差异。这在监控和运动检测等领域中非常有用。在这个实验中,从相同的摄像机位置拍摄的两张不同时间的图像被相减,以便观察变化。
实现方法
- 确保两张图像尺寸相同。
- 将一张图像的像素值逐一减去另一张图像对应像素的值。
Matlab代码
matlab
function result = subtract_images(img1, img2)
% 确保两张图像是同一尺寸
assert(all(size(img1) == size(img2)), 'Images must be the same size.');
% 将图像数据类型转换为double以进行计算
img1_double = double(img1);
img2_double = double(img2);
% 图像相减
result_double = img1_double - img2_double;
% 处理结果:取绝对值
result_double = abs(result_double); % 取绝对值
% 将结果归一化到0到255的范围内
result = uint8(255 * mat2gray(result_double));
end
效果
8. 对两个噪声图片相加求平均
设计思路
将两个含有随机噪声的图像相加并求平均,可以在一定程度上抵消噪声。这是图像去噪的基本方法之一,基于噪声的随机性和图像内容的一致性。
实现方法
- 将多张张含噪声的图像像素值相加。
- 将结果除以图片数目,得到平均图像。
Matlab代码
matlab
function avg_img = average_images(img_array)
% 检查输入数组是否为空
assert(~isempty(img_array), 'The image array cannot be empty.');
% 获取第一张图像的尺寸和数据类型作为参考
[rows, cols, channels] = size(img_array{1});
img_type = class(img_array{1});
% 初始化用于累加图像的矩阵
sum_img = zeros(rows, cols, channels, 'double');
% 遍历图像数组,累加所有图像
for i = 1:length(img_array)
% 累加图像
sum_img = sum_img + double(img_array{i});
end
% 计算平均图像,并转换回原始图像的数据类型
avg_img = sum_img / length(img_array);
avg_img = cast(avg_img, 'like', img_array{1}); % 使用'like'参数保持与原图像相同的数据类型
end
效果
9.进行3x3的均值滤波
设计思路
3x3的均值滤波是一种基本的图像平滑技术,通过将每个像素的值替换为其3x3邻域内像素值的平均值来减少图像噪声。
实现方法
- 遍历图像中的每个像素。
- 对每个像素,计算其3x3邻域内像素的平均值。
- 将计算出的平均值赋给当前像素。
Matlab代码
matlab
function filtered_img = mean_filter_3x3(img)
[rows, cols] = size(img);
filtered_img = zeros(rows, cols, class(img));
% 遍历图像中的每个像素
for i = 2:rows-1
for j = 2:cols-1
% 提取3x3邻域
neighborhood = img(i-1:i+1, j-1:j+1);
% 计算邻域的平均值
mean_value = sum(neighborhood(:)) / 9;
% 将平均值赋给中心像素
filtered_img(i, j) = mean_value;
end
end
% 复制边缘像素
filtered_img(1,:) = img(1,:);
filtered_img(end,:) = img(end,:);
filtered_img(:,1) = img(:,1);
filtered_img(:,end) = img(:,end);
end
效果
10.进行5x5的高斯滤波(方差自行确定)
设计思路
5x5的高斯滤波使用高斯函数作为权重,对图像进行平滑处理。这种方法比均值滤波更加有效,因为它考虑了像素与邻域中心的距离,更加重视中心像素的值。
实现方法
- 创建一个5x5的高斯核,核中的值由高斯函数决定。
- 将高斯核应用于图像的每个像素,计算加权平均值。
- 将加权平均值赋给当前像素。
Matlab代码
matlab
function filtered_img = gaussian_filter_5x5(img, sigma)
[rows, cols] = size(img);
filtered_img = zeros(rows, cols, class(img));
% 创建5x5高斯滤波器核
kernel_size = 5;
kernel = zeros(kernel_size, kernel_size);
for i = 1:kernel_size
for j = 1:kernel_size
x = i - ceil(kernel_size/2);
y = j - ceil(kernel_size/2);
kernel(i, j) = exp(-(x^2 + y^2) / (2 * sigma^2));
end
end
kernel = kernel / sum(kernel(:)); % 归一化
% 遍历图像中的每个像素
for i = 3:rows-2
for j = 3:cols-2
% 提取5x5邻域
neighborhood = img(i-2:i+2, j-2:j+2);
% 计算邻域与高斯核的卷积
conv_value = sum(sum(double(neighborhood) .* kernel));
% 将卷积结果赋给中心像素
filtered_img(i, j) = conv_value;
end
end
% 复制边缘像素
filtered_img(1:2,:) = img(1:2,:);
filtered_img(end-1:end,:) = img(end-1:end,:);
filtered_img(:,1:2) = img(:,1:2);
filtered_img(:,end-1:end) = img(:,end-1:end);
end