与已知图像匹配的局部二进制模式

Posted

技术标签:

【中文标题】与已知图像匹配的局部二进制模式【英文标题】:Local Binary Patterns Matched with Known Image 【发布时间】:2015-10-20 14:10:23 【问题描述】:

我目前正在寻找一种使用 OpenCV 和 C++ 实现本地二进制模式的方法。

目前我发现了这个:https://github.com/bytefish/opencv/tree/master/lbp

但是,我需要将 2 个图像或 LBP 直方图相互比较并给出一些相似度指数。

这是我修改后的代码:

    #include <opencv/cv.h>
#include <opencv/highgui.h>
#include "lbp.hpp"
#include "histogram.hpp"

using namespace cv;

int main(int argc, const char *argv[]) 
    int deviceId = 0;
    if(argc > 1)
        deviceId = atoi(argv[1]);

    VideoCapture cap(deviceId);

    if(!cap.isOpened()) 
        cerr << "Capture Device ID " << deviceId << "cannot be opened." << endl;
        return -1;
    

    // initial values
    int radius = 1;
    int neighbors = 8;

    // windows
    namedWindow("original",CV_WINDOW_AUTOSIZE);
    namedWindow("lbp",CV_WINDOW_AUTOSIZE);

    // matrices used
    Mat test;
    Mat test1;
    Mat frame; // always references the last frame
    Mat dst; // image after preprocessing
    Mat dst1;
    Mat lbp; // lbp image
    Mat lbp1;

    // just to switch between possible lbp operators
    vector<string> lbp_names;
    lbp_names.push_back("Extended LBP"); // 0
    lbp_names.push_back("Fixed Sampling LBP"); // 1
    lbp_names.push_back("Variance-based LBP"); // 2
    int lbp_operator=1;

    bool running=true;
    while(running) 
        //cap >> frame;
        dst = imread("Coin1.jpg", CV_LOAD_IMAGE_GRAYSCALE); //Known Image
        dst1 = imread("Coin2.jpg", CV_LOAD_IMAGE_GRAYSCALE); //Compared to

        switch(lbp_operator) 
        case 0:
            lbp::ELBP(test, lbp, radius, neighbors); // use the extended operator
            break;
        case 1:
            lbp::OLBP(dst, lbp); // use the original operator
            lbp::OLBP(dst1, lbp1); // use the original operator
            break;
        case 2:
            lbp::VARLBP(dst, lbp, radius, neighbors);
            break;
        
        // now to show the patterns a normalization is necessary
        // a simple min-max norm will do the job...
        normalize(lbp, lbp, 0, 255, NORM_MINMAX, CV_8UC1);

        Mat lbp_hist, lbp1_hist;
        int histSize[] = 256;
        float s_ranges[] =  0, 256 ;
        const float* ranges[] =  s_ranges ;

    // Use the o-th and 1-st channels
    int channels[] =  0 ;

        calcHist( &lbp, 1, channels, Mat(), lbp_hist, 1, histSize, ranges, true, false );
        normalize( lbp1_hist, lbp1_hist, 0, 1, NORM_MINMAX, -1, Mat() );

        calcHist( &lbp1, 1, channels, Mat(), lbp1_hist, 1, histSize, ranges, true, false );
        normalize( lbp_hist, lbp_hist, 0, 1, NORM_MINMAX, -1, Mat() );

        double base_base = compareHist( lbp_hist, lbp1_hist, 0 );
        printf("%f\n",base_base); //get a similarity

        //imshow("original", lbp);
        //imshow("lbp", lbp1);
        imshow("1", lbp_hist);
        imshow("2", lbp1_hist);

        char key = (char) waitKey(0);;

    
        return 0; // success

但是我认为它不能正常工作。我没有得到准确的直方图。所以我无法比较。

请帮忙。

【问题讨论】:

【参考方案1】:

我记得在开始使用 OpenCV LBPH 时遇到过类似的问题

试试这个函数的直方图

void lbp::histogram(const Mat& src, Mat& hist, int numPatterns) 
switch(src.type()) 
    case CV_8SC1: histogram_<char>(src, hist, numPatterns); break;
    case CV_8UC1: histogram_<unsigned char>(src, hist, numPatterns); break;
    case CV_16SC1: histogram_<short int>(src, hist, numPatterns); break;
    case CV_16UC1: histogram_<unsigned short>(src, hist, numPatterns); break;
    case CV_32SC1: histogram_<int>(src, hist, numPatterns); break;
    



template <typename _Tp>
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;
        
    
 

//Manual normalization 
cv::Mat hist_norm=cv::Mat::zeros(1,hist.cols,CV_32F);
int sum=0;
for(int j=0;j<hist.cols;j++)sum+=hist.at<int>(0,j);
for(int j=0;j<hist.cols;j++)hist_norm.at<float>(0,j)+= (float)hist.at<int>(0,j)/(float)sum;

这适用于我的计算机上的基本 LBPH。我使用了另一个库中的 LBP 实现,可能和你一样。 告诉我它是否适合你。

【讨论】:

我厌倦了使用 lbp::histogram(lbp, lbp_hist, 2);但最终得到了一个类似的小直方图 你的意思是直方图的大小是 256x1 吗?这很正常。

以上是关于与已知图像匹配的局部二进制模式的主要内容,如果未能解决你的问题,请参考以下文章

图像识别基于模板匹配实现扑克牌识别matlab源码

图像识别基于模板匹配之手写英文字母识别matlab源码

人脸识别基于模板匹配算法实现人脸识别matlab源码

车位识别基于matlab模板匹配车位识别含Matlab源码244期

身份牌识别基于matlab GUI模板匹配身份牌识别含Matlab源码 1354期

身份牌识别基于matlab GUI模板匹配身份牌识别含Matlab源码 1354期