Eliminating different backgrounds from an image and object segmentation?
Let's say I have this input image with any number of boxes. I want to segment these fields, so I can eventually extract them. input image:
The background can be continuous, like a painted wall, a wooden table, a carpet. My idea was that the gradient would be the same in the background and with a constant gradient. I could rotate, where the gradient is about the same, to zero in the image.
With edge detection, I expanded and filled in the areas where edges were detected. Basically my goal is to blob the areas where the boxes are. With blobs, I would know exactly the location of the boxes, thus being able to cut boxes from the input image. So in this case, I have to have four blobs, and then I could cut four images from the input image.
This is how far I got it: the segmented image:
query = imread('AllFour.jpg'); gray = rgb2gray(query); [~, threshold] = edge(gray, 'sobel'); weightedFactor = 1.5; BWs = edge(gray,'roberts'); %figure, imshow(BWs), title('binary gradient mask'); se90 = strel('disk', 30); se0 = strel('square', 3); BWsdil = imdilate(BWs, [se90]); %figure, imshow(BWsdil), title('dilated gradient mask'); BWdfill = imfill(BWsdil, 'holes'); figure, imshow(BWdfill); title('binary image with filled holes');
source to share
What a very interesting problem! Here's my solution in an attempt to resolve this issue for you. The background is assumed to have the same color distribution. First convert the image from RGB to HSV color space with rgb2hsv
. The HSV color space is the ideal conversion for color analysis. After that, I would look at the saturation and value planes. Saturation is related to how "pure" a color is, and value is the intensity or brightness of the color itself. If you look at the saturation planes and values ββfor the image, this is shown:
im = imread('http://i.stack.imgur.com/1SGVm.jpg');
out = rgb2hsv(im);
figure;
subplot(2,1,1);
imshow(out(:,:,2));
subplot(2,1,2);
imshow(out(:,:,3));
This is what I get:
Looking at some places on the gray background, it looks like most of the saturation is less than 0.2, and elements in the value plane are greater than 0.3. Thus, we want to find opposite of these pixels to get our objects. Thus, we find those pixels whose saturation is greater than 0.2 or , these pixels with a value that is less than 0.3:
seg = out(:,:,2) > 0.2 | out(:,:,3) < 0.3;
This is what we get:
Almost there! There are a few spurious single pixels, so I'm going to do an opening with a imopen
line out.
After that I will expand with with imdilate
to close any gaps, then use imfill
with the option 'holes'
to fill in the gaps, then erode with imerode
to shrink the shapes to their original shape. Thus:
se = strel('line', 3, 90); pre = imopen(seg, c); se = strel('square', 20); pre2 = imdilate(pre, se); pre3 = imfill(pre2, 'holes'); final = imerode(pre3, se); figure; imshow(final);
final
contains a segmented image with 4 candy boxes. This is what I get:
source to share
Try resizing the image. When you make it smaller, it would be easier to merge the edges. I tried what is shown below. You may need to adjust it depending on the nature of the background.
close all; clear all; im = imread('1SGVm.jpg'); small = imresize(im, .25); % resize grad = (double(imdilate(small, ones(3))) - double(small)); % extract edges gradSum = sum(grad, 3); bw = edge(gradSum, 'Canny'); joined = imdilate(bw, ones(3)); % join edges filled = imfill(joined, 'holes'); filled = imerode(filled, ones(3)); imshow(label2rgb(bwlabel(filled))) % label the regions and show
source to share
If you have the latest version of MATLAB installed, try the Color Thresholder app in the imaging toolbar. It allows you to interactively play different color spaces to see which one can give you the best segmentation.
source to share
If your candies are fixed coated or you know all the coatings that appear in the scene, then Pattern Matching is best . Since it doesn't depend on the background in the image.
http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html
source to share