图像处理之局部二值特征

简介: 图像处理之局部二值特征一:局部二值模式(LBP)介绍 局部二值模式(Local Binary Pattern)主要用来实现2D图像纹理分析。其基本思想是用每个像素跟它周围的像素相比较得到局部图像结构,假设中心像素值大于相邻像素值则则相邻像素点赋值为1,否则赋值为0,最终对每个像素点都会得到一个二进制八位的表示,比如11100111。

图像处理之局部二值特征

一:局部二值模式(LBP)介绍
局部二值模式(Local Binary Pattern)主要用来实现2D图像纹理分析。其基本思想是用每个像素跟它周围的像素相比较得到局部图像结构,假设中心像素值大于相邻像素值则则相邻像素点赋值为1,否则赋值为0,最终对每个像素点都会得到一个二进制八位的表示,比如11100111。假设3x3的窗口大小,这样对每个像素点来说组合得到的像素值的空间为[0~2^8]。这种结果我称为图像的局部二值模式或者简写为了LBP。
这里写图片描述

二:局部二值模式(LBP)扩展
对于这种固定窗口大小方式的局部二值模式,很多人很快就发现它的弊端,不能很好的反映出图像结构,于是高人纷纷上阵把它改为窗口大小可变,而且把矩形结构改成圆形结构。而且还总结出来如下一系列的典型结构单元:
这里写图片描述

该操作是基于原来的局部二值模式的扩展,所以又被称为扩展的局部二值模式。但是一旦改为圆形的时候,寻找八个点坐标可能会产生小数坐标,这个时候就需要通过插值方式产生该像素点的像素值,最常见的插值方式基于双线性插值。这样就完成了任意尺度上的局部二值模式的采样。

三:运行
输入图像与3x3默认的LBP运行结果如下:
这里写图片描述
在扩展模式下半径分别为1、3、5、7时候的运行结果:
这里写图片描述

四:代码实现 - 基于OpenCV实现
简单说一下步骤
1. 读入图像
2. 彩色图像转灰度
3. 默认LBP处理操作
4. 扩展LBP处理操作
完整的源代码如下:

#include <opencv2/opencv.hpp>
#include <iostream>
#include "math.h"

using namespace cv;
using namespace std;

int max_thresh = 20;
int current_radius = 5;
Mat gray_src, LBP_image, ELBP_image;
void Demo_ELBP(int, void*);
int main(int argc, char** argv) {
    Mat src, dst;
    src = imread("D:/vcprojects/images/cat.jpg");
    if (src.empty()) {
        printf("could not load image...\n");
        return -1;
    }
    const char* output_tt = "LBP Result";
    namedWindow("input image", CV_WINDOW_AUTOSIZE);
    namedWindow(output_tt, CV_WINDOW_AUTOSIZE);
    imshow("input image", src);

    // convert to gray

    cvtColor(src, gray_src, COLOR_BGR2GRAY);
    int width = gray_src.cols;
    int height = gray_src.rows;

    // default LBP image
    LBP_image = Mat::zeros(src.rows - 2, src.cols - 2, CV_8UC1);
    for (int row = 1; row < height-1; row++) {
        for (int col = 1; col < width-1; col++) {
            uchar center = gray_src.at<uchar>(row, col);
            uchar code = 0;
            code |= (gray_src.at<uchar>(row - 1, col - 1) > center) << 7;
            code |= (gray_src.at<uchar>(row - 1, col) > center) << 6;
            code |= (gray_src.at<uchar>(row - 1, col + 1) > center) << 5;
            code |= (gray_src.at<uchar>(row, col + 1) > center) << 4;
            code |= (gray_src.at<uchar>(row+ 1, col + 1) > center) << 3;
            code |= (gray_src.at<uchar>(row + 1, col) > center) << 2;
            code |= (gray_src.at<uchar>(row + 1, col - 1) > center) << 1;
            code |= (gray_src.at<uchar>(row, col - 1) > center) << 0;
            LBP_image.at<uchar>(row- 1, col - 1) = code;
        }
    }

    imshow(output_tt, LBP_image);

    // extend LBP 
    namedWindow("ELBP_Result", CV_WINDOW_AUTOSIZE);
    createTrackbar("Radius:", "ELBP_Result", &current_radius, max_thresh, Demo_ELBP);
    Demo_ELBP(0, 0);

    waitKey(0);
    return 0;
}

void Demo_ELBP(int, void*) {
    int offset = current_radius * 2;
    ELBP_image = Mat::zeros(gray_src.rows - offset, gray_src.cols - offset, CV_8UC1);
    int height = gray_src.rows;
    int width = gray_src.cols;

    int neighbors = 8;
    for (int n = 0; n<neighbors; n++) {
        // sample points
        float x = static_cast<float>(current_radius) * cos(2.0*CV_PI*n / static_cast<float>(neighbors));
        float y = static_cast<float>(current_radius) * -sin(2.0*CV_PI*n / static_cast<float>(neighbors));
        // relative indices
        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));
        // fractional part
        float ty = y - fy;
        float tx = x - fx;
        // set interpolation weights
        float w1 = (1 - tx) * (1 - ty);
        float w2 = tx  * (1 - ty);
        float w3 = (1 - tx) *      ty;
        float w4 = tx  *      ty;
        // iterate through your data
        for (int i = current_radius; i < gray_src.rows - current_radius; i++) {
            for (int j = current_radius; j < gray_src.cols - current_radius; j++) {
                float t = w1*gray_src.at<uchar>(i + fy, j + fx) + w2*gray_src.at<uchar>(i + fy, j + cx) + w3*gray_src.at<uchar>(i + cy, j + fx) + w4*gray_src.at<uchar>(i + cy, j + cx);
                // we are dealing with floating point precision, so add some little tolerance
                ELBP_image.at<uchar>(i - current_radius, j - current_radius) += ((t > gray_src.at<uchar>(i, j)) && (abs(t - gray_src.at<uchar>(i, j)) > std::numeric_limits<float>::epsilon())) << n;
            }
        }
    }

    imshow("ELBP_Result", ELBP_image);
}

请继续关注本博客,同时关注微信公众号【OpenCV学堂】定期推送更多干货,图像处理算法!

目录
相关文章
|
7月前
|
算法
【MATLAB】语音信号识别与处理:一维信号NLM非局部均值滤波算法去噪及谱相减算法呈现频谱
【MATLAB】语音信号识别与处理:一维信号NLM非局部均值滤波算法去噪及谱相减算法呈现频谱
157 1
|
6月前
|
算法 计算机视觉
图像处理之积分图应用四(基于局部均值的图像二值化算法)
图像处理之积分图应用四(基于局部均值的图像二值化算法)
554 0
|
6月前
|
算法 计算机视觉
图像处理之基于一维高斯快速模糊
图像处理之基于一维高斯快速模糊
36 8
|
6月前
|
算法 Java 计算机视觉
图像处理之积分图算法
图像处理之积分图算法
74 2
|
5月前
|
并行计算 算法 Java
尺度函数在图像处理中的应用与优化
尺度函数在图像处理中的应用与优化
|
6月前
|
计算机视觉
图像处理之局部二值特征
图像处理之局部二值特征
58 0
|
6月前
|
算法 计算机视觉
图像处理之Lanczos采样放缩算法
图像处理之Lanczos采样放缩算法
79 0
|
6月前
|
算法 计算机视觉
图像处理之基于采样距离变换算法
图像处理之基于采样距离变换算法
39 0
|
6月前
|
算法 Java 计算机视觉
图像处理之应用卷积一实现噪声消去
图像处理之应用卷积一实现噪声消去
55 0
|
7月前
|
机器学习/深度学习 文字识别 算法
[Halcon&图像] 基于多层神经网络MLP分类器的思想提取颜色区域
[Halcon&图像] 基于多层神经网络MLP分类器的思想提取颜色区域
166 0