图像处理之局部二值特征

简介: 图像处理之局部二值特征

图像处理之局部二值特征

一:局部二值模式(LBP)介绍

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

20170106160703222.png


二:局部二值模式(LBP)扩展

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

20170106160729664.png


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


三:运行

输入图像与3x3默认的LBP运行结果如下:

20170106160809414.png

在扩展模式下半径分别为1、3、5、7时候的运行结果:

20170106160834568.png


四:代码实现 - 基于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);
}
相关文章
|
18天前
|
算法 计算机视觉
图像处理之积分图应用四(基于局部均值的图像二值化算法)
图像处理之积分图应用四(基于局部均值的图像二值化算法)
23 0
|
25天前
|
机器学习/深度学习 计算机视觉 网络架构
【YOLOv8改进】Non-Local:基于非局部均值去噪滤波的自注意力模型 (论文笔记+引入代码)
YOLO目标检测专栏探讨了YOLO的创新改进,包括引入非局部操作以捕获远程依赖,增强上下文信息。非局部模块可应用于图像分类、目标检测等任务,尤其适合视频分类。文章介绍了Non-local自注意力模型,通过计算任意位置间交互,提供全局信息。此外,展示了如何在YOLOv8中实现NLBlockND模块。详细内容及实战配置见相关链接。
【YOLOv8改进】Non-Local:基于非局部均值去噪滤波的自注意力模型 (论文笔记+引入代码)
|
1月前
|
1月前
|
传感器 移动开发 测试技术
通过卷积公式学习声速重建的成像模型
【1月更文挑战第1篇】通过卷积公式学习声速重建的成像模型
53 2
|
1月前
|
机器学习/深度学习 文字识别 算法
[Halcon&图像] 基于多层神经网络MLP分类器的思想提取颜色区域
[Halcon&图像] 基于多层神经网络MLP分类器的思想提取颜色区域
78 0
|
8月前
|
机器学习/深度学习 传感器 缓存
可分离高斯神经网络:结构、分析和函数逼近
可分离高斯神经网络:结构、分析和函数逼近
111 0
|
9月前
|
机器学习/深度学习 传感器 算法
【图像分割】图像检测(分割、特征提取)、各种特征(面积等)的测量和过滤(Matlab代码实现)
【图像分割】图像检测(分割、特征提取)、各种特征(面积等)的测量和过滤(Matlab代码实现)
|
11月前
|
vr&ar
用于非线性时间序列预测的稀疏局部线性和邻域嵌入(Matlab代码实现)
用于非线性时间序列预测的稀疏局部线性和邻域嵌入(Matlab代码实现)
用于非线性时间序列预测的稀疏局部线性和邻域嵌入(Matlab代码实现)
|
10月前
|
算法
基于 SIFT 对图像进行局部特征匹配(Matlab代码实现)
基于 SIFT 对图像进行局部特征匹配(Matlab代码实现)
|
机器学习/深度学习 传感器 算法
【图像分割】基于局部空间信息直方图模糊聚类FGFCM 实现图像图像分割附matlab代码
【图像分割】基于局部空间信息直方图模糊聚类FGFCM 实现图像图像分割附matlab代码