1 | initial version |
... so, i had to give it a try..
//
// reference impl, walking over pixels.
//
struct lbp_pix
{
void operator()( const Mat &z, Mat & h ) const
{ PROFILEX("lbp_pix");
h = Mat::zeros(1,256,CV_32F);
Mat_<uchar> fI(z.size());
Mat_<uchar> img(z);
const int m=1;
for ( int r=m; r<z.rows-m; r++ )
{
for ( int c=m; c<z.cols-m; c++ )
{
uchar v = 0;
uchar cen = img(r,c);
v |= (img(r-1,c ) > cen) << 0;
v |= (img(r-1,c+1) > cen) << 1;
v |= (img(r ,c+1) > cen) << 2;
v |= (img(r+1,c+1) > cen) << 3;
v |= (img(r+1,c ) > cen) << 4;
v |= (img(r+1,c-1) > cen) << 5;
v |= (img(r ,c-1) > cen) << 6;
v |= (img(r-1,c-1) > cen) << 7;
fI(r,c) = v;
}
}
hist(fI,h,256,GRID,GRID);
}
};
//
// here be matlab dragons.
//
// pitfalls:
// * since a Matop in opencv like A>B results in a Mat filled with [0xff or 0], (not [0 or 1]),
// we have to use & and | instead of * and +
//
//
#define SHIFTED_MATS_3x3 \
int M = I.rows; \
int N = I.cols; \
Mat I7 = I(Range(1,M-2), Range(1,N-2));\
Mat I6 = I(Range(1,M-2), Range(2,N-1));\
Mat I5 = I(Range(1,M-2), Range(3,N ));\
Mat I4 = I(Range(2,M-1), Range(3,N ));\
Mat I3 = I(Range(3,M ), Range(3,N ));\
Mat I2 = I(Range(3,M ), Range(2,N-1));\
Mat I1 = I(Range(3,M ), Range(1,N-2));\
Mat I0 = I(Range(2,M-1), Range(1,N-2));\
Mat Ic = I(Range(2,M-1), Range(2,N-1));\
struct LBP_3x3
{
void operator()( const Mat &I, Mat & h ) const
{ PROFILEX("LBP");
SHIFTED_MATS_3x3;
Mat fI = ((I7>Ic)&128) |
((I6>Ic)&64) |
((I5>Ic)&32) |
((I4>Ic)&16) |
((I3>Ic)&8) |
((I2>Ic)&4) |
((I1>Ic)&2) |
((I0>Ic)&1);
hist(fI,h,256,GRID,GRID);
}
};
struct LQP_3x3
{
int kerP1;
int kerP2;
LQP_3x3(int k1=5,int k2=5) : kerP1(k1), kerP2(k2) {}
void operator()( const Mat &I, Mat & h ) const
{ PROFILEX("LQP");
Mat fI_2,fI_1,fI1,fI2;
SHIFTED_MATS_3x3;
Mat Icplus1 = Ic+kerP1;
Mat Icplus2 = Ic+kerP2;
Mat Icminus1 = Ic-kerP1;
Mat Icminus2 = Ic-kerP2;
fI_2 = ((I7<Icminus2)&128 ) |
((I6<Icminus2)& 64 ) |
((I5<Icminus2)& 32 ) |
((I4<Icminus2)& 16 ) |
((I3<Icminus2)& 8 ) |
((I2<Icminus2)& 4 ) |
((I1<Icminus2)& 2 ) |
((I0<Icminus2)& 1 );
fI_1 = (((I7>=Icminus2) &(I7<Icminus1))&128 ) |
(((I6>=Icminus2) &(I6<Icminus1))& 64 ) |
(((I5>=Icminus2) &(I5<Icminus1))& 32 ) |
(((I4>=Icminus2) &(I4<Icminus1))& 16 ) |
(((I3>=Icminus2) &(I3<Icminus1))& 8 ) |
(((I2>=Icminus2) &(I2<Icminus1))& 4 ) |
(((I1>=Icminus2) &(I1<Icminus1))& 2 ) |
(((I0>=Icminus2) &(I0<Icminus1))& 1 );
fI1 = (((I7>=Icplus1) &(I7<Icplus2))&128 ) |
(((I6>=Icplus1) &(I6<Icplus2))& 64 ) |
(((I5>=Icplus1) &(I5<Icplus2))& 32 ) |
(((I4>=Icplus1) &(I4<Icplus2))& 16 ) |
(((I3>=Icplus1) &(I3<Icplus2))& 8 ) |
(((I2>=Icplus1) &(I2<Icplus2))& 4 ) |
(((I1>=Icplus1) &(I1<Icplus2))& 2 ) |
(((I0>=Icplus1) &(I0<Icplus2))& 1 );
fI2 = ((I7>=Icplus2)&128 ) |
((I6>=Icplus2)& 64 ) |
((I5>=Icplus2)& 32 ) |
((I4>=Icplus2)& 16 ) |
((I3>=Icplus2)& 8 ) |
((I2>=Icplus2)& 4 ) |
((I1>=Icplus2)& 2 ) |
((I0>=Icplus2)& 1 );
Mat h1,h2,h3,h4;
hist(fI_2,h1,256,GRID,GRID);
hist(fI_1,h2,256,GRID,GRID);
hist(fI1, h3,256,GRID,GRID);
hist(fI2, h4,256,GRID,GRID);
h.push_back(h1);
h.push_back(h2);
h.push_back(h3);
h.push_back(h4);
h = h.reshape(1,1);
}
};
a 1000 iterations over a 120x120 pix:
lbp1 0.3950 256
lbp2 0.5835 256
LTP 1.3512 512
LQP 3.4761 1024
RT 0.3751 9
BGC1 0.5785 256