继上一篇人脸图像预处理,现在给出opencv的程序。由于涉及到滤波,我先给出Opencv滤波的函数。
void filter2D(InputArray src, //要进行滤波的图像
OutputArray dst,//滤波后的图像
int ddepth, //原图像的深度 src.depth()
InputArray kernel, //第一步建立的Mask
Point anchor=Point(-1,-1),//Mask的中心点
double delta=0, //Optional value added to the filtered pixels before storing them in dst
int borderType=BORDER_DEFAULT
)
对于filter2D,我们只需要计算得到kernel即可,对于滤波模板kernel,我们需要对其旋转180度如下函数:
void filp(InputArray src, //要进行滤波的图像
OutputArray dst,//滤波后的图像
int filpcode)
如果我们不进行旋转180度,我们得出来就只是相关。对于Matlab就是如下函数:
conv2(img, kernel,'same');
如果要使filter2D函数与conv2(img, kernel,’same’);相同,只需要borderType = BORDER_CONSTANT
http://blog.timmlinder.com/2011/07/opencv-equivalent-to-matlabs-conv2-function/谈到matlab的conv2和opencv之间的关系和使用
下面给出光照预处理Opencv代码
Parameter.h
#ifndef PARAMETER_H
#define PARAMETER_H
#include<opencv2/opencv.hpp>
#include<vector>
using namespace cv;
static double do_norm = 10.0;
static double mask = 0.1;
static double trim = 10.0;
static double gamma = 0.2;
static double sigma0 = 1;
static double sigma1 = 2;
static double sigma00[] = {-3, -2, -1, 0, 1, 2, 3};
static double sigma11[] = {-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6};
static double sigma2 = -2.0;
#endif // PARAMETER_H
Mat FaceFeatureExtract::psTan(Mat src)
{
double b;
Mat c, d;
Mat C, C1, D, mergeImg, dst0, dst1;
dst0.convertTo(dst0, CV_64FC1);
if (gamma > 0)
pow(src, gamma, src);
double border = 1;
if(border != 0){
b = floor(3 * abs(sigma2));
c = Mat::ones(b, b, CV_64FC1);
d = Mat::ones(b, 1, CV_64FC1);
C = Mat::ones(b, b, CV_64FC1);
C1 = Mat::ones(b, b, CV_64FC1);
C = c*src.at<double>(0,0);
D = d * src.row(0);
C1 = c * src.at<double>(0, src.cols-1);
Mat C2 = src.col(0) * d.t();
Mat C3 = src.col(src.cols-1) * d.t();
Mat C4 = src.at<double>(src.rows, 0) * c;
Mat C5 = d * src.row(src.rows-1);
Mat C6 = c * src.at<double>(src.rows-1, src.cols-1);
Mat subPatch1 = mergeCols(C, D, C1);
Mat subPatch2 = mergeCols(C2, src, C3);
Mat subPatch3 = mergeCols(C4, C5, C6);
mergeImg = mergeRows(subPatch1, subPatch2, subPatch3);
}
Mat src1 = mergeImg;
double gaussTp[7];
double sum = 0.0;
for (int i = 0; i < 7; i++){
gaussTp[i] = exp((-sigma00[i]*sigma00[i])/(2 * sigma0 * sigma0));
sum = sum + gaussTp[i];
}
for (int i = 0; i < 7; i++){
gaussTp[i] = gaussTp[i]/sum;
}
Mat sigma000 = Mat(1, 7, CV_64FC1, gaussTp);
Mat sigma0result = sigma000.t() * sigma000;
filter2D(src1, dst0, src.depth(), sigma0result, Point(-1,-1), 0, BORDER_CONSTANT);
double gaussTp1[13];
sum = 0.0;
for (int i = 0; i < 13; i++)
{
gaussTp1[i] = exp((-sigma11[i]*sigma11[i])/(2 * sigma1 * sigma1));
sum = sum + gaussTp1[i];
}
for (int i = 0; i < 13; i++)
{
gaussTp1[i] = gaussTp1[i]/sum;
}
Mat sigma111 = Mat(1, 13, CV_64FC1, gaussTp1);
Mat sigma1result = sigma111.t() * sigma111;
filter2D(src1, dst1, src.depth(), sigma1result, Point(-1,-1), 0, BORDER_CONSTANT);
Mat dst = dst0 - dst1;
Mat normResult = Normalization(dst, src.cols, src.rows);
// Mat roi = dst0(Rect(0,0,4,4));
// cout<<"func2:"<<roi<<endl;
return normResult;
}
Mat FaceFeatureExtract::Normalization(Mat src, double m, double n)
{
double b = floor(3 * abs(sigma2));
Mat roi = src(Rect(b, b, m, n));
double trim = abs(do_norm);
Mat roi1,roi4;
roi.copyTo(roi1);
Mat roi2 = Mat::zeros(roi.size(),CV_64FC1);
Mat roi3 = Mat::zeros(roi.size(),CV_64FC1);
pow(roi, mask, roi);
Scalar roiMean = mean(roi);
for (int i = 0; i < roi.rows; i++)
{
for(int j = 0; j < roi.cols; j++)
{
roi2.at<double>(i,j) = roi1.at<double>(i,j)/pow(roiMean.val[0],10);
}
}
for (int i = 0; i < roi.rows; i++)
{
for(int j = 0; j < roi.cols; j++)
{
if (roi2.at<double>(i,j) > 10.0)
roi3.at<double>(i,j) = 10.0;
else
roi3.at<double>(i,j) = roi2.at<double>(i,j);
}
}
roi3.copyTo(roi4);
pow(roi3, mask, roi3);
Scalar roi3Mean = mean(roi3);
for (int i = 0; i < roi.rows; i++)
{
for(int j = 0; j < roi.cols; j++)
{
roi4.at<double>(i,j) = trim * tanh(roi4.at<double>(i,j)/(pow(roi3Mean.val[0], 1.0/mask)*trim));
}
}
Mat ROI = roi4(Rect(0,0,4,4));
cout<<ROI<<endl;
return roi2;
}
可以自己建一个类,调用方式为dst = XX.psTan(src),XX为类名。如下:
Preprocess facefe;
Mat dst = facefe.psTan(src);