#include "speakcls.h" 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::detect_speak(vector<Mat> images){ auto session = net->createSession(config);//创建session Mat input_data=data_process(images); // cout << _Tensor->elementSize() << endl; std::vector<std::vector<cv::Mat>> nChannels; std::vector<cv::Mat> rgbChannels(30); cv::split(input_data, rgbChannels); nChannels.push_back(rgbChannels); // NHWC 转NCHW auto *pvData = malloc(1 * 30 * 112 * 112 *sizeof(float)); int nPlaneSize = 112 * 112; for (int c = 0; c < 30; ++c) { cv::Mat matPlane = nChannels[0][c]; memcpy((float *)(pvData) + c * nPlaneSize,\ matPlane.data, nPlaneSize * sizeof(float)); } auto inTensor = net->getSessionInput(session, NULL); auto nchwTensor = new Tensor(inTensor, Tensor::CAFFE); ::memcpy(nchwTensor->host<float>(), pvData, nPlaneSize * 30 * sizeof(float)); inTensor->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; } }