图像处理之局部二值特征

简介: 图像处理之局部二值特征一:局部二值模式(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学堂】定期推送更多干货,图像处理算法!

目录
相关文章
|
网络协议 安全 定位技术
顺着 IP 地址,真的能找到我家吗?
这篇文章主要讨论了互联网平台陆续显示用户 IP 属地以及此举可能引发的隐私问题。文章指出,一些人支持平台强制在前台显示用户 IP 属地,认为这可以让人们收敛行为,防止虚假信息传播;而另一些人质疑这一举措会进一步侵犯个人隐私。文章还介绍了 IP 地址的基本定义和作用,以及它与个人隐私的关系。同时,也提到了用户和平台建立连接的基础是 IP,因此用户的 IP 信息会被平台服务器记录下来。对于公开用户 IP 属地所带来的隐私问题,文章提到了一些专家和律师的看法,以及一些保护个人隐私的建议,包括隐藏位置信息、删去不想暴露的信息、使用不同的用户名和密码等。
151520 36
百度搜索:蓝易云【ipmitool配置BMC的ip】
以上操作将配置BMC的IP地址为新的值。请注意,操作BMC需要谨慎,确保你对服务器有足够的权限,并且仔细检查新的IP地址、子网掩码和默认网关,以免导致服务器网络失联。
461 7
|
Java 数据库
若依框架---模板生成
若依框架---模板生成
438 0
|
3月前
|
弹性计算 ice
阿里云4核8g服务器多少钱一年?1个月和1小时价格,省钱购买方法分享
阿里云4核8G服务器价格因实例类型而异,经济型e实例约159元/月,计算型c9i约371元/月,支持按小时计费及年付优惠,实际购买可享折扣,热门CPU含Intel Xeon、AMD EPYC等。
251 10
|
设计模式 XML Java
设计模式觉醒系列(03)创建型模式的5个设计模式 | 一口气讲全讲透
本文详细介绍了设计模式中的创建型模式,包括建造者模式、原型模式、单例模式、工厂方法模式和抽象工厂模式。创建型模式关注对象的创建过程,隐藏了创建细节,以提高代码的可维护性和可扩展性。通过具体的实战demo和应用场景分析,展示了每种模式的特点和优势。例如,建造者模式适用于复杂对象的分步骤构建;原型模式通过复制对象实现高效复用;单例模式确保全局唯一实例;工厂方法模式和抽象工厂模式则提供了灵活的对象创建机制,支持多类型产品族的生产。这些模式在实际开发中能够简化客户端代码,提升系统灵活性和复用性。
|
安全 Android开发 iOS开发
安卓vs iOS:探索两种操作系统的独特魅力与技术深度###
【10月更文挑战第16天】 本文旨在深入浅出地探讨安卓(Android)与iOS这两种主流移动操作系统的特色、优势及背后的技术理念。通过对比分析,揭示它们各自如何塑造了移动互联网的生态,并为用户提供丰富多彩的智能体验。无论您是科技爱好者还是普通用户,都能从这篇文章中感受到技术创新带来的无限可能。 ###
695 2
|
双11 文件存储 前端开发
限量版阿里云手办,原来这么简单就拿到了(附详细攻略)
阿里云今年双11出了个“带云小宝回家”的活动,一共限量3000个手办,还挺有科技感,出个攻略,方便大家去薅羊毛。按照下面的步骤,一步一步操作就行。
2758 0
限量版阿里云手办,原来这么简单就拿到了(附详细攻略)
|
安全 Linux Shell
探索Linux中的`lslogins`命令:用户账户信息的便捷查看器
`lslogins`是Linux中用于查看登录用户信息的便捷命令,它从`/etc/passwd`读取数据,过滤出有登录权限的用户。该命令特点是简洁、快速且易于使用,可帮助管理员审计或迁移用户账户。通过`lslogins`可直接列出登录用户,也可与其他命令结合使用,如`xargs`来获取用户家目录。注意,非特权用户可能无法运行此命令,且在某些发行版中可能需额外安装。建议系统管理员定期使用`lslogins`检查用户账户安全。
|
存储 网络协议 网络安全
Flannel dial tcp X.X.X.X i/o timeout报错解决
总的来说,解决这个问题需要对你的网络环境、Flannel配置和etcd服务进行全面的检查和调试。
653 0
|
XML 测试技术 程序员
QTest单元测试框架,简单,好用,高效
QTest单元测试框架,简单,好用,高效