Bwlabel, randperm with constraints

I cannot clearly explain myself so I'll use the image attached. - I have a binary mask. I use bwlabel to visualize all the connected components. Since labels are from 1,....,N, if I use direct bwlabel output, I get colors varying smoothly. This is bad because I want to clearly show each component. - So I use randperm to shuffle labels. This gives me image.png as attached. However, randomized shuffles still hurt me sometimes if two labels are close (like 500,510 almost the same color). So I am trying to make sure the numbers in array 1,2,3,..,N get rearranged in a way that every number is as far away from any number that would be close to it as possible. Like 1,100,200,300,400,5,1000, etc. I described it badly here, but the idea is that simply two components that are close in the image should have very different colors, in order to maximize the visual discriminative power. How can I do this?

Answers (1)

bwlabel() does not display color, just return labels. You must have a different routine such as imshow() that is displaying the color.
The easiest way to proceed is not to randomize the entries at all, but to simply change your colormap so that adjacent entries are visually distinct.
But...
You can construct entries in the colormap to be as visually distinct as possible, such as using an order such as [0 0 0; 1 0 0; 0 1 0; 0 0 1; 1/2 0 0; 0 1/2 0; 0 0 1/2; 3/4 0 0; 0 3/4 0; 0 0 3/4; 1/4 0 0; 0 1/4 0; 0 0 1/4 ...] . Notice though that this construction of the earlier entries to be as distinct as possible from each other ends up forcing the later entries to get closer and closer. If you order the color entries on any one attribute such as hue or brightness, and proceed by choosing pairs where the attribute is low and the attribute is high (maximum possible discrimination between adjacent elements as you build it up) then as you get further on, the difference between the two pair members is going to get lower and lower.
I think you are going to need to redefine your requirements a bit.

4 Comments

I only want to have a easily distinguishable labeled image. I have no constraints on how to achieve that. Maybe I should say it like this: If we divide the image into wxh grid, I want grids to go from darker to lighter as you move to its center. If grid 1 is dark to light, neighboring/touching grids should have light to dark. That way, each subregion will be discernible and borders of grid won't have similar colors too.
I think that wouldn't work on an irregular grid like this. In fact, I shouldn't even call it a grid.
You could do it by using a graph coloring algorithm; https://en.wikipedia.org/wiki/Graph_coloring . You would represent the touching areas by vertices and edges, and do a vertex coloring; the 4 Color Map Theorem promises that on a flat plane that at most 4 different colors will be required.

Sign in to comment.

Categories

Asked:

on 6 May 2018

Commented:

on 11 May 2018

Community Treasure Hunt

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

Start Hunting!