Image segmentation - Specify an area of interest

Hi guys,
I have two images ('A' and 'B'). On the first image 'A' there are circle-shaped objects e.g. those chips. What I did so far is to identify those objects with their information about coordinates and radii. Here is the toy-code for the first part:
rgb = imread('coloredChips.png');
figure
imshow(rgb)
d = imdistline;
delete(d);
gray_image = rgb2gray(rgb);
imshow(gray_image);
[centers, radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark')
[centers, radii] = imfindcircles(rgb,[20 25],'ObjectPolarity','dark', ...
'Sensitivity',0.9)
imshow(rgb);
h = viscircles(centers,radii);
Based on the information about the position and radii in 'A', I want to run a second edge detection algorithm on image 'B' to identify there a circle-shaped object, that lies somewhere within the object of the first picture 'A'. Both images has the same dimension.
Objective: Get the coordinates and radii of the objects in image 'A' and the same for image 'B'.
My thoughts: My idea was to draw rectangles around the main object in 'image' B and make the background black. This is not the best solution but it would reduce the running time.
Do you have any hints for me, how to solve this problem?
Thanks a lot.

 Accepted Answer

You can use a mask of the circles, determined from A, on B and analyze what is remaining.
% Creates a mask from one image and applies it to an image.
clc; % Clear the command window.
workspace; % Make sure the workspace panel is showing.
clearvars;
close all;
format long g;
format compact;
fontSize = 20;
rgbImage = imread('coloredChips.png');
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows, columns, numberOfColorChannels] = size(rgbImage);
subplot(3, 2, 1);
imshow(rgbImage)
title('Original RGB Image', 'fontSize', fontSize);
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% 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')
% d = imdistline;
% delete(d);
grayImage = rgb2gray(rgbImage);
subplot(3, 2, 2);
imshow(grayImage);
drawnow;
title('Gray Scale Image', 'fontSize', fontSize);
% [centers, radii] = imfindcircles(rgbImage,[20 25],'ObjectPolarity','dark')
[centers, radii] = imfindcircles(rgbImage,[20 25],'ObjectPolarity','dark', ...
'Sensitivity',0.9)
subplot(3, 2, 3);
imshow(rgbImage);
h = viscircles(centers, radii);
title('Original RGB Image with Circles in Overlay', 'fontSize', fontSize);
% Make a binary image mask
subplot(3, 2, 4);
mask = false(rows, columns);
for k = 1 : length(centers)
% Create a logical image of a circle with specified
% diameter, center, and image size.
% First create the image.
[columnsInImage rowsInImage] = meshgrid(1:columns, 1:rows);
% Next create the circle in the image.
centerX = centers(k, 1);
centerY = centers(k, 2);
radius = radii(k);
circlePixels = (rowsInImage - centerY).^2 ...
+ (columnsInImage - centerX).^2 <= radius.^2;
% circlePixels is a 2D "logical" array.
% Now, display it.
imshow(circlePixels) ;
mask(circlePixels) = true;
imshow(mask);
drawnow;
end
imshow(mask);
title('Binary image mask', 'fontSize', fontSize);
% Mask the image using bsxfun() function
maskedRgbImage = bsxfun(@times, rgbImage, cast(mask, 'like', rgbImage));
subplot(3, 2, 5);
imshow(maskedRgbImage);
title('Masked RGB Image', 'fontSize', fontSize);

6 Comments

Kamu
Kamu on 23 Nov 2016
Edited: Kamu on 23 Nov 2016
Dear Image Analyst, first of all, thank you very much for your useful tutorials. I could learn a lot about image segmentation. Back to your answer, I tried this method before, but it doesn't work for the images I have. Please find attach an example image for 'A' and 'B'. In image 'A' you can see those circles. Some of those are not visible in image 'B' but one of them shares the same position as in 'B'(brightest circle-shaped object). For both, I would like the radii and position. I apologise if it was unclear before.
Those aren't solid discs - they're rings. The center is the same as the surrounding background. So this is a case where you might have to use edge detection. See this paper: http://www.ecse.rpi.edu/homepages/qji/Papers/ellipse_det_icpr02.pdf
Dear Image Analyst,
thanks for the paper. I think it is worth a try to implement the algorithm in matlab. However, I have an additional question about masking. Is it possible to 'label' the masked circles and then to fill those circles black, that the brightness is not high enough given a specific threshold?
Not sure what you're asking. If you have a binary image, you can label the blobs (give each blob an ID number) using bwlabel() or bwconncomp(). You can also fill closed regions with holes in them using imfill(bw, 'holes').
I don't know what the brightness part is asking. You can certainly adjust the brightness using multiplication or the imadjust() function. If you want to adjust the brightness only on pixels above or below a threshold, then you have to create a mask (binaryImage) based on that threshold and then use that as an index. For example:
mask = grayImage > 200;
grayImage(mask) = 233; % Set all pixels more than 200 to a new value of 233.
Kamu
Kamu on 28 Nov 2016
Edited: Kamu on 28 Nov 2016
I apologise for my unprecise question. Please, let me try again. Let say, we have the masked image of coins (grayscale) like here LINK . I would like to distinguish between those coins based on their stamping and fill only those holes, that have a specific stamping of interests (all coins have the same size).
That's exactly what my "Image Segmentation Tutorial" does. It finds coins.

Sign in to comment.

More Answers (0)

Asked:

on 22 Nov 2016

Commented:

on 28 Nov 2016

Community Treasure Hunt

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

Start Hunting!