2

I have an Image histogram using imhist and it contains 3 different regions like the attached image shows, I want to get the borders or the interval of the largest continuous area of the histogram, in this case, the second region is the one that I am looking for and the borders would be 43 and 225

the image histogram

Thomas Fritsch
  • 9,639
  • 33
  • 37
  • 49
K.soula
  • 45
  • 4

2 Answers2

1

You can find the begin and end bins for each region like this

[counts,binLocations] = imhist(I);
der = diff([false; counts>0; false]);
upedge = find(der == 1);
downedge = find(der == -1) - 1;
regions = [binLocations(upedge) binLocations(downedge)];

If the values are not exactly zero, but very close to zero then you can replace 0 with some threshold value in the above code.

Example

im = uint8(zeros(300,400));
im(1:100,:) = uint8(randi([0,40],[100,400]));
im(101:200,:) = uint8(randi([90,100],[100,400]));
im(201:300,:) = uint8(randi([140,240],[100,400]));

[counts,binLocations] = imhist(im);
der = diff([false; counts>0; false]);
upedge = find(der == 1);
downedge = find(der == -1) - 1;
regions = [binLocations(upedge) binLocations(downedge)];

results in

regions =

     0    40
    90   100
   140   240
jodag
  • 19,885
  • 5
  • 47
  • 66
  • Thank you so much for your answer but it gives me 0 and 255 because, in fact, the histogram has 3 regions the first one is for binLocations=0 the second one where binLocations are between 43 and 225 and it is the one that I am looking for and the third one is when the binLocations=255 – K.soula Aug 10 '17 at 17:32
  • Modified answer. Will work for regions width width 1 like the 0 and 255 you describe. Will also split into more regions if there are more regions. – jodag Aug 10 '17 at 17:52
  • why not just using `find(count > (thres + 10*eps(thres)), 'last')` ? – Yvon Aug 10 '17 at 18:00
  • 1
    @Yvon Because that only finds the end of the last region. I'm assuming you meant `find(count > (thres + 10*eps(thres)), 1, 'last')` – jodag Aug 10 '17 at 18:09
0

I will use the answer to this question to find regions of consecutive non zero elements in an array.

lets assume we have this array (histogram):

h = [0,0,0,1,2,3,44,77,5,656,0,0,0,0,0,0,2,99,7,34];

now we want to know were each region of consecutive non-zero elements starts and ends, in this example we want

startIndex = [4,17]
endIndex   = [10,20]
lengths    = [7,4]

to get this result we use the code from the question as follows:

dsig = diff([1,h(:)'==0,1]);
startIndex = find(dsig < 0);
endIndex = find(dsig > 0)-1;
duration = endIndex-startIndex+1;

and to get longest region use:

[~,maxLengthIndex] = max(lengths);
maxStartIndex = startIndex(maxLengthIndex);
maxEndIndex = endIndex(maxLengthIndex);
DontCareBear
  • 825
  • 2
  • 11
  • 25