How to do background subtraction between two images

120 views (last 30 days)
I got many numerical frames. Please help me to revise the code to subtract the background so that I can work on the region which I am Interested (spray evolution). I also attached two pictures for your refenences.
My code:
backgroundImage = imread('animation-1_0000.png');
% Ensure the background image is grayscale
if size(backgroundImage, 3) == 3
backgroundImage = rgb2gray(backgroundImage);
end
% Check if the file exists
if isfile(currentFileName)
% Read the current image
thisImage = imread(currentFileName);
% Convert to grayscale if necessary
if size(thisImage, 3) == 3
thisImage = rgb2gray(thisImage);
end
% Debug: Print sizes before resizing
fprintf('Background image size: [%d, %d]\n', size(backgroundImage));
fprintf('Current image size: [%d, %d]\n', size(thisImage));
% Resize to match the background image size
if ~isequal(size(thisImage), size(backgroundImage))
thisImage = imresize(thisImage, size(backgroundImage));
end
% Perform subtraction
subtractionImage = backgroundImage - thisImage;
% Save the subtraction result
saveFileName = sprintf('%s/Sub/%04d.bmp', savefolder, i);
imwrite(subtractionImage, saveFileName);
% Black and White Image Processing
% Create a binary mask based on threshold
mask1 = abs(Wh) > 10; % Threshold above the noise level (10 gray levels)
% Rotate the mask image
J = imrotate(mask1, 90);
% Save the rotated mask
saveFileName = sprintf('%s/Wh/animation-1_%04d.png', savefolder, i);
imwrite(J, saveFileName);
end

Accepted Answer

Image Analyst
Image Analyst on 24 Nov 2024 at 1:50
@Khai your code and the other answer's code here is not correct. You cannot just subtract the pseudocolored images. They MUST be converted to grayscale using the colormap as shown in the colorbar. You cannot just simply call rgb2gray. It's not the same. I can't stress this enough. Don't do it.
If you have the original gray scale image, use that. If you don't you can "undo" the colormapping using a process as shown in my thermal image demo in my File Exchange:
  2 Comments
Khai
Khai on 24 Nov 2024 at 2:11
Edited: Khai on 24 Nov 2024 at 2:14
Thanh you so much for your support. It gone beyond my expectations.
Image Analyst
Image Analyst on 24 Nov 2024 at 3:16
The colorbar you were supposed to outline is just the colorbar, you should not include the tickbars and labels and white background, though I might have put in code to ignore that in order to make it more robust.
So do that for both images and save the floating point images and then you can do the background subtraction.
The reason you can't simply call rgb2gray is that there may be several colors along the colorbar that have the same gray level even though they should not have since they are at different parts of the scale.

Sign in to comment.

More Answers (1)

Ayush
Ayush on 22 Nov 2024 at 11:40
Hi Khai,
I understand that you need to subtract the background effectively. Few improvements to the current logic can be done and integrated with your specific region of interest, which is the spray evolution.
Here is how you can enhance the process:
1. The current approach directly subtracts the background from each frame, but it may create negative values or lose fine details. To avoid this, we can take the absolute value of the subtraction or apply a threshold to highlight significant differences (such as spray movement).
2. After subtraction, we can focus on the region of interest (e.g., the spray). You might want to either define a fixed region or use image segmentation to extract dynamic areas where the spray evolves.
3. To better isolate the spray, we can apply thresholding to the difference image, followed by morphological operations (like erosion or dilation) to remove noise and fill gaps in the spray's structure.
4. We will add your mask-processing logic for further refinement, ensuring only relevant areas (spray) are focused upon.
Here is pseudo code for your reference:
backgroundImage = imread('animation-1_0000.png');
% Ensure the background image is grayscale
if size(backgroundImage, 3) == 3
backgroundImage = rgb2gray(backgroundImage);
end
if isfile(currentFileName)
% Read the current image
thisImage = imread(currentFileName);
if size(thisImage, 3) == 3
thisImage = rgb2gray(thisImage);
end
if ~isequal(size(thisImage), size(backgroundImage))
thisImage = imresize(thisImage, size(backgroundImage));
end
% Perform background subtraction (absolute difference to avoid negative values)
subtractionImage = abs(double(backgroundImage) - double(thisImage));
% Threshold to remove small differences (noise removal)
threshold = 10;
subtractionImage(subtractionImage < threshold) = 0;
% Apply binary thresholding to focus on significant differences (e.g., spray)
binaryImage = subtractionImage > threshold; % Create a binary mask
% Apply morphological operations to clean up the binary mask (optional)
binaryImage = imclose(binaryImage, strel('disk', 5)); % Fill small gaps
binaryImage = imopen(binaryImage, strel('disk', 3)); % Remove small noise
saveFileName = sprintf('%s/Sub/%04d.bmp', savefolder, i);
imwrite(subtractionImage, saveFileName);
% Further processing on the mask
% Rotate the mask for consistency with your logic
rotatedMask = imrotate(binaryImage, 90);
saveFileName = sprintf('%s/Wh/animation-1_%04d.png', savefolder, i);
imwrite(rotatedMask, saveFileName);
end
For more information on “imread”, you can refer here: https://www.mathworks.com/help/matlab/ref/imread.html
For more information on “imwrite”, you can refer here: https://www.mathworks.com/help/matlab/ref/imwrite.html
For more information on “rgb2gray”, you can refer here: https://www.mathworks.com/help/matlab/ref/rgb2gray.html
Hope it helps!
  3 Comments
Walter Roberson
Walter Roberson on 23 Nov 2024 at 19:10
You are going to need to describe the difference between what you want and what @Ayush has provided. Just saying that your problem can not be solved until now does not give us any information about what you are looking for that has not already been given.
Khai
Khai on 24 Nov 2024 at 1:31
Edited: Khai on 24 Nov 2024 at 1:32
I revised my code to get this result but it till did not match my expectation. I focus to get on the region which I am Interested (spray evolution, yellow color region on white background). My code also atttached below. Could you please help me to revise it.
image1 = imread('animation-1_0000.png');
image2 = imread('animation-1_2569.png');
if size(image1, 3) == 4
image1 = image1(:, :, 1:3);
end
if size(image2, 3) == 4
image2 = image2(:, :, 1:3);
end
image1 = double(image1);
image2 = double(image2);
diffImage = abs(image1 - image2);
normalizedDiff = mat2gray(diffImage);
figure;
subplot(1, 3, 1); imshow(uint8(image1)); title('Image 1');
subplot(1, 3, 2); imshow(uint8(image2)); title('Image 2');
subplot(1, 3, 3); imshow(normalizedDiff); title('Difference Image');
differenceImageToSave = uint8(normalizedDiff * 255);
imwrite(differenceImageToSave, 'difference_image.png');
result

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!