Image Processing Toolbox: Subtracting 2 images

12 views (last 30 days)
Hi everyone! I am working with an image of a cone. Attached:
As you can see, there is a lot of imperfections and I will like to remove them and leave only the black outline of the cone. My first thought was to take the same picture, but without a cone and the substract them. I attach the second image without the cone.
Nevertheless, the operation isnt working as I will expect. The results of the operation are the following, each accounting for different substractions.
In this image imperfections are still present.
And in this image I tried increasing the brightness but didnt work.
Am I thinking the method wrong? Or is there any other better method to process this images?
Thank you in advance!

Accepted Answer

Image Analyst
Image Analyst on 22 Apr 2021
Try this. I trust you can find the angle yourself now that I've found the equation of the lines:
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;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGES
folder = pwd;
baseFileName = 'ConeReference.png';
image1 = imread(baseFileName);
baseFileName = 'ConeTest.png';
image2 = imread(baseFileName);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(image1)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Use weighted sum of ALL channels to create a gray scale image.
image1 = min(image1, [], 3);
end
%--------------------------------------------------------------------------------------------------------
% Display the images.
nexttile
imshow(image1, []);
axis('on', 'image');
title('Reference Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
hFig = gcf;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
% Now show image 2
nexttile
imshow(image2, []);
axis('on', 'image');
title('Test Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
drawnow;
% Get a mask of the bright parts in image 2.
% imhist(image1);
% grid on;
mask = imbinarize(image2);
nexttile
imshow(mask, []);
axis('on', 'image');
title('Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
drawnow;
% Get the means of each image within the mask region.
meanRef = mean(image1(mask))
meanTest = mean(image2(mask))
% Scale image 2 so that the mean in the bright region will be the same as for image1.
% This will enable better, more complete subtraction.
image2 = uint8(double(image2) * meanRef / meanTest);
% Double check the mean - should be really close as image 1 now.
meanTest = mean(image2(mask))
% Compute the difference image.
diffImage = imabsdiff(image1, image2);
% Display the image.
nexttile
imshow(diffImage, []);
axis('on', 'image');
title('Difference Image', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
% Check the mean of the subtraction image in the mask region - should be close to 0.
meanSubtraction = mean(diffImage(mask))
% Threshold to find the cone.
coneMask = imbinarize(diffImage);
nexttile
imshow(coneMask, []);
axis('on', 'image');
title('Cone Alone', 'FontSize', fontSize, 'Interpreter', 'None');
impixelinfo;
drawnow;
% Find the highest y value - the top of the cone
[r, c] = find(coneMask);
[minR, indexOfMinR] = min(r)
peakC = c(indexOfMinR);
hold on;
xline(peakC, 'Color', 'r', 'LineWidth', 2); % Put a line there.
% Get left half coordinates
leftx = c(c < peakC);
lefty = r(c < peakC);
% Fit to a line
coefficientsLeft = polyfit(leftx, lefty, 1)
yFittedLeft = polyval(coefficientsLeft, leftx);
plot(leftx, yFittedLeft, 'r-', 'LineWidth', 2); % Overlay fitted line over image.
% Get right half coordinates
rightx = c(c >= peakC);
righty = r(c >= peakC);
% Fit to a line
coefficientsRight = polyfit(rightx, righty, 1)
yFittedRight = polyval(coefficientsRight, rightx);
plot(rightx, yFittedRight, 'r-', 'LineWidth', 2); % Overlay fitted line over image.
msgbox('Done');

More Answers (1)

Image Analyst
Image Analyst on 21 Apr 2021
What I'd do is to make a template of the bright spot without the cone. Then determine the means and scale them, then subtract.
% Get the mean of each image.
mean1 = mean(refimage(mask))
mean2 = mean(testImage(mask));
% Scale test image's mean to be the same as the reference image's mean.
testImage = double(testImage) * mean1 / mean2;
% Cast it back to the same image type as refImage.
testImage = cast(testImage, 'like', refimage);
% Now subtract.
subtractionImage = imabsdiff(refImage, testImage);
Now they should subtract much closer to zero than with what you did.
  1 Comment
Urbano Alfonso Medina Martinez
Im really sorry but I wasn´t able to run the first line of code. I apologize, I am new to image processing.
The problem I am having is how to define the mask. So, applying a mask to a matrix (which corresponds in this case to the image) is extracting all those values which obeys the mask condition, i.e., numbers greater or smaller than the mask. Then I will simply find the mean of this values by using the mean function.
But how do I define an appropriate mask?
That is my question. Thanks!

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!