Snowy with Fog style image processor (a function)

Version 1.0.0 (3,05 KB) von Chun
Converts an image to a snowy fog style with realistic Bokeh flakes.
0 Downloads
Aktualisiert 22. Sep 2025

Lizenz anzeigen

function imgOut = snowyFog(inputData, varargin)
% snowyFog_v4: Converts an image to a snowy fog style with realistic Bokeh flakes.
% 将图像转换为雪雾风格,雪花效果基于真实的焦外成像(Bokeh)原理。
%
% Version: 4.0 (Bugfix & Blend Mode Improvement)
% Key Improvements:
% - Fixed a critical bug that caused the image to turn white.
% (修复了导致画面全白的致命bug)
% - Used Screen Blend for layering snowflakes, preventing brightness overflow.
% (使用屏幕混合模式叠加雪花,防止亮度溢出,效果更真实)
%
% USAGE:
% imshow(snowyFog('landscape.jpg'));
% imgOut = snowyFog(img, 'snow_amount', 20000, 'flake_blur_range', [0.5, 8]);
% 1. Input Parser / 参数解析
p = inputParser;
addRequired(p, 'inputData');
addParameter(p, 'fog_density', 0.6, @(x) x>=0 && x<=1);
addParameter(p, 'snow_amount', 1500, @isnumeric);
addParameter(p, 'motion_blur_strength', 20, @isnumeric);
addParameter(p, 'desaturation', 0.8, @(x) x>=0 && x<=1);
addParameter(p, 'flake_blur_range', [5, 20], @(x) isnumeric(x) && numel(x)==2); % [min_sigma, max_sigma]
addParameter(p, 'flake_opacity_range', [10, 50], @(x) isnumeric(x) && numel(x)==2); % [min, max]
parse(p, inputData, varargin{:});
params = p.Results;
% 2. Load Image & Initialization / 读取图像与初始化
if ischar(params.inputData) || isstring(params.inputData)
img_orig = imread(params.inputData);
else if isnumeric(params.inputData) && ndims(params.inputData) == 3
img_orig = params.inputData;
else, error('Invalid input. Must be a file path or an RGB image matrix.');
end
end
img_orig = im2double(img_orig);
[h, w, ~] = size(img_orig);
fprintf('Initializing snowy fog effect v4.0 (Bugfix Edition)...\n');
% 3. Layer 1: Depth-Aware Fog / 第一层: 带景深的雾气
fprintf('Layer 1: Generating depth-aware fog...\n');
gray_img = rgb2gray(img_orig);
desaturated_img = gray_img * params.desaturation + img_orig * (1 - params.desaturation);
depth_mask = repmat(linspace(1, 0.2, h)', 1, w);
depth_mask = imgaussfilt(depth_mask, 20);
fog_intensity = depth_mask .* params.fog_density;
fog_color = 0.95;
foggy_img = desaturated_img .* (1 - fog_intensity) + fog_color .* fog_intensity;
foggy_img = imgaussfilt(foggy_img, 1.5);
foggy_img = min(max(foggy_img, 0), 1);
% 4. Layer 2: Randomized Bokeh Snowflakes / 第二层: 随机焦外成像雪花
fprintf('Layer 2: Generating realistic Bokeh snowflakes...\n');
num_flakes = params.snow_amount;
x_coords = randi(w, num_flakes, 1);
y_coords = randi(h, num_flakes, 1);
flake_sigmas = params.flake_blur_range(1) + rand(num_flakes, 1) * (params.flake_blur_range(2) - params.flake_blur_range(1));
flake_opacities = params.flake_opacity_range(1) + rand(num_flakes, 1) * (params.flake_opacity_range(2) - params.flake_opacity_range(1));
num_groups = 6;
sigma_groups = linspace(params.flake_blur_range(1), params.flake_blur_range(2), num_groups);
snow_canvas = zeros(h, w);
screen_blend = @(A, B) 1 - (1 - A) .* (1 - B); % 定义屏幕混合函数
for i = 1:num_groups
if i == 1
indices = flake_sigmas <= sigma_groups(1);
else
indices = flake_sigmas > sigma_groups(i-1) & flake_sigmas <= sigma_groups(i);
end
if ~any(indices), continue; end
group_x = x_coords(indices);
group_y = y_coords(indices);
group_opacities = flake_opacities(indices);
temp_canvas = zeros(h, w);
linear_indices = sub2ind([h, w], group_y, group_x);
temp_canvas(linear_indices) = group_opacities;
kernel_sigma = mean(flake_sigmas(indices));
if kernel_sigma > 0.1
kernel_size = ceil(kernel_sigma * 6) + 1;
kernel = fspecial('gaussian', kernel_size, kernel_sigma);
temp_canvas = imfilter(temp_canvas, kernel, 'replicate', 'conv');
end
% --- 【核心修正】---
% 使用屏幕混合模式叠加雪花层,而不是简单相加(+),以防止亮度溢出
snow_canvas = screen_blend(snow_canvas, temp_canvas);
end
% --- 【修正】移除了之前版本中错误的clamping操作 ---
% The line 'snow_canvas = min(max(snow_canvas, 1), 1);' has been removed.
% 'screen_blend' naturally handles the brightness, making the clamp unnecessary.
% 屏幕混合模式自然地处理了亮度,不再需要手动限制。
if params.motion_blur_strength > 0
angle = 90 + (rand-0.5)*20;
motion_kernel = fspecial('motion', params.motion_blur_strength, angle);
snow_canvas = imfilter(snow_canvas, motion_kernel, 'replicate', 'conv');
end
snow_canvas_color = repmat(snow_canvas, [1, 1, 3]);
% 5. Final Blending / 最终混合
fprintf('Finalizing the image...\n');
final_img = screen_blend(foggy_img, snow_canvas_color);
% 6. Final Output / 最终输出
imgOut = im2uint8(final_img);
fprintf('Snowy fog effect v4.0 applied successfully.\n');
end

Zitieren als

Chun (2025). Snowy with Fog style image processor (a function) (https://www.mathworks.com/matlabcentral/fileexchange/182088-snowy-with-fog-style-image-processor-a-function), MATLAB Central File Exchange. Abgerufen.

Kompatibilität der MATLAB-Version
Erstellt mit R2025b
Kompatibel mit allen Versionen
Plattform-Kompatibilität
Windows macOS Linux

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!
Version Veröffentlicht Versionshinweise
1.0.0