OpenCv-C++-LBP特徵檢測
阿新 • • 發佈:2018-12-23
什麼是LBP?它是一種用來描述影象區域性紋理特徵的運算元,英文叫做“Local Binary Pattern”,區域性二值模式。
它具有旋轉不變性,灰度不變性和光照強度不變性等優點。特別是光照強度不變性這一點,如果一張圖片在光照很強的畫面裡特徵物體根本無法識別,LBP就能很好的檢測到物體。這一點我覺得很實用。
部分原理的話其實參考這篇文章就好,很詳細,也很能懂。
參考文章:https://blog.csdn.net/heli200482128/article/details/79204008
我主要是以程式碼應用為主:
下面放上程式碼:
#include<opencv2/opencv.hpp> #include<iostream> #include<math.h> using namespace cv; using namespace std; int current_radius = 3; int max_count = 20; void Expand_LBP_demo(int, void*); Mat src,gray_src; int main(int argc, char** argv) { src = imread("D:/test/girl.png"); if (!src.data) { cout << "圖片未找到" << endl; return -1; } imshow("input title", src); cvtColor(src, gray_src, CV_BGR2GRAY); int width = src.cols - 2; int hight = src.rows - 2; //基本LBP演示 Mat lbpImg = Mat::zeros(hight, width, CV_8UC1); for (int row = 1; row < src.rows - 1; row++) { for (int col = 1; col < src.cols - 1; col++) { uchar c = gray_src.at<uchar>(row, col); uchar code = 0; code |= (gray_src.at<uchar>(row - 1, col - 1) > c) << 7; code |= (gray_src.at<uchar>(row - 1, col ) > c) << 6; code |= (gray_src.at<uchar>(row - 1, col + 1) > c) << 5; code |= (gray_src.at<uchar>(row, col + 1) > c) << 4; code |= (gray_src.at<uchar>(row + 1, col +1) > c) << 3; code |= (gray_src.at<uchar>(row + 1, col ) > c) << 2; code |= (gray_src.at<uchar>(row + 1, col - 1) > c) << 1; code |= (gray_src.at<uchar>(row , col ) > c) << 0; lbpImg.at<uchar>(row-1, col-1) = code; } } imshow("LBP", lbpImg); namedWindow("Expand LBP", CV_WINDOW_AUTOSIZE); createTrackbar("current_radius", "Expand LBP", ¤t_radius, max_count,Expand_LBP_demo); Expand_LBP_demo(0, 0); waitKey(0); return 0; } //擴充套件LBP demo void Expand_LBP_demo(int, void *) { int offset = current_radius * 2; Mat elbpImg = Mat::zeros(gray_src.rows-offset, gray_src.cols-offset, CV_8UC1); int numNeighbor = 8; for (int n = 0; n < numNeighbor; n++) { float x = current_radius * cos((2 * CV_PI*n) / numNeighbor); float y = current_radius * (-sin((2 * CV_PI*n) / numNeighbor)); 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)); float ty = y - fy; float tx = x = fx; float w1 = (1 - tx)*(1 - ty); float w2 = (tx)*(1 - ty); float w3 = (1-tx)*(ty); float w4 = (tx)*(ty); for (int row = current_radius; row < (gray_src.rows-current_radius); row++) { for (int col = current_radius; col < (gray_src.cols- 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); elbpImg.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("Expand LBP", elbpImg); } }
執行結果: