LBP特征提取

重点有以下几个:

1.普通LBP所采用的邻域是一个3*3方格,可以用一个圆形区域来代替,但计算圆形区域上的点的像素值比较麻烦,需要用到双线性插值。

2.得到一个LBP值(一个8位值)后,考虑到旋转不变性,可以把这个值循环左移8次,求出8次中最小的值,并最终输出这个最小值。

3.考虑LBP的uniform pattern,即一个数用二进制表示后,若左移一位并亦或,各个位置上(除去最后一位)的1不超过2个,则可将其归为uniform pattern。否则归为另一类。考虑旋转不变性后类别总共有9类。建立类别的直方图统计。

4.实际编程时可以将图片分成8*8块小区域,然后分别建立每一小块的直方图,最后把64个直方图连起来作为这张图片的特征。

 

#include<iostream>
#include<cv.h>
#include<highgui.h>
#include<map>
using namespace std;
using namespace cv;



uchar calcLBP(Mat_<double>& image,int i, int j, int radius,int neighbor)
{
    double r;
    uchar v = 0;
    for (int n = 0; n < neighbor; n++)
    {
        double x = -radius*sin(2.0*CV_PI*n / neighbor);
        double y = radius*cos(2.0*CV_PI*n / neighbor);
        int fx = static_cast<int>(floor(x));//向下取整
        int fy = static_cast<int>(floor(y));
        int cx = static_cast<int>(ceil(x));//向上取整
        int cy = static_cast<int>(ceil(y));
        double ty = y - fy;
        double tx = x - fx;
        double w1 = (1 - tx)*(1 - ty);
        double w4 = tx*ty;
        double w2 = tx*(1 - ty);
        double w3 = (1 - tx)*ty;
        r = image(i + fx, j + fy)*w1 + image(i + fx, j + cy)*w2 + image(i + cx, j + fy)*w3 + image(i + cx, j + cy)*w4;
        v += (r >= image(i, j)) << n;
    }
        
    return v;
}

uchar shift_min(uchar v)
{
    uchar vmin = v;
    for (int k = 0; k < 8; k++)
    {
        uchar left = v << 1;
        uchar right = (v >> (8 - 1));
        v = left | right;
        vmin = min(v, vmin);
    }
    return vmin;
}

int calcHop(uchar v)
{
    int num = 0;
    uchar bits[8];
    for (int k = 0; k < 8; k++)
    {
        int t = v >> (8 - k - 1);
        bits[k] = t & 1;
    }
    for (int k = 0; k < 7; k++)
    {
        if (bits[k] ^ bits[k + 1] == 1)
            num++;
    }
    return num;
}

int main()
{
    Mat_<double> image = imread("E:\\COFW_Dataset\\trainingImages\\1.jpg", 0);
    int neighbors = 8;
    int radius = 16;
    int border = 20;
    int right = radius - image.cols%radius + border;
    int bottom = radius - image.rows%radius + border;
    copyMakeBorder(image, image, border, bottom, border, right, BORDER_REFLECT);
    int hop;
    map<int, int> imap;
    int num = 0;
    for (int i = 0; i < 256; i++)
    {
        int vmin = (int)shift_min((uchar)i);
        hop = calcHop(vmin);
        if (hop <= 2 && imap.find(vmin) == imap.end())
        {
            imap.insert(make_pair(vmin, num++));
        }
    }
    //vector<vector<int> > histogram(num, 0);
    Mat_<int> histogram(64, num);
    histogram.setTo(0);
    Mat_<uchar> result(image.rows - 2 * border, image.cols - 2 * border);
    int chuckwidth = (image.cols - 2 * border) / 8;
    int chuckheight = (image.rows - 2 * border) / 8;
    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
        {
            Mat_<double> tmp = image(Rect(border + chuckwidth*j, border + chuckheight*i, chuckwidth, chuckheight));
            copyMakeBorder(tmp, tmp, border, border, border, border, BORDER_REFLECT);
            int order = i * 8 + j;
            for (int k1 = 0; k1 < chuckheight; k1++)
            {
                for (int k2 = 0; k2 < chuckwidth; k2++)
                {
                    uchar val = shift_min(calcLBP(tmp, k1, k2, radius, neighbors));
                    if (imap.find(val) != imap.end())
                    {                        
                        histogram(order, imap[val])++;
                    }
                    else
                    {
                        histogram(order, 8)++;
                    }
                }
            }
            /*for (int i = border; i < image.rows - border; i++)
            {
                for (int j = border; j < image.cols - border; j++)
                {
                    result(i - 20, j - 20) = shift_min(calcLBP(image, i, j, radius, neighbors));
                    if (imap.find(result(i - 20, j - 20)) != imap.end())
                    {
                        histogram[imap[result(i - 20, j - 20)]]++;
                    }
                    else
                    {
                        histogram[8]++;
                    }
                }
            }*/
        }
    }
    histogram.reshape(0, 64 * num);

    imshow("1", result);
    
    waitKey(0);
    return 0;
}
View Code

 

posted @ 2016-11-23 11:08  vaevaevae  阅读(334)  评论(0)    收藏  举报