This is my original image:
I've asked the user to crop it, converted it to grayscale and ran this line of code on it:
edgeImg = edge(grayImg,'canny',0.23);
This is the result:
I want to "cut out" everything the middle circle and the outside edge, essentially. I'm having a really hard time figuring out how to do this and honestly I'm at a loss.
I considered trying to fill in the area that I want to keep in the binary image, and then I could use it as a stamp, but I couldn't come up with a way that didn't fill in the middle circle as well.
Any ideas?
Thanks.
EDIT: This white area is what I want to keep:
I would suggest not to do edge detection in the first place, you are loosing valuable information related to color. You may try some clustering algorithm, like K-Means (including source code) or whatever else.
After clustering is done, you may keep pixels that are related to cluster(s) with the object. Desirable cluster(s) may be selected based on the object position in the image (including cropping of the image) and its color.
Code example of K-Means clustering for 2 clusters is below:
he = imread('D:\1.jpg');
imshow(he);
cform = makecform('srgb2lab');
lab_he = applycform(he,cform);
ab = double(lab_he(:,:,2:3));
nrows = size(ab,1);
ncols = size(ab,2);
ab = reshape(ab,nrows*ncols,2);
%One cluster for your object and one for background
nColors = 2;
[cluster_idx, cluster_center] = kmeans(ab,nColors,'distance','sqEuclidean', ...
'Replicates',2);
pixel_labels = reshape(cluster_idx,nrows,ncols);
segmented_images = cell(1,3);
rgb_label = repmat(pixel_labels,[1 1 3]);
for k = 1:nColors
color = he;
color(rgb_label ~= k) = 0;
segmented_images{k} = color;
end
%Show both clusters: object and non-object
imshow(segmented_images{1});
figure;
imshow(segmented_images{2});
The resulting segmentation is quite good:
Instead of using K-Means, you can simply use the color thresholder since you have so much color information. Then you can call the mask function automatically generated called createMask
and further post process your image there. The code is below. The best part of this method is that createMask
is reusable for any image, not just your own!
% Read Image
I = imread('r8ATB.jpg');
figure; imshow( I );
% Crop Image
C = I(75:490,40:460,:);
figure; imshow( C );
% Plot Noisy Mask
[BW,MK] = createMask( C );
figure; imshow( BW );
figure; imshow( BW );
% Fix Holes
imopen( ... );
This is the original image.
Cropped Image
Start threshold window.
Threshold Parameters
Created mask
Final Image
The createMask.m function that is automatically generated using my parameter is as follows.
function [BW,maskedRGBImage] = createMask(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
% minimum/maximum values for each channel of the colorspace were set in the
% App and result in a binary mask BW and a composite image maskedRGBImage,
% which shows the original RGB image values under the mask BW.
% Auto-generated by colorThresholder app on 23-Apr-2015
%------------------------------------------------------
% Convert RGB image to chosen color space
I = rgb2hsv(RGB);
% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.983;
channel1Max = 0.167;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 0.205;
channel2Max = 1.000;
% Define thresholds for channel 3 based on histogram settings
channel3Min = 0.341;
channel3Max = 1.000;
% Create mask based on chosen histogram thresholds
BW = ( (I(:,:,1) >= channel1Min) | (I(:,:,1) <= channel1Max) ) & ...
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) & ...
(I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
% Invert mask
BW = ~BW;
% 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;
You can then proceed to use imopen and imclose to clean up your mask. Then apply it to the image. My method requires tuning to get it perfect as per any method, but it will give you consistent results.
To obtain the complement of your image, all you need to do is invert the mask and apply it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With