人脸识别---光照预处理(Opencv代码和Matlab代码)

继上一篇人脸图像预处理,现在给出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);
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值