How to cut out annular of this Image?

6 views (last 30 days)
Hello,
i want to cut out everything but the annular in between the red circles and display that in an axes.
Heres the original image:

Accepted Answer

Image Analyst
Image Analyst on 15 Aug 2018
The code below works for this image. Of course it may not work if you change the lighting, exposure, camera angle, F-stop, or clutter (other stuff) in the image, and would need adaptation for those cases.
% Code to analyze grinding wheel
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clearvars;
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 16;
%=======================================================================================
% Read in image.
fullFileName = fullfile(pwd, 'annular_orig.jpg');
[folder, baseFileName, ext] = fileparts(fullFileName);
rgbImage = imread(fullFileName);
% Shrink it to speed it up
% rgbImage = imresize(rgbImage, 0.75);
% Get the dimensions of the image.
[rows, columns, numberOfColorChannels] = size(rgbImage);
% Display the original image.
subplot(2, 2, 1);
imshow(rgbImage, []);
axis on;
caption = sprintf('Original Color Image "%s"', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0.05 1 0.95]);
% Get rid of tool bar and pulldown menus that are along top of figure.
% set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
% Get mask for outer gray, and inner blue parts of the wheel by doing color segmentations.
[wheelMask,maskedRGBImage] = createMaskForWholeWheel(rgbImage);
[blueMask,maskedRGBImage] = createMaskForBlueCenter(rgbImage);
% Clean up noise by filling holes and taking largest blob only.
wheelMask = imfill(wheelMask, 'holes');
wheelMask = bwareafilt(wheelMask, 1);
blueMask = imfill(blueMask, 'holes');
blueMask = bwareafilt(blueMask, 1);
% Display the images.
subplot(2, 2, 2);
imshow(wheelMask);
axis on;
title('Total Wheel Mask', 'FontSize', fontSize, 'Interpreter', 'None');
subplot(2, 2, 3);
imshow(blueMask);
axis on;
title('Blue Center Mask', 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
% Get the ring mask
ringMask = wheelMask & ~blueMask;
% Display the image.
subplot(2, 2, 4);
imshow(ringMask);
axis on;
title('Ring Mask', 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
% Find boundaries
boundaries = bwboundaries(ringMask);
% Display the original image with mask boundary over it.
figure;
imshow(rgbImage, []);
axis on;
caption = sprintf('Color Image with Boundary');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
% Plot boundaries
hold on;
numberOfBoundaries = size(boundaries, 1);
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k};
plot(thisBoundary(:,2), thisBoundary(:,1), 'r', 'LineWidth', 3);
end
hold off;
% Get the equivalent circular diameters.
propsWheel = regionprops(wheelMask, 'EquivDiameter');
wheelDiameter = propsWheel.EquivDiameter
propsBlue = regionprops(blueMask, 'EquivDiameter');
blueDiameter = propsBlue.EquivDiameter
% Get the area of the ring and put it up on the image.
ringArea = sum(ringMask(:));
message = sprintf('Area of ring = %d pixels.\nAverage Diameter of Entire Wheel = %.1f pixels.\nAverage Diameter of Blue Part = %.1f pixels.\nAverage Thickness of Edge = %.1f pixels.', ...
ringArea, wheelDiameter, blueDiameter, wheelDiameter-blueDiameter);
text(20, 150, message, 'FontSize', fontSize, 'Color', 'y', 'FontWeight', 'bold', 'VerticalAlignment', 'top');
function [BW,maskedRGBImage] = createMaskForWholeWheel(RGB)
%createMask Threshold RGB image using auto-generated code from colorThresholder app.
% [BW,MASKEDRGBIMAGE] = createMask(RGB) thresholds image RGB using
% auto-generated code from the colorThresholder app. The colorspace and
% range for each channel of the colorspace were set within the app. The
% segmentation mask is returned in BW, and a composite of the mask and
% original RGB images is returned in maskedRGBImage.
% Auto-generated by colorThresholder app on 15-Aug-2018
%------------------------------------------------------
% Convert RGB image to chosen color space
I = rgb2hsv(RGB);
% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.363;
channel1Max = 0.855;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 0.000;
channel2Max = 1.000;
% Define thresholds for channel 3 based on histogram settings
channel3Min = 0.000;
channel3Max = 1.000;
% Create mask based on chosen histogram thresholds
sliderBW = (I(:,:,1) >= channel1Min ) & (I(:,:,1) <= channel1Max) & ...
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) & ...
(I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
BW = sliderBW;
% Initialize output masked image based on input image.
maskedRGBImage = RGB;
% Set background pixels where BW is false to zero.
maskedRGBImage(repmat(~BW,[1 1 3])) = 0;
end
function [BW,maskedRGBImage] = createMaskForBlueCenter(RGB)
%createMask Threshold RGB image using auto-generated code from colorThresholder app.
% [BW,MASKEDRGBIMAGE] = createMask(RGB) thresholds image RGB using
% auto-generated code from the colorThresholder app. The colorspace and
% range for each channel of the colorspace were set within the app. The
% segmentation mask is returned in BW, and a composite of the mask and
% original RGB images is returned in maskedRGBImage.
% Auto-generated by colorThresholder app on 15-Aug-2018
%------------------------------------------------------
% Convert RGB image to chosen color space
I = rgb2hsv(RGB);
% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.569;
channel1Max = 0.671;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 0.229;
channel2Max = 1.000;
% Define thresholds for channel 3 based on histogram settings
channel3Min = 0.251;
channel3Max = 1.000;
% Create mask based on chosen histogram thresholds
sliderBW = (I(:,:,1) >= channel1Min ) & (I(:,:,1) <= channel1Max) & ...
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) & ...
(I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
BW = sliderBW;
% Initialize output masked image based on input image.
maskedRGBImage = RGB;
% Set background pixels where BW is false to zero.
maskedRGBImage(repmat(~BW,[1 1 3])) = 0;
end

More Answers (1)

Image Analyst
Image Analyst on 13 Aug 2018
Do you already have the (x,y) coordinates of the red circles you plotted? If so, you can just use polyarea().
Or do you not have that and need to do color segmentation to find the whole wheel and the gray outer part?
You should improve your image capture situation. The white background should fill the entire background and not have wood showing. Also you should use better lighting so that you don't have shadows.
  5 Comments
Image Analyst
Image Analyst on 14 Aug 2018
It's easy but complicated somewhat by the fact that you're choosing not to use a big enough sheet of white paper. So what you need to do is first to identify the wood and make that white. You can use the color thresholder app to do that. Then use it again in HSV color space to find the gray outer ring, and the inner blue ring. Now you have two masks and can do whatever you want. Give it a try - it's not hard. Ask again if you tried but just can't figure it out.
Nimos Sereth
Nimos Sereth on 14 Aug 2018
Edited: Nimos Sereth on 14 Aug 2018
Thanks alot, I did it by using 3 points around the outer and inner circumference to establish two circles and then using a mask which only shows elements in bewtween the radii. Again thanks for your help!

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!