generating random particles effect to an image

조회 수: 12(최근 30일)
David Levi
David Levi 2022년 8월 6일
편집: DGM 2022년 8월 6일
Hi!
I want to implement a code that generates random colored particles effect into an image, something like the attached image
'particles.jpg' . (the background will be bleck, eventually I want to create png image)
My idea is to generate random 2d gaussians (with random centers and radius), and then combining them to one image. After that I want to paint them with random colors (each of them will have different color).
can you please help me create this code?

채택된 답변

DGM
DGM 2022년 8월 6일
편집: DGM 2022년 8월 6일
This is built using MIMT tools:
% parameters
s = [500 300]; % output image size [height width]
numspots = 20; % number of spots
spotbounds = [30 70]; % allowable range of spot widths (px)
spotopacity = [0.1 0.7]; % allowable range of spot opacity
blurbounds = [0 50]; % allowable range of blur width (px)
bgcolor = [0.08 0 0.2]; % background color (unit-scale)
spotbounds = round(spotbounds/2); % convert to radius
s = [s(1:2) 3]; % output is color
padwidth = spotbounds(2) + blurbounds(2) + 2; % calculate required padding
wpict = colorpict([s(1:2)+padwidth*2 s(3)],bgcolor); % preallocate
for n = 1:numspots
% create antialiased disk (the spot)
rspot = ceil(randrange(spotbounds,[1 1]));
spotmap = simnorm(fkgen('disk',[2 2]*rspot));
% blur the spot as required
fkb = fkgen('gaussian',randrange(blurbounds,[1 1]));
spotmap = imfilter(spotmap,fkb,'full');
% find coordinates to insert the spot
rxy = ceil(rand([1 2]).*s(1:2))+padwidth;
rspot = size(spotmap,1)/2;
rangec = (rxy(1)-floor(rspot)):(rxy(1)+ceil(rspot)-1);
ranger = (rxy(2)-floor(rspot)):(rxy(2)+ceil(rspot)-1);
% composite the spot into the image
thisalpha = randrange(spotopacity,[1 1]);
thiscolor = rand(1,3);
thisbg = wpict(rangec,ranger,:);
wpict(rangec,ranger,:) = replacepixels(thiscolor,thisbg,spotmap*thisalpha);
end
outpict = imcast(cropborder(wpict,padwidth),'uint8');
imshow(outpict)
The rest is tailoring the distributions. For example:
% parameters
s = [300 500]; % output image size [height width]
numspots = 70; % number of spots
spotbounds = [15 40]; % allowable range of spot widths (px)
spotopacity = [0.1 0.7]; % allowable range of spot opacity
blurbounds = [0 50]; % allowable range of blur width (px)
bgcolor = [0.08 0 0.2]; % background color (unit-scale)
clustercenter = [1 0.5]; % cluster location in normalized coordinates [y x]
clustersigma = [0.25 0.25]; % control spread of spots away from cluster center
spotbounds = round(spotbounds/2);
s = [s(1:2) 3];
padwidth = spotbounds(2) + blurbounds(2) + 2;
wpict = colorpict([s(1:2)+padwidth*2 s(3)],bgcolor);
for n = 1:1:numspots
% create antialiased disk (the spot)
rspot = ceil(randrange(spotbounds,[1 1]));
spotmap = simnorm(fkgen('disk',[2 2]*rspot));
% blur the spot as required
fkb = fkgen('gaussian',randrange(blurbounds,[1 1]));
spotmap = imfilter(spotmap,fkb,'full');
% find coordinates to insert the spot
goodpoint = false;
while ~goodpoint
rxy = ceil((clustercenter + clustersigma.*randn([1 2])).*s(1:2))+padwidth;
goodpoint = all(rxy > padwidth) && all(rxy <= padwidth+s(1:2));
end
rspot = size(spotmap,1)/2;
rangec = (rxy(1)-floor(rspot)):(rxy(1)+ceil(rspot)-1);
ranger = (rxy(2)-floor(rspot)):(rxy(2)+ceil(rspot)-1);
% composite the spot into the image
thisalpha = randrange(spotopacity,[1 1]);
thiscolor = rand(1,3);
thisbg = wpict(rangec,ranger,:);
wpict(rangec,ranger,:) = replacepixels(thiscolor,thisbg,spotmap*thisalpha);
end
outpict = imcast(cropborder(wpict,padwidth),'uint8');
  댓글 수: 4
DGM
DGM 2022년 8월 6일
편집: DGM 2022년 8월 6일
If you want to simulate motion, then you'll have to take a step backward and separate the spot creation and positioning from the compositing. You'll have to keep track of each spot sub-image, its position/trajectory, its color and alpha between frames. If new spots are allowed to move into frame during the sequence, then it just becomes that much more complicated.
Consider the given examples as a simplified version of what you want. Some of the elements should still be useful. I don't have the time to write a whole thing. What I posted was an adaptation of something I had at hand.
I should add that if you want to simulate depth of field with the blur, you might want to scale the blur according to the spot size instead of allowing it to be independent and random like I did.

댓글을 달려면 로그인하십시오.

추가 답변(1개)

Image Analyst
Image Analyst 2022년 8월 6일
Here's a start. I trust you can finish it. If so, see this:
% Demo by Image Analyst to create multiple Gaussians.
% Initialization Steps.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
numSpheres = 50;
windowWidth = 30;
rows = 640;
columns = 640;
grayImage = zeros(rows, columns, 'uint8');
for k = 1 : numSpheres
radius = windowWidth * rand;
g = rescale(fspecial("gaussian", windowWidth, radius), 0, 1);
g = uint8(255 * g);
subplot(1, 2, 1);
imshow(g, []);
axis('on', 'image')
caption = sprintf('One Gaussian with sigma = %.5f', radius);
title(caption, 'FontSize', fontSize)
xUpperLeft = round(rand(1) * (columns - windowWidth)) + 1;
yUpperLeft = round(rand(1) * (rows - windowWidth)) + 1;
% Paste in image
grayImage(yUpperLeft : (yUpperLeft + windowWidth - 1), xUpperLeft : (xUpperLeft + windowWidth - 1)) = g;
subplot(1, 2, 2);
imshow(grayImage, []);
axis('on', 'image')
caption = sprintf('%d Gaussians', k);
title(caption, 'FontSize', fontSize)
drawnow;
end
g = gcf;
g.WindowState = 'maximized'
I'm attaching another demo, gaussianCircles_demo.m, that produces this image.

Community Treasure Hunt

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

Start Hunting!

Translated by