#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. javaBean分析

    package com.ldf.domain; /** * 实体bean */ import java.io.Serializable; import java.util.Date; public c ...

  2. Java - “JUC”锁

    [Java并发编程实战]-----“J.U.C”:锁,lock   在java中有两种方法实现锁机制,一种是在前一篇博客中([java7并发编程实战]-----线程同步机制:synchronized) ...

  3. Mybatis之SessionFactory原理

    Mybatis在使用前需进行初始化,下面就针对Mybatis的初始化过程进行介绍.Mybatis的初始化过程有两种:基于XML和基于Java API两种方式,下面就针对基于XML的方式进行展开. 一. ...

  4. Linux常用基本命令(chmod)

    chmod命令用来改变文件或者目录的权限,只有文件的属主和超级用户才能够执行这个命令 格式: chmod [option] [mode] [file] >常用参数选项 -R : 递归修改目录以及 ...

  5. HDU1083(KB10-C 二分图最大匹配)

    Courses Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total S ...

  6. linux学习笔记-目录结构(1)

    每个linux系统的目录结构差不多,因为有FHS(Filesystem Hierarchy Standard)标准的规范. FHS的重点在于规范每个特定的目录下应该要放什么样的数据. FHS依据文件系 ...

  7. Ajax常见面试题 -- 前端面试题(二)

    1:什么是ajax?ajax作用是什么? 异步的javascript和xml AJAX 是一种用于创建快速动态网页的技术. ajax用来与后台交互   2:原生js ajax请求有几个步骤?分别是什么 ...

  8. word2vec前世今生

    word2vec前世今生 2013年,Google开源了一款用于词向量计算的工具--word2vec,引起了工业界和学术界的关注.首先,word2vec可以在百万数量级的词典和上亿的数据集上进行高效地 ...

  9. MS SQL backup database的俩个参数

    http://msdn.microsoft.com/zh-cn/library/ms186865.aspx 数据传输选项 BUFFERCOUNT = { buffercount | @bufferco ...

  10. 华为Eudemon 100E的密码恢复

    华为Eudemon 100E的密码恢复 转自http://blog.sina.com.cn/s/blog_53835f380100hdc3.html  为了让自己下次能记住 Eudemon 100E系 ...