Jose Ramon - 1 year ago 148
C++ Question

# Uniform histogram implementation in c++

I using the code of bytefish in order to calculate Local Binary Patterns (LBP) spatial uniform histograms for an image. I am using the the spatial_histogram function which calculates the histogram of local patches of image. Every calculated patch has size 256 so the final Mat hist file size is 1x(n*256). What I am trying to understand is how can I convert that histogram implementation to uniform histogram implementation. Implemented histogram code is the following:

``````void lbp::histogram_(const Mat& src, Mat& hist, int numPatterns) {
hist = Mat::zeros(1, numPatterns, CV_32SC1);
for(int i = 0; i < src.rows; i++) {
for(int j = 0; j < src.cols; j++) {
int bin = src.at<_Tp>(i,j);
hist.at<int>(0,bin) += 1;
}
}
``````

Uniform process is based on the following paper ( for local binary patterns) here.
A local binary pattern is called uniform if the binary pattern contains at most two bitwise transitions from 0 to 1 or vice versa when the bit pattern is considered circular.

[edit2] color reduction

• that is easy it is just recoloring by the table `uniform[256]` has nothing to do with uniform histograms !!!

1. create translation(recoloring) table for each possible color

• for 8-bit gray-scale it is 256 colors
• for example

``````BYTE table[256] = {
0,1,2,3,4,58,5,6,7,58,58,58,8,58,9,10,11,58,58,58,58,58,58,58,12,58,58,58,13,58,
14,15,16,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,17,58,58,58,58,58,58,58,18,
58,58,58,19,58,20,21,22,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,
58,58,58,58,58,58,58,58,58,58,58,58,23,58,58,58,58,58,58,58,58,58,58,58,58,58,
58,58,24,58,58,58,58,58,58,58,25,58,58,58,26,58,27,28,29,30,58,31,58,58,58,32,58,
58,58,58,58,58,58,33,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,34,58,58,58,58,
58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,
58,35,36,37,58,38,58,58,58,39,58,58,58,58,58,58,58,40,58,58,58,58,58,58,58,58,58,
58,58,58,58,58,58,41,42,43,58,44,58,58,58,45,58,58,58,58,58,58,58,46,47,48,58,49,
58,58,58,50,51,52,58,53,54,55,56,57 };
``````
• you can also compute it programaticaly like `table[i]=(58*i)/255;` for linear distribution

• but I suggest it is more like this:

recolor based on histogram example

``````//hist[256] - already computed classic histogram
//table[59] - wanted recolor table
void compute_table(int *table,int *hist)
{
int i,c,threshold=1;
for (c=-1,i=0;i<256;i++)
if (hist[i]>threshold) { c++; table[i]=c; }
else table[i]=58;
}
``````
• set the threshold by area size or color count or whatever ...

2. recolor color

• `color_59=table[color_256];`
• either recolor source image
• or just change color value before used in histogram computation

That is all.

[edit1] LBP

• I do not think is a good idea to compute histogram for LBP at all
1. I would compute `min` and `max` color for sub image region you work with
2. then convert colors to binary
• `if (color>=(max+min)/2) color=1; else color=0;`
3. now shift or them to form the LBP vector
• 4x4 LBP example:
• `LBP =color[0][0];`
• `LBP<<=1; LBP|=color[0][1];`
• `LBP<<=1; LBP|=color[0][2];`
• ...
• `LBP<<=1; LBP|=color[3][3];`
• you can do the step 3 directly in step 2

Histogram is the probability/occurrence/count of distinct color(shade)

• uniform histogram means that each colors have almost the same count/area in the whole image
• by bins I assume you mean distinct colors not the sub-images

To combine sub-histogram

• or use single hist array init it once and then just sum to it as you have something like:

``````??? hist=Mat::zeros(1, numPatterns, CV_32SC1);

void lbp::histogram_(const Mat& src, Mat& hist, int numPatterns, bool init) {
if (init) hist = Mat::zeros(1, numPatterns, CV_32SC1);
for(int i = 0; i < src.rows; i++) {
for(int j = 0; j < src.cols; j++) {
int bin = src.at<_Tp>(i,j);
hist.at<int>(0,bin) += 1;
}
}
``````
• set init to true for the first patch call and false for all the rest

• numPatterns is the max used color+1 or max possible colors count (not the distinct colors count)

If you want save only used colors

• then you need to remember also the color;
• `int hist[][2],hists=0;` or use some dynamic list template for that
• the hist computation will change (will be much slower)

1. take color
2. test if it is in `hist[i][0]==color`
• if yes increment its counter `hist[i][1]++;`
• if not add new color `hist[hists][0]=color; hist[hists][1]=1; hists++;`
• this will save space only if used colors are less then half of the possible ones

• to improve performance you can compute hist normally
• and recompute to this list after that in the same maner (instead of the increment part of coarse)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download