0

In the following image, I have filled two regions with two different shades:

enter image description here

How can I fill the remaining part of the image (parts not filled) with the pixel values 0 (black) in MATLAB?

Thanks.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
Simplicity
  • 47,404
  • 98
  • 256
  • 385
  • 2
    What method did you use to fill the regions? It would be easier to determine the locations of the regions at that stage, and then create a new image with a black background containing only those regions. – nkjt Aug 22 '13 at 11:19
  • Also, what do you mean by "colour"? The image is grayscale after all... – Buck Thorn Aug 22 '13 at 11:31
  • @Try Hard. Let's say `shades`. I have changed that in my question. But, want to fill the ramaining part of the image with `black` – Simplicity Aug 22 '13 at 11:32

4 Answers4

2

Assuming this is a follow on from this question, when you take your roi, instead of or in addition to using it to create the image above, you can use it to make an image with a black background. This avoids any issues with having the same values elsewhere in the image (credit to Bee's answer from the previous question):

img = im2double(imread('cameraman.tif'));
imshow(img);
roi = imfreehand(gca);

img2 = img;
img3 = zeros(size(img));

img2(roi.createMask) = val_1;
img3(roi.createMask) = val_1;
% and repeat to add additional roi

Alternatively, you can store the regions as individual BW masks, if you want to use them again later:

imshow(img);

% create masks
roi = imfreehand(gca);
BW = roi.createMask;
roi2 = imfreehand(gca);
BW2 = roi.createMask;

% original image + roi
img2 = img;
img2(BW) = val_1;
img2(BW2) = val_2;

% B&W image 
img3 = BW*val_1+BW2*val_2;
Community
  • 1
  • 1
nkjt
  • 7,825
  • 9
  • 22
  • 28
  • Thanks for your reply. I have written the code as shown in this link here: http://pastebin.com/Ebjwd724. When I use the code, I'm able to select two regions, but only the region selected first shows filled, and everything else is black. What could the reason be? – Simplicity Aug 22 '13 at 14:35
  • 1
    1. You have a typo, I presume line 14 should be `img5(roi2.createMask) = 200;` 2. If you want to put both roi into one image, when you create the second roi reuse the previous images - e.g. `img3(roi2.createMask) = 200;`. Also, this is assuming that your regions do not overlap. – nkjt Aug 22 '13 at 15:49
  • Nice points. Thanks a lot. This is the final version of the program: http://pastebin.com/JxJvkBni – Simplicity Aug 22 '13 at 18:31
1

Try this to pick points in the two gray shapes and black out all else.

img = imread(myimagefilename);
imshow(img);

% you can skip the following part and set clr1 and clr2 manually 
% if you already know the grayscale values in the patches

pts=ginput(2);  % <-- pick points within the regions you colored in

clr1=img(pts(1,2),pts(1,1));
clr2=img(pts(2,2),pts(2,1));

img2=img;
img2(find(img~=clr1 & img~=clr2)) = 0;

img2=im2bw(img2,0.2);  % <-- 0.2 is the threshold

[xxx idx1]= bwfill(~img2,pts(1,1),pts(1,2),8);
[xxx idx2]= bwfill(~img2,pts(2,1),pts(2,2),8);
idx=setxor(union(idx1,idx2),[1:numel(img)]);

img2 = img;
img2(idx)=0;
imshow(img2)

Feels overly complicated but it works. It uses two steps, first a coarse "filter" and then a more thorough removal using a mask generated by converting the initially filtered image to B&W (which requires a threshold) and then a fill operation to identify pixels within the patches.

Buck Thorn
  • 5,024
  • 2
  • 17
  • 27
  • Would this not give a lot of *noise* points as well? The regions need not have shades which are distinct from the rest of the image. – Roney Michael Aug 22 '13 at 10:48
  • @RoneyMichael You're right, I went for a really quick and dirty solution. I will have to change it to remove the leftovers. – Buck Thorn Aug 22 '13 at 10:49
1

Assuming that the values of the pixel values of the two regions are known as val_1 and val_2, you could do something like so:

Algorithm

  1. Get two images, one with everything except val_1 set to 0, the other doing the same with val_2. This will most likely contain a lot of noise points as well.
  2. Erode the two images with masks of appropriate threshold size. This eliminates the points of that value not in the region.
  3. Grow the high regions of the resulting image to the connected component in the original image.
  4. Change the shade of the high regions in the respective images as necessary and add them to get the resultant image.

If the shades are not known beforehand, you could use ginput as illustrated @TryHard's answer.

Roney Michael
  • 3,964
  • 5
  • 30
  • 45
  • Thanks for your reply. For instance, I have `val_1=100`. The case is that when I want to select all the pixels with `val_1`, I have such values also **outside** that region. So, pixels outside the region will also be selected. What should I do in this case? – Simplicity Aug 22 '13 at 11:15
  • Yeah. that was my concern too. When you erode with a mask of appropriate size, those *noise* points should go away. This can easily be done using the image processing toolbox. – Roney Michael Aug 22 '13 at 13:06
1

You may use the Simple single-seeded region growing function (or one of its equivalent) from matlab file exchange (below or download). This function will create a logical mask you can use to blacken your image (successive calls to this function for multiple regions)

I = im2double(imread('5Yo8l.png'));  
J = segCroissRegion(0.01,I,0,0)  

imshow(I+J);  



function Phi = segCroissRegion(tolerance,Igray,x,y)  

    if(x == 0 || y == 0)    
        imshow(Igray);    
        [y,x] = ginput(1);    %%% beware of the (x,y) mix-up here
    end    
    Phi = false(size(Igray,1),size(Igray,2));    
    ref = true(size(Igray,1),size(Igray,2));    
    PhiOld = Phi;    
    Phi(uint8(x),uint8(y)) = 1;    
    while(sum(Phi(:)) ~= sum(PhiOld(:)))    
        PhiOld = Phi;    
        segm_val = Igray(Phi);    
        meanSeg = mean(segm_val);    
        posVoisinsPhi = imdilate(Phi,strel('disk',1,0)) - Phi;    
        voisins = find(posVoisinsPhi);    
        valeursVoisins = Igray(voisins);    
        Phi(voisins(valeursVoisins > meanSeg - tolerance & valeursVoisins < meanSeg + tolerance)) = 1;    
    end    
marsei
  • 7,691
  • 3
  • 32
  • 41