1 #include <opencv2/opencv.hpp> 2 #include <iostream> 3 #include "math.h" 4 5 using namespace cv; 6 using namespace std; 7 8 Mat src, gray_src; 9 10 const char* output_tt = "LBP Result"; 11 12 int main(int argc, char** argv) { 13 src = imread("test.jpg"); 14 if (src.empty()) { 15 printf("could not load image...\n"); 16 return -1; 17 } 18 19 namedWindow("input image", CV_WINDOW_AUTOSIZE); 20 namedWindow(output_tt, CV_WINDOW_AUTOSIZE); 21 imshow("input image", src); 22 23 // convert to gray 24 cvtColor(src, gray_src, COLOR_BGR2GRAY); 25 int width = gray_src.cols; 26 int height = gray_src.rows; 27 28 // 基本LBP演示 29 Mat lbpImage = Mat::zeros(gray_src.rows - 2, gray_src.cols - 2, CV_8UC1);//3*3窗口,边界有左右各1个像素不处理 30 for (int row = 1; row < height - 1; row++) { 31 for (int col = 1; col < width - 1; col++) { 32 uchar c = gray_src.at<uchar>(row, col);//获取中心像素值 33 uchar code = 0;//特征码 34 code |= (gray_src.at<uchar>(row - 1, col - 1) > c) << 7; 35 code |= (gray_src.at<uchar>(row - 1, col) > c) << 6; 36 code |= (gray_src.at<uchar>(row - 1, col + 1) > c) << 5; 37 code |= (gray_src.at<uchar>(row, col + 1) > c) << 4; 38 code |= (gray_src.at<uchar>(row + 1, col + 1) > c) << 3; 39 code |= (gray_src.at<uchar>(row + 1, col) > c) << 2; 40 code |= (gray_src.at<uchar>(row + 1, col - 1) > c) << 1; 41 code |= (gray_src.at<uchar>(row, col - 1) > c) << 0; 42 lbpImage.at<uchar>(row - 1, col - 1) = code;//原图1,1=效果图0,0 43 } 44 } 45 imshow(output_tt, lbpImage); 46 47 waitKey(0); 48 return 0; 49 }
LBP的扩展(多尺度表达):
1 #include <opencv2/opencv.hpp> 2 #include <iostream> 3 #include "math.h" 4 5 using namespace cv; 6 using namespace std; 7 8 Mat src, gray_src; 9 int current_radius = 3; 10 int max_count = 10; 11 12 const char* output_tt = "LBP Result"; 13 14 void ELBP_Demo(int, void*); 15 int main(int argc, char** argv) { 16 src = imread("test.jpg"); 17 if (src.empty()) { 18 printf("could not load image...\n"); 19 return -1; 20 } 21 22 namedWindow("input image", CV_WINDOW_AUTOSIZE); 23 namedWindow(output_tt, CV_WINDOW_AUTOSIZE); 24 imshow("input image", src); 25 26 // convert to gray 27 cvtColor(src, gray_src, COLOR_BGR2GRAY); 28 int width = gray_src.cols; 29 int height = gray_src.rows; 30 31 // 基本LBP演示 32 Mat lbpImage = Mat::zeros(gray_src.rows - 2, gray_src.cols - 2, CV_8UC1);//3*3窗口,边界有左右各1个像素不处理 33 for (int row = 1; row < height - 1; row++) { 34 for (int col = 1; col < width - 1; col++) { 35 uchar c = gray_src.at<uchar>(row, col);//获取中心像素值 36 uchar code = 0;//特征码 37 code |= (gray_src.at<uchar>(row - 1, col - 1) > c) << 7; 38 code |= (gray_src.at<uchar>(row - 1, col) > c) << 6; 39 code |= (gray_src.at<uchar>(row - 1, col + 1) > c) << 5; 40 code |= (gray_src.at<uchar>(row, col + 1) > c) << 4; 41 code |= (gray_src.at<uchar>(row + 1, col + 1) > c) << 3; 42 code |= (gray_src.at<uchar>(row + 1, col) > c) << 2; 43 code |= (gray_src.at<uchar>(row + 1, col - 1) > c) << 1; 44 code |= (gray_src.at<uchar>(row, col - 1) > c) << 0; 45 lbpImage.at<uchar>(row - 1, col - 1) = code; 46 } 47 } 48 imshow(output_tt, lbpImage); 49 50 // ELBP 演示 51 52 namedWindow("ELBP Result", CV_WINDOW_AUTOSIZE); 53 createTrackbar("ELBP Radius:", "ELBP Result", ¤t_radius, max_count, ELBP_Demo); 54 ELBP_Demo(0, 0); 55 56 waitKey(0); 57 return 0; 58 } 59 60 void ELBP_Demo(int, void*) { 61 int offset = current_radius * 2;//输出图无法计算到的边界宽度 62 Mat elbpImage = Mat::zeros(gray_src.rows - offset, gray_src.cols - offset, CV_8UC1); 63 int width = gray_src.cols; 64 int height = gray_src.rows; 65 66 int numNeighbors = 8;//应根据半径变化,为了简便这里固定为8 67 for (int n = 0; n < numNeighbors; n++) { 68 float x = static_cast<float>(current_radius) * cos(2.0 * CV_PI*n / static_cast<float>(numNeighbors));//x=r*cos(2*PI*n/8) 69 float y = static_cast<float>(current_radius) * -sin(2.0 * CV_PI*n / static_cast<float>(numNeighbors)); 70 71 int fx = static_cast<int>(floor(x));//floor“向下取整” 72 int fy = static_cast<int>(floor(y)); 73 int cx = static_cast<int>(ceil(x));//ceil“向上取整” 74 int cy = static_cast<int>(ceil(y)); 75 76 //双线性插值 77 float ty = y - fy; 78 float tx = x - fx; 79 80 //双线性插值,周边4个点的权重 81 float w1 = (1 - tx)*(1 - ty); 82 float w2 = tx * (1 - ty); 83 float w3 = (1 - tx)* ty; 84 float w4 = tx * ty; 85 86 for (int row = current_radius; row < (height - current_radius); row++) { 87 for (int col = current_radius; col < (width - current_radius); col++) { 88 float t = w1 * gray_src.at<uchar>(row + fy, col + fx) + w2 * gray_src.at<uchar>(row + fy, col + cx) + 89 w3 * gray_src.at<uchar>(row + cy, col + fx) + w4 * gray_src.at<uchar>(row + cy, col + cx); 90 elbpImage.at<uchar>(row - current_radius, col - current_radius) += 91 ((t > gray_src.at<uchar>(row, col)) && (abs(t - gray_src.at<uchar>(row, col)) > std::numeric_limits<float>::epsilon())) << n; 92 } 93 } 94 } 95 imshow("ELBP Result", elbpImage); 96 return; 97 }