人脸识别实战之用QT做点事(五):特征提取之等价LBP

xiaoxiao2021-02-28  32

    在检测到人脸后,需要对人脸图像进行特征提取,最常见的特征提取方式为LBP,这里采用等价LBP,具体的流程如下:

    1、新建一个features.h文件,内容如下:

#ifndef FEATURES_H #define FEATURES_H //UniformLBP Mat UniformLBP(Mat img, double * lbp_hist, Mat &out); //中心对称LBP Mat CSLBP(Mat & src, double * lbp_hist, Mat &out); #endif // FEATURES_H

 

    2、新建一个features.cpp文件,内容如下:

 

//UniformLBP // 当某个LBP所对应的循环二进制数从0到1或者从1到0最多有两次跳变时, // 该LBP所对应的二进制就称为一个等价模式。在实际图像中, // 计算出来的大部分值都在等价模式之中,可达百分之90%以上。 Mat UniformLBP(Mat img, double * lbp_hist, Mat &out) { uchar UTable[256]; memset(UTable, 0, 256 * sizeof(uchar)); uchar temp = 1; // 总共有256种2进制模式 // 这里进行分类 // 对属于等级模式的二进制表示进行统计 for (int i = 0; i < 256; i++) { if (getHopCount(i) <= 2) { UTable[i] = temp; ++temp; } } Mat result; result.create(img.rows - 2, img.cols - 2, img.type()); result.setTo(0); // 计算二进制表示,并通过查表的方式,获取其对应的等价模式下的值 for (int i = 1; i < img.rows - 1; i++) { for (int j = 1; j < img.cols - 1; j++) { uchar center = img.at<uchar>(i, j); uchar code = 0; code |= (img.at<uchar>(i - 1, j - 1) >= center) << 7; code |= (img.at<uchar>(i - 1, j) >= center) << 6; code |= (img.at<uchar>(i - 1, j + 1) >= center) << 5; code |= (img.at<uchar>(i, j + 1) >= center) << 4; code |= (img.at<uchar>(i + 1, j + 1) >= center) << 3; code |= (img.at<uchar>(i + 1, j) >= center) << 2; code |= (img.at<uchar>(i + 1, j - 1) >= center) << 1; code |= (img.at<uchar>(i, j - 1) >= center) << 0; result.at<uchar>(i - 1, j - 1) = UTable[code]; } } out = result; // 进行直方图统计 for (int i = 0; i < result.rows; i++) for (int j = 0; j < result.cols; j++) { lbp_hist[result.at<uchar>(i, j)] += 1; } // 查找最大值 float max_hist_val = 0; for (int i = 0; i < 59; i++) { if (max_hist_val < lbp_hist[i]) { max_hist_val = lbp_hist[i]; } } for (int i = 0; i < 59; i++) { lbp_hist[i] /= max_hist_val; } Mat LBP_hist_pic_color; Mat LBP_hist_pic = Mat::zeros(59, (59 + 1) * 2, CV_8U); cvtColor(LBP_hist_pic, LBP_hist_pic_color, COLOR_GRAY2BGR); for (int i = 0; i < 59; i++) { rectangle(LBP_hist_pic_color, Point(i * 2, 59), Point((i + 1) * 2, (1 - lbp_hist[i]) * 59), Scalar(255, 0, 0)); } /*for (int i = 0; i < 59; i++) { rectangle(LBP_hist_pic_color, Point(i* LBP_hist_pic.cols / 118, LBP_hist_pic.rows), Point((i + 1)* LBP_hist_pic.cols /118, (1 - lbp_hist[i]) * LBP_hist_pic.rows), Scalar(255, 0, 0), 2); }*/ return LBP_hist_pic_color; } // (ni - ni+4)* pow(2, i) Mat CSLBP(Mat & src, double * lbp_hist, Mat &out) { Mat img; src.copyTo(img); uchar UTable[16]; // 计算二进制表示,并通过查表的方式,获取其对应的等价模式下的值 for (int i = 1; i < img.rows - 1; i++) { for (int j = 1; j < img.cols - 1; j++) { uchar code = 0; for (int m = 0; m < 4; m++) { code |= (src.at<uchar>(i - 1, j - 1) >= src.at<uchar>(i + 1, j + 1)) << 0; code |= (src.at<uchar>(i, j - 1) >= src.at<uchar>(i, j + 1)) << 1; code |= (src.at<uchar>(i + 1, j - 1) >= src.at<uchar>(i - 1, j + 1)) << 2; code |= (src.at<uchar>(i + 1, j) >= src.at<uchar>(i - 1, j)) << 3; } img.at<uchar>(i, j) = code; } } out = img; for (int i = 1; i < img.rows - 1; i++) { for (int j = 1; j < img.cols - 1; j++) { UTable[img.at<uchar>(i, j)]++; } } // 查找最大值 float max_hist_val = 0; for (int i = 0; i < 16; i++) { if (max_hist_val < UTable[i]) { max_hist_val = UTable[i]; } } //cout << max_hist_val << endl; for (int i = 0; i < 16; i++) { lbp_hist[i] = 1.0 * UTable[i] / max_hist_val; //cout << "lbp_hist: " << lbp_hist[i] << endl; } Mat LBP_hist = Mat::zeros(32, 17 * 2, CV_8U); Mat LBP_hist_color; cvtColor(LBP_hist, LBP_hist_color, COLOR_GRAY2BGR); for (int i = 0; i < 16; i++) { //cout << 1 - UTable[i] << endl; rectangle(LBP_hist_color, Point(i * 2, 32), Point((i + 1) * 2, int((1 - lbp_hist[i]) * 32)), Scalar(255, 0, 0)); } return LBP_hist_color; }

    3、在mainwidow.cpp文件中添加如下文件:

double lbp_hist[59] = {0};

    在检测人脸之后,添加如下代码:

equalizeHist(face_gray, face_gray); ULBP = UniformLBP(face_gray, lbp_hist, ULBP_out); int width_3 = ui->label_3->width(); int height_3 = ui->label_3->height(); cv::resize(ULBP, ULBP, cv::Size(width_3, height_3)); cvtColor(ULBP, ULBP_show, COLOR_BGR2RGB); QImage img_ULBP((const uchar*)ULBP_show.data, ULBP_show.cols, ULBP_show.rows, ULBP_show.cols * ULBP_show.channels(), QImage::Format_RGB888); ui->label_3->setPixmap(QPixmap::fromImage(img_ULBP));

效果如下:

转载请注明原文地址: https://www.6miu.com/read-1450075.html

最新回复(0)