speakcls.cpp 2.89 KB
#include "speakcls.h"


bool SpeakCls::init_model(string model_path){
    net= std::shared_ptr<MNN::Interpreter>(MNN::Interpreter::createFromFile(model_path.c_str()));//创建解释器
    config.numThread = 2;
    config.type = MNN_FORWARD_CPU;
    session = net->createSession(config);
    input_tensor = net->getSessionInput(session,NULL);
    net->resizeTensor(input_tensor,{1,3*split_nums,112,112});
    net->resizeSession(session);
}

cv::Mat SpeakCls::standardize(cv::Mat image){
    cv::Mat image_f,dst;
    image.convertTo(image_f, CV_32F);
    Scalar max_pix = Scalar(255.0f,255.0f,255.0f);
    Scalar mean = Scalar(0.485f, 0.456f, 0.406f);
    Scalar std = Scalar(0.229f, 0.224f, 0.225f);
    dst=image_f/max_pix;
    dst = (dst-mean)/std;
    return dst;
}

cv::Mat SpeakCls::data_process(vector<Mat> images){
    std::vector<cv::Mat> all_image_channels;
    for(auto f:images){
        Mat tmp_image = standardize(f);
        std::vector<cv::Mat> tmp_channels;
        cv::split(tmp_image,tmp_channels);
        all_image_channels.push_back(tmp_channels[0]);
        all_image_channels.push_back(tmp_channels[1]);
        all_image_channels.push_back(tmp_channels[2]);
    }
    Mat input_data;
    cv::merge(all_image_channels,input_data);
    return input_data;
}

vector<double> SpeakCls::softmax(vector<double> input){
    double total=0;
	for(auto x:input)
	{
		total+=exp(x);
	}
	vector<double> result;
	for(auto x:input)
	{
		result.push_back(exp(x)/total);
	}
	return result;
}

bool SpeakCls::inference(vector<Mat> images){
    
    Mat input_data=data_process(images);
    // cout << _Tensor->elementSize() << endl;
    std::vector<std::vector<cv::Mat>> nChannels;
    std::vector<cv::Mat> rgbChannels(3*split_nums);
    cv::split(input_data, rgbChannels);
    nChannels.push_back(rgbChannels); //  NHWC  转NCHW
    auto *pvData = malloc(1 * 3*split_nums * 112 * 112 *sizeof(float));
    int nPlaneSize = 112 * 112;
    for (int c = 0; c < 3*split_nums; ++c)
    {
    cv::Mat matPlane = nChannels[0][c];
    memcpy((float *)(pvData) + c * nPlaneSize,\
            matPlane.data, nPlaneSize * sizeof(float));
    }

    auto nchwTensor = new Tensor(input_tensor, Tensor::CAFFE);
    ::memcpy(nchwTensor->host<float>(), pvData, nPlaneSize * 3*split_nums * sizeof(float));
    
    input_tensor->copyFromHostTensor(nchwTensor);
    //推理
    net->runSession(session);
    auto output= net->getSessionOutput(session, NULL);

    MNN::Tensor feat_tensor(output, output->getDimensionType());
    output->copyToHostTensor(&feat_tensor);

    auto scores_dataPtr  = feat_tensor.host<float>();

    cout<<scores_dataPtr[0]<<" "<<scores_dataPtr[1]<<endl;
    vector<double> outputs={scores_dataPtr[0],scores_dataPtr[1]};
    // softmax
    vector<double> result=softmax(outputs);

    printf("output belong to class: %f  %f\n", result[0],result[1]);
    if(result[0]>result[1]){
        return false;
    }else{
        return true;
    }
}