#include <opencv2/opencv.hpp>
#include <iostream>
#include "math.h" using namespace cv;
using namespace std; Mat src, gray_src; const char* output_tt = "LBP Result"; int main(int argc, char** argv) {
src = imread("test.jpg");
if (src.empty()) {
printf("could not load image...\n");
return -;
} 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; // 基本LBP演示
Mat lbpImage = Mat::zeros(gray_src.rows - , gray_src.cols - , CV_8UC1);//3*3窗口,边界有左右各1个像素不处理
for (int row = ; row < height - ; row++) {
for (int col = ; col < width - ; col++) {
uchar c = gray_src.at<uchar>(row, col);//获取中心像素值
uchar code = ;//特征码
code |= (gray_src.at<uchar>(row - , col - ) > c) << ;
code |= (gray_src.at<uchar>(row - , col) > c) << ;
code |= (gray_src.at<uchar>(row - , col + ) > c) << ;
code |= (gray_src.at<uchar>(row, col + ) > c) << ;
code |= (gray_src.at<uchar>(row + , col + ) > c) << ;
code |= (gray_src.at<uchar>(row + , col) > c) << ;
code |= (gray_src.at<uchar>(row + , col - ) > c) << ;
code |= (gray_src.at<uchar>(row, col - ) > c) << ;
lbpImage.at<uchar>(row - , col - ) = code;//原图1,1=效果图0,0
}
}
imshow(output_tt, lbpImage); waitKey();
return ;
}

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

 #include <opencv2/opencv.hpp>
#include <iostream>
#include "math.h" using namespace cv;
using namespace std; Mat src, gray_src;
int current_radius = ;
int max_count = ; const char* output_tt = "LBP Result"; void ELBP_Demo(int, void*);
int main(int argc, char** argv) {
src = imread("test.jpg");
if (src.empty()) {
printf("could not load image...\n");
return -;
} 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; // 基本LBP演示
Mat lbpImage = Mat::zeros(gray_src.rows - , gray_src.cols - , CV_8UC1);//3*3窗口,边界有左右各1个像素不处理
for (int row = ; row < height - ; row++) {
for (int col = ; col < width - ; col++) {
uchar c = gray_src.at<uchar>(row, col);//获取中心像素值
uchar code = ;//特征码
code |= (gray_src.at<uchar>(row - , col - ) > c) << ;
code |= (gray_src.at<uchar>(row - , col) > c) << ;
code |= (gray_src.at<uchar>(row - , col + ) > c) << ;
code |= (gray_src.at<uchar>(row, col + ) > c) << ;
code |= (gray_src.at<uchar>(row + , col + ) > c) << ;
code |= (gray_src.at<uchar>(row + , col) > c) << ;
code |= (gray_src.at<uchar>(row + , col - ) > c) << ;
code |= (gray_src.at<uchar>(row, col - ) > c) << ;
lbpImage.at<uchar>(row - , col - ) = code;
}
}
imshow(output_tt, lbpImage); // ELBP 演示 namedWindow("ELBP Result", CV_WINDOW_AUTOSIZE);
createTrackbar("ELBP Radius:", "ELBP Result", &current_radius, max_count, ELBP_Demo);
ELBP_Demo(, ); waitKey();
return ;
} void ELBP_Demo(int, void*) {
int offset = current_radius * ;//输出图无法计算到的边界宽度
Mat elbpImage = Mat::zeros(gray_src.rows - offset, gray_src.cols - offset, CV_8UC1);
int width = gray_src.cols;
int height = gray_src.rows; int numNeighbors = ;//应根据半径变化,为了简便这里固定为8
for (int n = ; n < numNeighbors; n++) {
float x = static_cast<float>(current_radius) * cos(2.0 * CV_PI*n / static_cast<float>(numNeighbors));//x=r*cos(2*PI*n/8)
float y = static_cast<float>(current_radius) * -sin(2.0 * CV_PI*n / static_cast<float>(numNeighbors)); int fx = static_cast<int>(floor(x));//floor“向下取整”
int fy = static_cast<int>(floor(y));
int cx = static_cast<int>(ceil(x));//ceil“向上取整”
int cy = static_cast<int>(ceil(y)); //双线性插值
float ty = y - fy;
float tx = x - fx; //双线性插值,周边4个点的权重
float w1 = ( - tx)*( - ty);
float w2 = tx * ( - ty);
float w3 = ( - tx)* ty;
float w4 = tx * ty; for (int row = current_radius; row < (height - current_radius); row++) {
for (int col = current_radius; col < (width - current_radius); col++) {
float t = w1 * gray_src.at<uchar>(row + fy, col + fx) + w2 * gray_src.at<uchar>(row + fy, col + cx) +
w3 * gray_src.at<uchar>(row + cy, col + fx) + w4 * gray_src.at<uchar>(row + cy, col + cx);
elbpImage.at<uchar>(row - current_radius, col - current_radius) +=
((t > gray_src.at<uchar>(row, col)) && (abs(t - gray_src.at<uchar>(row, col)) > std::numeric_limits<float>::epsilon())) << n;
}
}
}
imshow("ELBP Result", elbpImage);
return;
}

OpenCV——LBP(Local Binary Patterns)特征检测的更多相关文章

  1. 局部二值模式(Local Binary Patterns)纹理灰度与旋转不变性

    Multiresolution Gray Scale and Rotation Invariant Texture Classification with Local Binary Patterns, ...

  2. LBP(Local Binary Patterns)局部二进制模式

    1. LBP 用于人脸识别 为了预测每个像素属于哪个脸部器官(眼睛.鼻子.嘴.头发),通常的作法是在该像素周围取一个小的区域,提取纹理特征(例如局部二值模式),再基于该特征利用支持向量机等浅层模型分类 ...

  3. 机器视觉 Local Binary Pattern (LBP)

    Local binary pattern (LBP),在机器视觉领域,是非常重要的一种特征.LBP可以有效地处理光照变化,在纹理分析,纹理识别方面被广泛应用. LBP 的算法非常简单,简单来说,就是对 ...

  4. 【C++版】Face Alignment at 3000 FPS by Regressing Local Binary Features源码下载

    下载地址: 本帖隐藏的内容 <ignore_js_op> face-alignment-in-3000fps-master.zip (794.42 KB, 下载次数: 1076) 该源码采 ...

  5. Local Binary Convolutional Neural Networks ---卷积深度网络移植到嵌入式设备上?

    前言:今天他给大家带来一篇发表在CVPR 2017上的文章. 原文:LBCNN 原文代码:https://github.com/juefeix/lbcnn.torch 本文主要内容:把局部二值与卷积神 ...

  6. Vulkan移植GpuImage(三)从A到C的滤镜

    前面移植了几个比较复杂的效果后,算是确认了复杂滤镜不会对框架造成比较大的改动,开始从头移植,现已把A到C的所有滤镜用vulkan的ComputeShader实现了,讲一些其中实现的过程. Averag ...

  7. 使用opencv训练分类器时,traincascade训练报错:Train dataset for temp stage can not be filled.解决方法

    opencv分类器训练中,出错一般都是路径出错,例如, 1.opencv_traincascade.exe路径 2.负样本路径文件,neg.dat中的样本前路径是否正确 3.移植到别的电脑并修改完路径 ...

  8. [分享] 采用opencv_cascadetrain进行训练的步骤及注意事项 [复制链接]

    http://f.dataguru.cn/thread-725364-1-1.html 很有用的一个帖子 转自:http://blog.csdn.net/xidianzhimeng/article/d ...

  9. Opencv之LBP特征(算法)

    LBP(Local Binary Pattern),即局部二进制模式,对一个像素点以半径r画一个圈,在圈上取K个点(一般为8),这K个点的值(像素值大于中心点为1,否则为0)组成K位二进制数.此即局部 ...

随机推荐

  1. Mybatis中trim标签的用法

    select * from t_user <trim prefix="WHERE" prefixOverrides="and"> <if te ...

  2. Java 并发:Future FutureTask

    Future 当向一个ExecutorService提交任务后可以获得一个Future对象,在该对象上可以调用get,cancel等命令来获取任务运行值或者是取消任务.下面是一个简单的计数任务: pu ...

  3. html前端学习

    html : 1.相当于没有穿衣服的人,一套浏览器认识的规则, 2.开发者: 学习html规则 开发后台程序: -写html文件(充当模板) -数据库获取数据,然后替换到html文件的指定位置(web ...

  4. 你不知道的JavasScript上篇·第四章·混合对象·类

    一.类的理论 1.类的核心概念:多态 是说父类的通用行为可以被子类用更特殊的行为重写 二.类的机制 1.构造函数 类实例是有一个特殊的类方法构造的,这个方法名通常和类名一致: 类构造函数属于类,构造函 ...

  5. drupal常用api

    最短的函数 // 语言字串,除了可以获取对应语言外,还可以设置字串变量.可以是!var, @var或 %var,%var就添加元素外层.@var会过滤HTML,!var会原样输出HTML,%var会添 ...

  6. structs2.8创建拦截器

    控制层 public class PrintUsername { private String username; public String getUsername() { return usern ...

  7. iframe页面刷新问题

    1.问题:当iframe的页面加载过再关闭之后,如果iframe的src没有发生变化,js不会重新加载,再次打开页面不会刷新: 2.解决方法:关闭页面时清空src,再次打开时即可重新加载最新数据. $ ...

  8. Nginx的常用功能

    1.规范nginx的配置文件 在企业中我们的虚拟主机可能会很多,配置文件的内容也会有很多,这时候我们就可以规范一下我们的配置文件,把每个虚拟主机按照网站的域名或者是功能取名,放到统一的文件夹中,当然我 ...

  9. android 点击数字跳转到电话界面

    实现方式两种: 1,在xml文件下很简单的实现 只需要在textview属性中加入android:autoLink="phone".  <TextView           ...

  10. 从托管映像创建 VM

    可以从 Azure 中托管的 VM 映像创建多个 VM. 托管 VM 映像包含创建 VM 所需的信息,包括 OS 和数据磁盘. 构成映像的 VHD(包括 OS 磁盘和任何数据磁盘)存储为托管磁盘. 先 ...