掘金 阅读 ( ) • 2024-04-27 16:42

1.图像合成

设计思路

我们目的是合成三张不同光照条件下的图片以优化整体的视觉效果。为达成此目的,我们采用了权重分布的方法,通过调整每张图片的权重来强调或减弱特定区域的影响。通过使用 Sigmoid 函数,我们设定了在图片中心附近权重急剧下降的策略,使得每张图片只在其光照条件最佳的区域对最终图像贡献最大。

实现方法

  1. 图片处理与读取:首先,读取三张具有不同光照条件的图片。
  2. 权重设计:使用 Sigmoid 函数创建两种权重分布——一种从左至右逐渐减少,另一种从右至左逐渐减少。这两种分布分别应用于左侧和右侧光照的图片。
  3. 权重应用与图片合成:将设计好的权重矩阵应用到相应的图片上,再将所有处理过的图片叠加,生成最终的合成图像。
  4. 结果展示与分析:显示合成的图片和各个权重分布的图表,以便于直观理解每种权重分布对最终图像的影响。

Matlab代码

% 读取图片
img_no_light = imread('1.jpg');
img_left_light = imread('2.jpg');
img_right_light = imread('3.jpg');

% 获取图片大小
[rows, cols, ~] = size(img_no_light);

% 中心点附近急剧下降的权重
slope_factor = 1.5; % 增加这个值使变化更陡峭,减少使变化更平缓
x = linspace(-6 * slope_factor, 6 * slope_factor, cols);
sigmoid = 1 ./ (1 + exp(-x)); % Sigmoid 函数

% 左光照权重(中间向右急剧下降)
weight_left = sigmoid;
% 右光照权重(中间向左急剧下降)
weight_right = fliplr(sigmoid);

% 将权重矩阵扩展到三维,匹配 RGB 图像
weight_left = repmat(weight_left, [rows, 1, 3]);
weight_right = repmat(weight_right, [rows, 1, 3]);
weight_no_light = ones(rows, cols, 3); % 无光照图片权重不变

% 应用权重
left_weighted = double(img_left_light) .* weight_left;
right_weighted = double(img_right_light) .* weight_right;
no_light_weighted = double(img_no_light) .* weight_no_light;

% 合成图片
composite_img = uint8(left_weighted + right_weighted + no_light_weighted);

% 显示结果
imshow(composite_img);
title('合成图片');

% 绘制权重分布图
figure;
plot(1:cols, sigmoid, 'b-', 'LineWidth', 2); hold on;
plot(1:cols, fliplr(sigmoid), 'r-', 'LineWidth', 2);
plot(1:cols, ones(1, cols), 'g-', 'LineWidth', 2);
legend('左侧光照权重', '右侧光照权重', '无光照权重');
title('权重分布');
xlabel('像素列');
ylabel('权重值');
grid on;

效果

image.png image.png

2.图像调整

设计思路

我们通过用户交互选择的四个点对图像进行透视变换,以便将选定的四个点对应移至图像的四个角。此过程可用于校正图像的视角偏差,例如扫描文档或照片时的扭曲。通过对图像先进行直方图均衡化,增强了图像的对比度,从而使得特征点的选择更加清晰和准确。

实现方法

  1. 图像预处理:加载原始图像,并检查其是否为灰度图。如果不是,将其转换为灰度图以简化处理过程。接着,对图像进行直方图均衡化,以改善图像的整体对比度,使得特征点更易于识别。
  2. 点的选择与标记:利用 ginput 函数实现图像上的点选功能,允许用户依次选择四个点(左上角、右上角、左下角和右下角)。选择的每个点在图像上即时标记,并存储其坐标。
  3. 透视变换的定义与应用:根据用户选定的四个点和图像四角的预设坐标,使用 fitgeotrans 函数创建透视变换对象。随后,应用该变换到原始或直方图均衡化后的图像,使用 imwarp 函数进行实际的图像变换。
  4. 变换结果的展示:展示变换后的图像,以便用户可以直接看到透视校正的效果。

Matlab代码

% 读取图片
img = imread('4.png');

% 确保图片是灰度图,如果不是,则转换为灰度图
if size(img, 3) == 3
    img = rgb2gray(img);
end

% 对图片进行直方图均衡化
img_eq = histeq(img);

% 显示经过直方图均衡化的图片
imshow(img_eq);
title('请依次点击四个点:左上角、右上角、左下角、右下角');
movingPoints = zeros(4, 2); % 预先分配4x2的空间,存储x和y坐标


% 使用 ginput 获取四个角的坐标
% 参数 4 表示我们需要获取 4 个点
disp('选取的四个角的像素位置:');
for i = 1:4
    [x, y] = ginput(1);
    movingPoints(i, :) = [x, y]; % 将获得的坐标填入对应的行
    % 可以将坐标点绘制在图像上以确认
    hold on; % 保持当前图像,用于叠加新图层
    plot(x, y, 'r+', 'MarkerSize', 10, 'LineWidth', 2); % 绘制红色的加号标记所选位置
    hold off;
end

fixedPoints = [1 1; size(img, 2) 1; 1 size(img, 1); size(img, 2) size(img, 1)];

% 创建透视变换对象
tform = fitgeotrans(movingPoints, fixedPoints, 'projective');

% 应用变换
transformed_img = imwarp(img, tform, 'OutputView', imref2d(size(img)));

% 显示变换后的图像
figure;
imshow(transformed_img);
title('变换后的图像');

效果

image.png

image.png