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.
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 LinuxTags
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Live Editor erkunden
Erstellen Sie Skripte mit Code, Ausgabe und formatiertem Text in einem einzigen ausführbaren Dokument.
Version | Veröffentlicht | Versionshinweise | |
---|---|---|---|
1.0.0 |