• OpenCV——LBP(Local Binary Patterns)特征检测


     1 #include <opencv2/opencv.hpp>
     2 #include <iostream>
     3 #include "math.h"
     4 
     5 using namespace cv;
     6 using namespace std;
     7 
     8 Mat src, gray_src;
     9 
    10 const char* output_tt = "LBP Result";
    11 
    12 int main(int argc, char** argv) {
    13     src = imread("test.jpg");
    14     if (src.empty()) {
    15         printf("could not load image...
    ");
    16         return -1;
    17     }
    18     
    19     namedWindow("input image", CV_WINDOW_AUTOSIZE);
    20     namedWindow(output_tt, CV_WINDOW_AUTOSIZE);
    21     imshow("input image", src);
    22 
    23     // convert to gray
    24     cvtColor(src, gray_src, COLOR_BGR2GRAY);
    25     int width = gray_src.cols;
    26     int height = gray_src.rows;
    27 
    28     // 基本LBP演示
    29     Mat lbpImage = Mat::zeros(gray_src.rows - 2, gray_src.cols - 2, CV_8UC1);//3*3窗口,边界有左右各1个像素不处理
    30     for (int row = 1; row < height - 1; row++) {
    31         for (int col = 1; col < width - 1; col++) {
    32             uchar c = gray_src.at<uchar>(row, col);//获取中心像素值
    33             uchar code = 0;//特征码
    34             code |= (gray_src.at<uchar>(row - 1, col - 1) > c) << 7;
    35             code |= (gray_src.at<uchar>(row - 1, col) > c) << 6;
    36             code |= (gray_src.at<uchar>(row - 1, col + 1) > c) << 5;
    37             code |= (gray_src.at<uchar>(row, col + 1) > c) << 4;
    38             code |= (gray_src.at<uchar>(row + 1, col + 1) > c) << 3;
    39             code |= (gray_src.at<uchar>(row + 1, col) > c) << 2;
    40             code |= (gray_src.at<uchar>(row + 1, col - 1) > c) << 1;
    41             code |= (gray_src.at<uchar>(row, col - 1) > c) << 0;
    42             lbpImage.at<uchar>(row - 1, col - 1) = code;//原图1,1=效果图0,0
    43         }
    44     }
    45     imshow(output_tt, lbpImage);
    46 
    47     waitKey(0);
    48     return 0;
    49 }

    LBP的扩展(多尺度表达):

     1 #include <opencv2/opencv.hpp>
     2 #include <iostream>
     3 #include "math.h"
     4 
     5 using namespace cv;
     6 using namespace std;
     7 
     8 Mat src, gray_src;
     9 int current_radius = 3;
    10 int max_count = 10;
    11 
    12 const char* output_tt = "LBP Result";
    13 
    14 void ELBP_Demo(int, void*);
    15 int main(int argc, char** argv) {
    16     src = imread("test.jpg");
    17     if (src.empty()) {
    18         printf("could not load image...
    ");
    19         return -1;
    20     }
    21     
    22     namedWindow("input image", CV_WINDOW_AUTOSIZE);
    23     namedWindow(output_tt, CV_WINDOW_AUTOSIZE);
    24     imshow("input image", src);
    25 
    26     // convert to gray
    27     cvtColor(src, gray_src, COLOR_BGR2GRAY);
    28     int width = gray_src.cols;
    29     int height = gray_src.rows;
    30 
    31     // 基本LBP演示
    32     Mat lbpImage = Mat::zeros(gray_src.rows - 2, gray_src.cols - 2, CV_8UC1);//3*3窗口,边界有左右各1个像素不处理
    33     for (int row = 1; row < height - 1; row++) {
    34         for (int col = 1; col < width - 1; col++) {
    35             uchar c = gray_src.at<uchar>(row, col);//获取中心像素值
    36             uchar code = 0;//特征码
    37             code |= (gray_src.at<uchar>(row - 1, col - 1) > c) << 7;
    38             code |= (gray_src.at<uchar>(row - 1, col) > c) << 6;
    39             code |= (gray_src.at<uchar>(row - 1, col + 1) > c) << 5;
    40             code |= (gray_src.at<uchar>(row, col + 1) > c) << 4;
    41             code |= (gray_src.at<uchar>(row + 1, col + 1) > c) << 3;
    42             code |= (gray_src.at<uchar>(row + 1, col) > c) << 2;
    43             code |= (gray_src.at<uchar>(row + 1, col - 1) > c) << 1;
    44             code |= (gray_src.at<uchar>(row, col - 1) > c) << 0;
    45             lbpImage.at<uchar>(row - 1, col - 1) = code;
    46         }
    47     }
    48     imshow(output_tt, lbpImage);
    49 
    50     // ELBP 演示
    51 
    52     namedWindow("ELBP Result", CV_WINDOW_AUTOSIZE);
    53     createTrackbar("ELBP Radius:", "ELBP Result", &current_radius, max_count, ELBP_Demo);
    54     ELBP_Demo(0, 0);
    55 
    56     waitKey(0);
    57     return 0;
    58 }
    59 
    60 void ELBP_Demo(int, void*) {
    61     int offset = current_radius * 2;//输出图无法计算到的边界宽度
    62     Mat elbpImage = Mat::zeros(gray_src.rows - offset, gray_src.cols - offset, CV_8UC1);
    63     int width = gray_src.cols;
    64     int height = gray_src.rows;
    65 
    66     int numNeighbors = 8;//应根据半径变化,为了简便这里固定为8
    67     for (int n = 0; n < numNeighbors; n++) {
    68         float x = static_cast<float>(current_radius) * cos(2.0 * CV_PI*n / static_cast<float>(numNeighbors));//x=r*cos(2*PI*n/8)
    69         float y = static_cast<float>(current_radius) * -sin(2.0 * CV_PI*n / static_cast<float>(numNeighbors));
    70 
    71         int fx = static_cast<int>(floor(x));//floor“向下取整”
    72         int fy = static_cast<int>(floor(y));
    73         int cx = static_cast<int>(ceil(x));//ceil“向上取整”
    74         int cy = static_cast<int>(ceil(y));
    75 
    76         //双线性插值
    77         float ty = y - fy;
    78         float tx = x - fx;
    79 
    80         //双线性插值,周边4个点的权重
    81         float w1 = (1 - tx)*(1 - ty);
    82         float w2 = tx * (1 - ty);
    83         float w3 = (1 - tx)* ty;
    84         float w4 = tx * ty;
    85 
    86         for (int row = current_radius; row < (height - current_radius); row++) {
    87             for (int col = current_radius; col < (width - current_radius); col++) {
    88                 float t = w1 * gray_src.at<uchar>(row + fy, col + fx) + w2 * gray_src.at<uchar>(row + fy, col + cx) +
    89                     w3 * gray_src.at<uchar>(row + cy, col + fx) + w4 * gray_src.at<uchar>(row + cy, col + cx);
    90                 elbpImage.at<uchar>(row - current_radius, col - current_radius) +=
    91                     ((t > gray_src.at<uchar>(row, col)) && (abs(t - gray_src.at<uchar>(row, col)) > std::numeric_limits<float>::epsilon())) << n;
    92             }
    93         }
    94     }
    95     imshow("ELBP Result", elbpImage);
    96     return;
    97 }
  • 相关阅读:
    AcWiing 翻硬币
    AcWing 飞行员兄弟 二进制枚举
    AcWing 费解的开关 二进制枚举
    vue发送短信逻辑
    使用celery异步发送短信
    celery配置与基本使用
    celery原理与组件
    短信验证接口
    图片验证码接口
    编写注册接口
  • 原文地址:https://www.cnblogs.com/long5683/p/9738095.html
Copyright © 2020-2023  润新知