jjzjj

c++ - 在 openCV 中计算并显示 LBP 直方图

coder 2024-02-25 原文

我想使用 LBP 和 SVM 创建一个实时情绪识别程序。经过面部检测过程后,我将捕获的图像转换为 32x32 像素的灰度图像。 我很难为我的 LBP 创建和显示直方图(我使用简单的、未插值的 LBP)。到目前为止,我得到的是实时显示生成的 LBP 图像。

Ahonen 等。 al 的论文指出

divide the LBP image into m local regions and extract a histogram from each (region)

我们如何确定 m 个局部区域的数量?

我一直在努力寻找答案 here , 和 here但我无法理解它。我在这里看到了 berak 关于空间直方图的工作,但我仍然感到困惑。有人可以逐步教我吗(是的,我是新手 :/)。我真的需要计算并显示直方图,如第 14 页所示 here .

也许我应该在这里展示我凌乱的代码。

// Libraries included
#include "opencv2/core/core.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>

// Namespace declaration
using namespace std;
using namespace cv;

// Function Headers
void detectAndDisplay(Mat frame);
Mat LBP(Mat img);

// Global variables
String face_cascade_name = "haarcascade_frontalface_alt.xml";
String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;


// Function main
int main(){
    // Start cvStartWindowThread to create a thread process. VERY IMPORTANT
    cvStartWindowThread();

    // Initializing local variables
    int k=1;
    CvCapture* capture;
    Mat frame;

    // Load the cascade, use ifs (if more than one xml files are used) to prevent segmentation fault
    if (!face_cascade.load(face_cascade_name)){
        printf("--(!)Error loading\n");
        return (-1);
    }
    if( !eyes_cascade.load( eyes_cascade_name ) ){
        printf("--(!)Error loading\n");
        return -1;
    };

    // Start the program, capture from CAM with CAMID =0    
    capture = cvCaptureFromCAM(0 );
    if( capture !=0){   
        while(k==1){
            frame = cvQueryFrame( capture );
            cv::flip(frame,frame,1);
            //-- 3. Apply the classifier to the frame
            if( !frame.empty() ){
                detectAndDisplay( frame );
            }
            else{
                printf(" --(!) No captured frame -- Break!");
                break;
            }
            int c = waitKey(1);
            if( (char)c == 'c' ) {
                k=0;
                destroyWindow("FYP Live Camera");
                break;
            }
        }
    }
    else{
        printf("CvCaptureFromCAM ERROR\n");
    }
    cvReleaseCapture(&capture);
    return 0;
}

// Function detectAndDisplay
void detectAndDisplay(Mat frame){
    std::vector<Rect> faces;
    std::vector<Rect> eyes;
    Mat frame_gray;
    Mat crop;
    Mat crop2;
    Mat res;
    Mat gray;
    Mat dst;
    string text;
    stringstream sstm;


    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
    equalizeHist(frame_gray, frame_gray);

    // Detect faces
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 4, 0 | CV_HAAR_FIND_BIGGEST_OBJECT, Size(60, 60));

    // Set Region of Interest
    cv::Rect roi_b;
    cv::Rect roi_c;

    size_t ic = 0; // ic is index of current element


    if (faces.size() !=0){
        for (ic = 0; ic < faces.size(); ic++) // Iterate through all current elements (detected faces)
        {
            roi_b.x = faces[ic].x;
            roi_b.y = faces[ic].y;
            roi_b.width = faces[ic].width;
            roi_b.height = faces[ic].height;

            crop = frame(roi_b);
            resize(crop, res, Size(256, 256), 0, 0, INTER_LINEAR); // This will be needed later while saving images

            cvtColor(res, gray, CV_BGR2GRAY); // Convert cropped image to Grayscale

            eyes_cascade.detectMultiScale(gray, eyes, 1.1, 4, 0 |CV_HAAR_SCALE_IMAGE, Size(15, 15) );
            if (eyes.size() == 2){
                if ( eyes[0].x <= eyes[1].x ){
                    roi_c.x = eyes[0].x*0.75;
                    roi_c.y = eyes[0].y*0.7;
                    roi_c.width = (eyes[1].x+65)-roi_c.x;
                    roi_c.height = 190;
                }
                else if ( eyes[0].x >= eyes[1].x ) {
                    roi_c.x = eyes[1].x*0.75;
                    roi_c.y = eyes[1].y*0.7;
                    roi_c.width = (eyes[0].x+65)-roi_c.x;
                    roi_c.height = 190;
                }
                crop2 = gray(roi_c);
                resize(crop2, crop2, Size(128, 128), 0, 0, INTER_LINEAR); // This will be needed later while saving images

                dst= LBP(crop2);

                Point centerEye1( eyes[0].x + eyes[0].width*0.5, eyes[0].y + eyes[0].height*0.5 );
                int radiusEye1 = cvRound( (eyes[0].width + eyes[0].height)*0.25 );
                circle( gray, centerEye1, radiusEye1, Scalar( 0, 0, 255 ), 1, 8, 0 );

                Point centerEye2( eyes[1].x + eyes[1].width*0.5, eyes[1].y + eyes[1].height*0.5 );
                int radiusEye2 = cvRound( (eyes[1].width + eyes[1].height)*0.25 );
                circle( gray, centerEye2, radiusEye2, Scalar( 0, 0, 255 ), 1, 8, 0 );

            }

            Point pt1(faces[ic].x, faces[ic].y); // Display detected faces on main window - live stream from camera
            Point pt2((faces[ic].x + faces[ic].height), (faces[ic].y + faces[ic].width));
            rectangle(frame, pt1, pt2, Scalar(0, 255, 0), 1, 8, 0);
            putText(frame, "Auto-focused", cvPoint((faces[ic].x+faces[ic].width/4), faces[ic].y-10), FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(0, 0, 255), 1, CV_AA);
        }

    }


    imshow("Live Camera", frame);
    if (!crop2.empty())
    {
        imshow("Gray2", dst);
        imshow("Gray3", crop2);
    }
    else{
        destroyWindow("Gray2");
        destroyWindow("Gray3");
    }   
}
Mat LBP(Mat img){
    Mat dst = Mat::zeros(img.rows-2, img.cols-2, CV_8UC1);
    for(int i=1;i<img.rows-1;i++) {
        for(int j=1;j<img.cols-1;j++) {
            uchar center = img.at<uchar>(i,j);
            unsigned char code = 0;
            code |= ((img.at<uchar>(i-1,j-1)) > center) << 7;
                code |= ((img.at<uchar>(i-1,j)) > center) << 6;
            code |= ((img.at<uchar>(i-1,j+1)) > center) << 5;
            code |= ((img.at<uchar>(i,j+1)) > center) << 4;
            code |= ((img.at<uchar>(i+1,j+1)) > center) << 3;
            code |= ((img.at<uchar>(i+1,j)) > center) << 2;
            code |= ((img.at<uchar>(i+1,j-1)) > center) << 1;
            code |= ((img.at<uchar>(i,j-1)) > center) << 0;
            dst.at<uchar>(i-1,j-1) = code;
        }
    }
    return dst;
}

显然我无法发布我的屏幕截图,因为我没有足够的信誉点:(

最佳答案

嗯,首先,您要计算的只是 LBP 模式,而不是直方图 - 您需要为此创建一个 bin 数组并生成 LBP 特征的直方图。 在 bytefish 的代码中,如果您查看 github,您还会找到用于生成具有 59 个 bin 的直方图的代码。

关于c++ - 在 openCV 中计算并显示 LBP 直方图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23752507/

有关c++ - 在 openCV 中计算并显示 LBP 直方图的更多相关文章

  1. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby-on-rails - 使用 Sublime Text 3 突出显示 HTML 背景语法中的 ERB? - 2

    所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择

  5. ruby-on-rails - link_to 不显示任何 rails - 2

    我试图在索引页中创建一个超链接,但它没有显示,也没有给出任何错误。这是我的index.html.erb代码。ListingarticlesTitleTextssss我检查了我的路线,我认为它们也没有问题。PrefixVerbURIPatternController#Actionwelcome_indexGET/welcome/index(.:format)welcome#indexarticlesGET/articles(.:format)articles#indexPOST/articles(.:format)articles#createnew_articleGET/article

  6. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  7. ruby-on-rails - 复数 for fields_for has_many 关联未显示在 View 中 - 2

    目前,Itembelongs_toCompany和has_manyItemVariants。我正在尝试使用嵌套的fields_for通过Item表单添加ItemVariant字段,但是使用:item_variants不显示该表单。只有当我使用单数时才会显示。我检查了我的关联,它们似乎是正确的,这可能与嵌套在公司下的项目有关,还是我遗漏了其他东西?提前致谢。注意:下面的代码片段中省略了不相关的代码。编辑:不知道这是否相关,但我正在使用CanCan进行身份验证。routes.rbresources:companiesdoresources:itemsenditem.rbclassItemi

  8. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  9. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  10. ruby-on-rails - 在 Flash 警报 Rails 3 中显示错误消息 - 2

    如果我在模型中设置验证消息validates:name,:presence=>{:message=>'Thenamecantbeblank.'}我如何让该消息显示在闪光警报中,这是我迄今为止尝试过的方法defcreate@message=Message.new(params[:message])if@message.valid?ContactMailer.send_mail(@message).deliverredirect_to(root_path,:notice=>"Thanksforyourmessage,Iwillbeintouchsoon")elseflash[:error]

随机推荐