# Fill regions of a map and keep the borders

7 views (last 30 days)
giannit on 5 May 2020
Answered: Ryan Comeau on 9 May 2020
My image is a white map of Italy with black (actually various shades of gray) borders which outline every province of the country. The objective is to fill some provinces with black. I read about the imfill function, but since it fills black regions with white colors, I manually edited the image so that every province is filled with black. In this way I can use imfill to fill the provinces with white. The following code fills two adiacent provinces:
BW = imbinarize(I,.2); % low threeshold otherwise white borders are erased
A = imfill(BW,[760 420]); % fill one province
imshow( imfill(A,[780 480]) ) % fill another adiacent province
otherwise, since the borders are white, when the provinces are filled with white, their borders vanish, see image below
Is there a way to fill the provinces while keeping the borders visible? Or, alternatively, a way to fill with black the provinces of the white map? (link for the white map https://i.imgur.com/v7g4J0n.png) Or a way to fill with a color different from black?
EDIT: I'm trying to superimpose the white map above the one obtained with the imfill function.

Image Analyst on 5 May 2020
The image didn't come through. Please upload a PNG format image with the green and blue frame icon.
giannit on 5 May 2020
giannit on 5 May 2020
I used imfuse on a transparent image containing only the borders, and on the image obtained with the imfill function. The result is not bad, but the background color is green:
I = imread('https://i.imgur.com/w6osODY.png'); % black map
BW = imbinarize(I,.2);
first_fill = imfill(BW,[760 420]);
second_fill = imfill(first_fill,[780 480]);
T = imread('https://i.imgur.com/nTIVhDG.png'); % transparent map with borders
imshow( imfuse(second_fill,T) )
EDIT: I read that [1,1,1] is the RGB triplet for white, but when running the command
imshow(imfuse(second_fill,T,'ColorChannels',[1 1 1]))
I get the error The value of 'ColorChannels' is invalid
EDIT2: this one seems to be good
imfuse(second_fill,T,'diff')

Ryan Comeau on 9 May 2020
Hello,
So, you'll need to change your regions to show up in white and the borders in black. This will permit us to "binarize" the image and place it into the regionprops algorithm. We will then grab the output form this and color each region the way you want it to be. Let's rock.
image=rescale(image,0,1); %this helps in binarization, you're image is binary alread ofcourse
BW_im=imbinarize(image); %different types of binarization, look up documentation.
jj=regionprops(BW_im,{'Centroid','PixelList'});
So this function will return the centroid coordinates of the region, so you know which regions you're in. It will return the locations of all pixel which are contained in the region as well. The process will be a bit ad hoc as you'll need to go through each region returned from regionprops, but this will only be like 8 for you and color each region how you want. Here is the code to color each region to your liking:
color_i_want=[2,3,4,5,6,7,8]; %whatever color you want in greyscale
for i=1:length(jj) %% this is counting each region
for j=1:length(jj(i).PixelList(:,:)) %this is counting pixels in each region
image(jj(i).PixelList(j,:))=color_i_want(i);%so if 8 bit grescale choose 0 to 255.
end
end
Or if you want to do a region by itself, you can just take the inner for loop and manually change each one cause you'll have its centroid. you can plot centroids over you image with the following code:
centroids=cat(1,jj.Centroid)%turns struct into matrix
imshow(BW_im)
hold on
plot(centroids(:,1),centroids(:,2),'b*')
hold off
Hope this helps,
RC

R2019b

### Community Treasure Hunt

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

Start Hunting!