This commit is contained in:
songwei
2025-07-17 18:23:32 +08:00
parent 93c553b75a
commit bb175b20b4
33 changed files with 1 additions and 6922 deletions

View File

@@ -83,7 +83,7 @@
UILabel *label4=[[UILabel alloc] initWithFrame:CGRectMake(20, CGRectGetMaxY( self.baseTextView.frame)+20,self.view.frame.size.width-40,44)];
label4.text=@"数字人模型:";
label4.text=@"数字人模型url:";
label4.textColor=[UIColor blackColor];
label4.textAlignment=NSTextAlignmentLeft;
[self.view addSubview:label4];

View File

@@ -1,24 +0,0 @@
#pragma once
//#define MFCC_OFFSET 6436
#define MFCC_OFFSET 6400
//##define MFCC_OFFSET 0
#define MFCC_DEFRMS 0.1f
#define MFCC_FPS 25
#define MFCC_RATE 16000
//#define MFCC_WAVCHUNK 960000
#define MFCC_WAVCHUNK 560000
//#define MFCC_WAVCHUNK 512
//#define MFCC_MELBASE 6001
#define MFCC_MELBASE 3501
#define MFCC_MELCHUNK 80
//#define MFCC_MELCHUNK 20
//#define MFCC_BNFBASE 1499
#define MFCC_BNFBASE 874
#define MFCC_BNFCHUNK 256
//input==== NodeArg(name='speech', type='tensor(float)', shape=['B', 'T', 80])
//input==== NodeArg(name='speech_lengths', type='tensor(int32)', shape=['B'])
//output==== NodeArg(name='encoder_out', type='tensor(float)', shape=['B', 'T_OUT', 'Addencoder_out_dim_2'])

View File

@@ -1,445 +0,0 @@
#include "aimodel.h"
#include <stdlib.h>
#include <string.h>
void AiCfg::dump(){
int incnt = size_inputs.size();
int outcnt = size_outputs.size();
std::cout<<"======in onnx:"<<incnt<<std::endl;
//std::cout<<"======in onnx:"<<name_inputs.size()<<std::endl;
for(int k=0;k<incnt;k++){
//std::string sname(name_inputs[k]);
//std::cout<<"in name:"<<sname<<std::endl;
std::cout<<"size input:"<<size_inputs[k]<<std::endl;
for(int m=0;m<shape_inputs[k].size();m++)
std::cout<<"shape :"<<shape_inputs[k][m]<<std::endl;
std::cout<<"kind input:"<<kind_inputs[k]<<std::endl;
}
std::cout<<"=========out onnx:"<<outcnt<<std::endl;
//std::cout<<"======in onnx:"<<name_outputs.size()<<std::endl;
for(int k=0;k<outcnt;k++){
//std::string sname(name_outputs[k]);
//std::cout<<"out name:"<<sname<<std::endl;
std::cout<<"size output:"<<size_outputs[k]<<std::endl;
for(int m=0;m<shape_outputs[k].size();m++)
std::cout<<"shape :"<<shape_outputs[k][m]<<std::endl;
std::cout<<"kind outintpu:"<<kind_outputs[k]<<std::endl;
}
}
int AiCfg::inShape(int inx,int dim,int val){
if(inx>=shape_inputs.size())return -1;
if(dim>=shape_inputs[inx].size())return -2;
shape_inputs[inx][dim] = val;
int size = 1;
for(int k=0;k<shape_inputs[inx].size();k++){
size *= shape_inputs[inx][dim];
}
if(size>0){
size_inputs[inx] = size;
}
return 0;
}
int AiCfg::outShape(int inx,int dim,int val){
if(inx>=shape_outputs.size())return -1;
if(dim>=shape_outputs[inx].size())return -2;
shape_outputs[inx][dim] = val;
int size = 1;
for(int k=0;k<shape_outputs[inx].size();k++){
size *= shape_outputs[inx][dim];
}
if(size>0){
size_outputs[inx] = size;
}
return 0;
}
AiCfg AiCfg::clone(){
AiCfg onecfg;
AiCfg* cfg = &onecfg;//new AiCfg();
//
cfg->names.assign(names.begin(),names.end());
cfg->kind_inputs.assign(kind_inputs.begin(),kind_inputs.end());
cfg->name_inputs.assign(name_inputs.begin(),name_inputs.end());
cfg->size_inputs.assign(size_inputs.begin(),size_inputs.end());
//cfg->m_sizeinput = m_sizeinput;
for(int k=0;k<shape_inputs.size();k++){
std::vector<int64_t> shape(shape_inputs[k]);
cfg->shape_inputs.push_back(shape);
}
cfg->kind_outputs.assign(kind_outputs.begin(),kind_outputs.end());
cfg->name_outputs.assign(name_outputs.begin(),name_outputs.end());
cfg->size_outputs.assign(size_outputs.begin(),size_outputs.end());
//cfg->m_sizeoutput = m_sizeoutput;
for(int k=0;k<shape_outputs.size();k++){
std::vector<int64_t> shape(shape_outputs[k]);
cfg->shape_outputs.push_back(shape);
}
return onecfg;//cfg;
}
AiModel::AiModel(){
m_cfg = new AiCfg();
}
AiModel::~AiModel(){
delete m_cfg;
}
int AiModel::doInitModel(){
return -1;
}
AiCfg AiModel::config(){
return m_cfg->clone();
}
void AiModel::dump(){
m_cfg->dump();
}
int AiModel::pushName(const char* name,int input){
std::string sname(name);
m_cfg->names.push_back(sname);
if(input){
m_cfg->name_inputs.push_back(m_cfg->names[m_cfg->names.size()-1].c_str());
}else{
m_cfg->name_outputs.push_back(m_cfg->names[m_cfg->names.size()-1].c_str());
}
return 0;
}
int AiModel::initModel(std::string& modelpath){
m_modelPath = modelpath;
m_inited = doInitModel();
printf("===init %d\n",m_inited);
return m_inited;
}
int AiModel::initModel(std::string& binfn,std::string& paramfn){
m_modelbin = binfn;
m_modelparam = paramfn;
m_inited = doInitModel();
//printf("===init %d\n",m_inited);
return m_inited;
}
int AiModel::doRunModel(void** arrin,void** arrout,void* stream,AiCfg* pcfg){
return 0;
}
int AiModel::runModel(void** arrin,void** arrout,void* stream,AiCfg* pcfg){
if(m_inited){
//std::cout<<"model not inited:"<<m_inited<<std::endl;
return -999;
}
return doRunModel(arrin,arrout,stream,pcfg);
}
OnnxModel::OnnxModel(){
}
OnnxModel::OnnxModel(int b,int w,int h):AiModel(){
m_batch = b;
m_width = w;
m_height = h;
}
OnnxModel::~OnnxModel(){
}
int OnnxModel::doInitModel(){
env = Ort::Env(OrtLoggingLevel::ORT_LOGGING_LEVEL_WARNING, "ONNX");
sessionOptions = Ort::SessionOptions();
//std::vector<std::string> availableProviders = Ort::GetAvailableProviders();
//auto cudaAvailable = std::find(availableProviders.begin(), availableProviders.end(), "CUDAExecutionProvider");
//OrtCUDAProviderOptions cudaOption;
//if(cudaAvailable != availableProviders.end()){
//std::cout << "Inference device: GPU" << std::endl;
//sessionOptions.AppendExecutionProvider_CUDA(cudaOption);
//}else{
//std::cout << "Inference device: CPU" << std::endl;
//}
sessionOptions.SetIntraOpNumThreads(1);
sessionOptions.SetInterOpNumThreads(1);
// sessionOptions.AddConfigEntry("session.load_model_format", "ORT");
sessionOptions.AddConfigEntry("session.disable_prepacking", "1");
// sessionOptions.AddConfigEntry("session.use_ort_model_bytes_directly", "1");
session = Ort::Session(env, m_modelPath.c_str(), sessionOptions);
//Ort::AllocatorWithDefaultOptions allocator;
size_t numInputNodes = session.GetInputCount();
size_t numOutputNodes = session.GetOutputCount();
//std::cout << "input NUM: " << numInputNodes << std::endl;
//std::cout << "Output NUM: " << numOutputNodes << std::endl;
for(int k=0;k<numInputNodes;k++){
//m_cfg->name_inputs.push_back(session.GetInputName(k));//, allocator));
Ort::TypeInfo inputTypeInfo = session.GetInputTypeInfo(k);
auto tensorInfo = inputTypeInfo.GetTensorTypeAndShapeInfo();
auto elemType = tensorInfo.GetElementType();
m_cfg->kind_inputs.push_back((int)elemType);
std::vector<int64_t> inputTensorShape = tensorInfo.GetShape();
if(m_batch&&inputTensorShape.size()){
if(inputTensorShape[0]==-1)inputTensorShape[0]=m_batch;
}
if(m_batch&&(inputTensorShape.size()==4)){
if(inputTensorShape[0]==-1)inputTensorShape[0]=m_batch;
if(inputTensorShape[2]==-1)inputTensorShape[2]=m_height;
if(inputTensorShape[3]==-1)inputTensorShape[3]=m_width;
}
int size = 1;
for (auto shape : inputTensorShape){
size *= shape;
}
m_cfg->shape_inputs.push_back(inputTensorShape);
m_cfg->size_inputs.push_back(size);
}
for(int k=0;k<numOutputNodes;k++){
//m_cfg->name_outputs.push_back(session.GetOutputName(k));//, allocator));
Ort::TypeInfo outputTypeInfo = session.GetOutputTypeInfo(k);
auto tensorInfo = outputTypeInfo.GetTensorTypeAndShapeInfo();
auto elemType = tensorInfo.GetElementType();
m_cfg->kind_outputs.push_back((int)elemType);
std::vector<int64_t> outputTensorShape = tensorInfo.GetShape();
if(m_batch&&outputTensorShape.size()){
if(outputTensorShape[0]==-1)outputTensorShape[0]=m_batch;
}
if(m_batch&&(outputTensorShape.size()==4)){
if(outputTensorShape[0]==-1)outputTensorShape[0]=m_batch;
if(outputTensorShape[2]==-1)outputTensorShape[2]=m_height;
if(outputTensorShape[3]==-1)outputTensorShape[3]=m_width;
}
int size = 1;
for (auto shape : outputTensorShape){
size *= shape;
}
m_cfg->shape_outputs.push_back(outputTensorShape);
m_cfg->size_outputs.push_back(size);
}
return 0;
}
int OnnxModel::doRunModel(void** arrin,void** arrout,void* stream,AiCfg* pcfg){
AiCfg* cfg = pcfg==nullptr?m_cfg:pcfg;
int incnt = cfg->size_inputs.size();
int outcnt = cfg->size_outputs.size();
std::cout<<"run onnx:"<<outcnt<<std::endl;
if(!arrin || !arrout)return -1;
std::vector<Ort::Value> inputTensors;
Ort::MemoryInfo memoryInfo = Ort::MemoryInfo::CreateCpu( OrtAllocatorType::OrtArenaAllocator, OrtMemType::OrtMemTypeDefault);
for(int k=0;k<incnt;k++){
inputTensors.push_back(Ort::Value::CreateTensor( memoryInfo, arrin[k] ,cfg->size_inputs[k]*4 , cfg->shape_inputs[k].data(), cfg->shape_inputs[k].size(), (ONNXTensorElementDataType)cfg->kind_inputs[k] ));
}
std::vector<Ort::Value> outputTensors;
for(int k=0;k<outcnt;k++){
outputTensors.push_back(Ort::Value::CreateTensor( memoryInfo, arrout[k] ,cfg->size_outputs[k]*4 , cfg->shape_outputs[k].data(), cfg->shape_outputs[k].size(),(ONNXTensorElementDataType)cfg->kind_outputs[k] ));
}
this->session.Run(Ort::RunOptions{nullptr}, cfg->names_in, inputTensors.data(), incnt, cfg->names_out, outputTensors.data(),outcnt);
if(1)return 0;
/*
//for(int k=0;k<9;k++)dumpfloat((float*)arrout[k],10);//size_outputs[0]);
std::vector<Ort::Value> aoutputTensors = this->session.Run(Ort::RunOptions{nullptr}, name_inputs.data(), inputTensors.data(), 1, name_outputs.data(), 9);
//bool* pmsk = (bool*)aoutputTensors[1].GetTensorData<bool>();
for(int k=0;k<9;k++){
float* pbnf = (float*)aoutputTensors[0].GetTensorData<float>();
memcpy(arrout[k],pbnf,size_outputs[k]*4);
}
*/
return 0;
}
NcnnModel::NcnnModel():AiModel(){
}
NcnnModel::NcnnModel(int w,int h):AiModel(){
m_width = w;
m_height = h;
}
NcnnModel::~NcnnModel(){
net.clear();
}
int NcnnModel::doInitModel(){
net.clear();
net.load_param(m_modelparam.c_str());
net.load_model(m_modelbin.c_str());
return 0; //
}
int NcnnModel::doRunModel(void** arrin,void** arrout,void* stream,AiCfg* pcfg){
ncnn::Extractor ex = net.create_extractor();
AiCfg* cfg = pcfg==nullptr?m_cfg:pcfg;
int incnt = cfg->size_inputs.size();
int outcnt = cfg->size_outputs.size();
ncnn::Mat inmat[incnt];
for(int k=0;k<incnt;k++){
std::string name = cfg->name_inputs[k];
JMat* mat = (JMat*)arrin[k];
ncnn::Mat in_pack =mat->packingmat();
ex.input(name.c_str(), in_pack);
}
for(int k=0;k<outcnt;k++){
std::string name = cfg->name_outputs[k];
JMat* mat = (JMat*)arrout[k];
ncnn::Mat output;
ex.extract(name.c_str(), output);
ncnn::Mat in_park;
ncnn::convert_packing(output,in_park,3);
int size = mat->width()*mat->height()*3*sizeof(float);
memcpy((uint8_t*)mat->data(),in_park,size);
}
return 0;
}
#ifdef _TENSORRT_
#include "NvInferPlugin.h"
#include "cuda_runtime_api.h"
#include "cuda.h"
#define FPW 4
using namespace nvinfer1;
int TrtModel::doInitModel(){
std::cout<<"deserialize eng !"<<m_modelPath<<std::endl;
bool didInitPlugins = initLibNvInferPlugins(nullptr, "");
std::ifstream cache(m_modelPath,std::ios::binary);
cache.seekg(0,std::ios::end);
int engSize = cache.tellg();
if(!engSize)return -1;
cache.seekg(0,std::ios::beg);
void *modelMem = malloc(engSize);
if(!modelMem)return -2;
cache.read((char*)modelMem,engSize);
cache.close();
std::cout<<"deserialize size!"<<engSize<<std::endl;
IRuntime *runtime = nvinfer1::createInferRuntime(m_logger);
m_engine = runtime->deserializeCudaEngine(modelMem,engSize);
runtime->destroy();
free(modelMem);
if(! m_engine){
std::cout<<"deserialize eng error!"<<std::endl;
return -10;
}
std::cout<<"aaa"<<std::endl;
m_context = m_engine->createExecutionContext();
int bindings = m_engine->getNbBindings();
std::cout<<"bindings!"<<bindings<<std::endl;
for(int k=0;k<bindings;k++){
const char* name = m_engine->getBindingName(k);
std::string sname(name );
bool input = m_engine->bindingIsInput(k);
std::cout<<"name!"<<sname<<"===input"<<input<<std::endl;
Dims dims = m_engine->getBindingDimensions(k);
auto dt = m_engine->getBindingDataType(k);
int tdt = dt==DataType::kFLOAT?ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT:ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32;
std::vector<int64_t> tensorShape;
int dsize = 1;
for(int i = 0 ;i < dims.nbDims; i++){
tensorShape.push_back(dims.d[i]);
dsize *= dims.d[i];
//cout<<"==dsize!"<<dims.d[i]<<endl;
}
//cout<<"==========dsize!"<<dsize<<endl;
int size = dsize*FPW;//size_list[k];
if(input){
m_cfg->kind_inputs.push_back(tdt);
m_cfg->shape_inputs.push_back(tensorShape);
m_cfg->size_inputs.push_back(size);
m_cfg->name_inputs.push_back(name);
}else{
m_cfg->kind_outputs.push_back(tdt);
m_cfg->size_outputs.push_back(size);
m_cfg->name_outputs.push_back(name);
m_cfg->shape_outputs.push_back(tensorShape);
}
}
//getchar();
/*
m_sizeinput = 0;
for(int k=0;k<m_cfg->size_inputs.size();k++){
int size = m_cfg->size_inputs[k];
void* input ;
//int flag = cudaMalloc(&input,size);
//m_inputs.push_back(input);
//m_bindings[k]=input;
m_sizeinput += size;
//printf("===input %d output %d \n",m_sizeinput,m_sizeoutput);
}
std::cout<<"bbb"<<std::endl;
m_sizeoutput = 0;
int offset = m_cfg->size_inputs.size();
for(int k=0;k<m_cfg->size_outputs.size();k++){
int size = m_cfg->size_outputs[k];
void* output ;
//int flag = cudaMalloc(&output,size);
//m_outputs.push_back(output);
//m_bindings[offset+k]=output;
m_sizeoutput += size;
//printf("===input %d output %d \n",m_sizeinput,m_sizeoutput);
}
std::cout<<"ccc"<<std::endl;
*/
return 0;
}
int TrtModel::doRunModel(void** arrin,void** arrout,void* stream,AiCfg* pcfg){
AiCfg* cfg = pcfg==nullptr?m_cfg:pcfg;
int incnt = cfg->size_inputs.size();
int outcnt = cfg->size_outputs.size();
std::cout<<"incnt:"<<incnt<<"==outcnt:"<<outcnt<<std::endl;
std::vector<void*> m_bindings(incnt+outcnt,NULL);
for(int k=0;k<incnt;k++){
std::cout<<"in:"<<cfg->size_inputs[k]<<std::endl;
m_bindings[k] = arrin[k];
}
for(int k=0;k<outcnt;k++){
std::cout<<"out:"<<cfg->size_outputs[k]<<std::endl;
m_bindings[incnt+k] = arrout[k];
}
bool status = m_context->enqueue(1,m_bindings.data(),(cudaStream_t)stream,nullptr);
return status?0:-1;
}
TrtModel::TrtModel(int b,int w,int h):AiModel(){
}
TrtModel::TrtModel():AiModel(){
}
TrtModel::~TrtModel(){
if(m_context){
m_context->destroy();
m_context = nullptr;
}
if(m_engine){
m_engine->destroy();
m_engine = nullptr;
}
}
#endif
/*
int main(int argc,char** argv){
OnnxModel *model=new OnnxModel();
std::string fn = "onnx/mfcc.onnx";
model->initModel(fn);
delete model;
return 0;
}
*/

View File

@@ -1,136 +0,0 @@
#pragma once
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <algorithm>
#include "jmat.h"
struct AiCfg{
std::vector<int64_t> kind_inputs;
std::vector<int64_t> size_inputs;
std::vector<std::string> names;
std::vector<const char*> name_inputs;
//int m_sizeinput;
std::vector<std::vector<int64_t>> shape_inputs;
std::vector<int64_t> kind_outputs;
std::vector<int64_t> size_outputs;
std::vector<const char*> name_outputs;
//int m_sizeoutput;
std::vector<std::vector<int64_t>> shape_outputs;
const char** names_in;
const char** names_out;
void dump();
int inShape(int inx,int dim,int val);
int outShape(int inx,int dim,int val);
AiCfg clone();
};
class AiModel{
protected:
int m_inited;
std::string m_modelPath;
std::string m_modelbin;
std::string m_modelparam;
AiCfg *m_cfg;
virtual int doInitModel();
virtual int doRunModel(void** arrin,void** arrout,void* stream,AiCfg* pcfg=nullptr);
public:
void dump();
AiCfg config();
int pushName(const char* name,int input);
int initModel(std::string& modelpath);
int initModel(std::string& binfn,std::string& paramfn);
int runModel(void** arrin,void** arrout,void* stream,AiCfg* pcfg = nullptr);
AiModel();
virtual ~AiModel();
};
#define _ONNX_
#ifdef _ONNX_
#include "onnxruntime/onnxruntime_cxx_api.h"
class OnnxModel:public AiModel{
protected:
int m_batch = 0;
int m_width = 640;
int m_height = 960;
Ort::Env env{nullptr};
Ort::SessionOptions sessionOptions{nullptr};
Ort::Session session{nullptr};
int doInitModel()override;
int doRunModel(void** arrin,void** arrout,void* stream,AiCfg* pcfg=nullptr)override;
public:
OnnxModel(int b,int w,int h);
OnnxModel();
virtual ~OnnxModel();
};
#endif
#define _NCNN_
#ifdef _NCNN_
#include "ncnn/ncnn/net.h"
class NcnnModel:public AiModel{
protected:
int m_width = 160;
int m_height = 160;
ncnn::Net net;
int doInitModel()override;
int doRunModel(void** arrin,void** arrout,void* stream,AiCfg* pcfg=nullptr)override;
public:
NcnnModel(int w,int h);
NcnnModel();
virtual ~NcnnModel();
};
#endif
#ifdef _TENSORRT_
#include "NvInfer.h"
#include "NvInferLegacyDims.h"
#include "NvInferRuntime.h"
class Logger:public nvinfer1::ILogger {
public:
void log(nvinfer1::ILogger::Severity severity, const char *msg) noexcept override {
// suppress info-level messages
if (severity == Severity::kINFO)
return;
switch (severity) {
case Severity::kINTERNAL_ERROR:
std::cerr << "INTERNAL_ERROR: ";
break;
case Severity::kERROR:
std::cerr << "ERROR: ";
break;
case Severity::kWARNING:
std::cerr << "WARNING: ";
break;
case Severity::kINFO:
std::cerr << "INFO: ";
break;
default:
std::cerr << "UNKNOWN: ";
break;
}
std::cerr << msg << std::endl;
}
};
class TrtModel:public AiModel{
protected:
Logger m_logger;
nvinfer1::IExecutionContext *m_context;
nvinfer1::ICudaEngine *m_engine;
int doInitModel()override;
int doRunModel(void** arrin,void** arrout,void* stream,AiCfg* pcfg=nullptr)override;
public:
TrtModel(int b,int w,int h);
TrtModel();
virtual ~TrtModel();
};
#endif

View File

@@ -1,437 +0,0 @@
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "blendgram.h"
void exColorBlend_Normal(uint8* T,uint8* A,uint8* B){ ColorBlend_Buffer(T,A,B,Normal); }
void exColorBlend_Lighten(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,Lighten);}
void exColorBlend_Darken(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,Darken);}
void exColorBlend_Multiply(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,Multiply);}
void exColorBlend_Average(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,Average);}
void exColorBlend_Add(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,Add);}
void exColorBlend_Subtract(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,Subtract);}
void exColorBlend_Difference(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,Difference);}
void exColorBlend_Negation(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,Negation);}
void exColorBlend_Screen(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,Screen);}
void exColorBlend_Exclusion(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,Exclusion);}
void exColorBlend_Overlay(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,Overlay);}
void exColorBlend_SoftLight(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,SoftLight);}
void exColorBlend_HardLight(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,HardLight);}
void exColorBlend_ColorDodge(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,ColorDodge);}
void exColorBlend_ColorBurn(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,ColorBurn);}
void exColorBlend_LinearDodge(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,LinearDodge);}
void exColorBlend_LinearBurn(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,LinearBurn);}
void exColorBlend_LinearLight(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,LinearLight);}
void exColorBlend_VividLight(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,VividLight);}
void exColorBlend_PinLight(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,PinLight);}
void exColorBlend_HardMix(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,HardMix);}
void exColorBlend_Reflect(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,Reflect);}
void exColorBlend_Glow(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,Glow);}
void exColorBlend_Phoenix(uint8* T,uint8* A,uint8* B) { ColorBlend_Buffer(T,A,B,Phoenix);}
typedef void (*BlendFunc) (uint8* T,uint8* A,uint8* B);
static int MAX_FUNC = 25;
static BlendFunc blendfuncs[25]={
&exColorBlend_Normal,
&exColorBlend_Lighten,
&exColorBlend_Darken,
&exColorBlend_Multiply,
&exColorBlend_Average,
&exColorBlend_Add,
&exColorBlend_Subtract,
&exColorBlend_Difference,
&exColorBlend_Negation,
&exColorBlend_Screen,
&exColorBlend_Exclusion,
&exColorBlend_Overlay,
&exColorBlend_SoftLight,
&exColorBlend_HardLight,
&exColorBlend_ColorDodge,
&exColorBlend_ColorBurn,
&exColorBlend_LinearDodge,
&exColorBlend_LinearBurn,
&exColorBlend_LinearLight,
&exColorBlend_VividLight,
&exColorBlend_PinLight,
&exColorBlend_HardMix,
&exColorBlend_Reflect,
&exColorBlend_Glow,
&exColorBlend_Phoenix
};
void BlendGramSimp(unsigned char *Src,unsigned char* Mask, unsigned char *Dest, int Width, int Height, int Mode)
{
if(Mode<1)return;
if(Mode>=MAX_FUNC)return;
BlendFunc func=blendfuncs[Mode];
unsigned char *LinePS, *LinePD,*LinePM;
for (int Y = 0; Y < Height; Y += 1)
{
LinePS = Src + Y * Width * 4;
LinePM = Mask + Y * Width * 4;
LinePD = Dest + Y * Width * 4;
for (int X = 0; X < Width; X += 1)
{
func(LinePD,LinePS,LinePM);
LinePS += 4;
LinePM += 4;
LinePD += 4;
}
}
}
void BlendGramAlpha3(unsigned char *Src,unsigned char* Mask, unsigned char *Dest, int Width, int Height)
{
printf("w %d h %d\n",Width,Height);
unsigned char *LinePS, *LinePD,*LinePM;
for (int Y = 0; Y < Height; Y += 1)
{
LinePS = Src + Y * Width * 3;
LinePM = Mask + Y * Width * 3;
LinePD = Dest + Y * Width * 3;
for (int X = 0; X < Width; X += 1)
{
//func(LinePD,LinePS,LinePM);
//ColorBlend_Alpha(LinePD,LinePD,LinePS,*LinePM);
float alpha = *LinePM/255.0f;
float beta = 1.0f-alpha;
//if(beta<0.5f) printf("==alpha %f beta %f\n",alpha,beta);
//if(beta<0.5f) printf("od %u ps %u\n",LinePD[0],LinePS[0]);
LinePD[0] = CLAMPCOLOR( LinePD[0]*alpha+LinePS[0]*beta);
//if(beta<0.5f) printf("new %u ps%u \n",LinePD[0],LinePS[0]);
//if(beta<0.5f) getchar();
LinePD[1] = CLAMPCOLOR(LinePD[1]*alpha+LinePS[1]*beta);
LinePD[2] = CLAMPCOLOR( LinePD[2]*alpha+LinePS[2]*beta);
LinePS += 3;
LinePM += 3;
LinePD += 3;
}
}
}
void BlendGramAlpha(unsigned char *Src,unsigned char* Mask, unsigned char *Dest, int Width, int Height)
{
unsigned char *LinePS, *LinePD,*LinePM;
for (int Y = 0; Y < Height; Y += 1)
{
LinePS = Src + Y * Width * 3;
LinePM = Mask + Y * Width * 1;
LinePD = Dest + Y * Width * 3;
for (int X = 0; X < Width; X += 1)
{
//func(LinePD,LinePS,LinePM);
ColorBlend_Alpha(LinePD,LinePD,LinePS,*LinePM);
/*
float alpha = *LinePM/255.0f;
float beta = 1.0f-alpha;
//printf("==alpha %f beta %f\n",alpha,beta);
LinePD[0] = LinePD[0]*alpha+LinePS[0]*beta;
LinePD[1] = LinePD[1]*alpha+LinePS[1]*beta;
LinePD[2] = LinePD[2]*alpha+LinePS[2]*beta;
*/
LinePS += 3;
LinePM += 1;
LinePD += 3;
}
}
}
void BlendGramAlphaRev(unsigned char *Src,unsigned char* Mask, unsigned char *Dest, int Width, int Height)
{
unsigned char *LinePS, *LinePD,*LinePM;
for (int Y = 0; Y < Height; Y += 1)
{
LinePS = Src + Y * Width * 3;
LinePM = Mask + Y * Width * 1;
LinePD = Dest + Y * Width * 3;
for (int X = 0; X < Width; X += 1)
{
//func(LinePD,LinePS,LinePM);
ColorBlend_Alpha(LinePD,LinePS,LinePD,*LinePM);
LinePS += 3;
LinePM += 1;
LinePD += 3;
}
}
}
/*
void BlendGram(CBitmap* image,CBitmap* mask,int mode)
{
if(mode<1)return;
if(mode>=MAX_FUNC)return;
BlendFunc func=blendfuncs[mode];
int Stride=image->width*4;
unsigned char *LinePS, *LinePD,*LinePM;
for (int Y = 0; Y < image->height; Y += 1)
{
LinePS = (unsigned char*)image->pixels +image->stride*Y;
LinePM = (unsigned char*)mask->pixels + mask->stride*Y;
LinePD = (unsigned char*)image->pixels +image->stride*Y;
for (int X = 0; X < image->width; X += 1)
{
func(LinePD,LinePS,LinePM);
LinePS += 4;
LinePM += 4;
LinePD += 4;
}
}
}
void BlendImageAdjustWithMask(CBitmap* bmp,CBitmap* adj,CBitmap* dst ,CBitmap* msk,int mode)
{
unsigned char* bmppixels=(unsigned char*)bmp->pixels;
unsigned char* mskpixels=(unsigned char*)msk->pixels;
unsigned char* dstpixels=(unsigned char*)dst->pixels;
unsigned char* adjpixels=(unsigned char*)adj->pixels;
int stride=bmp->stride;
int width=bmp->width;
int height=bmp->height;
int X,Y;
unsigned char* LinePS , * LinePM , * LinePD , * LinePA ;
#pragma omp parallel for private(LinePS,LinePM,LinePD,LinePA,X,Y)
for (Y = 0; Y < height; Y ++)
{
int offset=stride*Y;
LinePS = bmppixels +offset;
LinePM = mskpixels +offset;
LinePD = dstpixels +offset;
LinePA = adjpixels +offset;
for (X = 0; X < width; X ++)
{
unsigned char M=*LinePM;
if(M==0xFF){
LinePD[0]=LinePS[0];
LinePD[1]=LinePS[1];
LinePD[2]=LinePS[2];
}else if(M==0x00){
LinePD[0]=LinePA[0];
LinePD[1]=LinePA[1];
LinePD[2]=LinePA[2];
}else{
ColorBlend_Alpha(LinePD,LinePS,LinePA,M);
}
LinePD[3]=LinePS[3];
LinePS += 4; LinePM += 4; LinePD += 4; LinePA += 4;
}
}
}
void BlendImageAdjustWithMaskEx(CBitmap* bmp,CBitmap* adj,CBitmap* dst ,CBitmap* msk,int mode)
{
unsigned char* bmppixels=(unsigned char*)bmp->pixels;
unsigned char* mskpixels=(unsigned char*)msk->pixels;
unsigned char* dstpixels=(unsigned char*)dst->pixels;
unsigned char* adjpixels=(unsigned char*)adj->pixels;
int stride=bmp->stride;
int width=bmp->width;
int height=bmp->height;
int X,Y;
unsigned char* LinePS , * LinePM , * LinePD , * LinePA ;
#pragma omp parallel for private(LinePS,LinePM,LinePD,LinePA,X,Y)
for (Y = 0; Y < height; Y ++)
{
int offset=stride*Y;
LinePS = bmppixels +offset;
LinePM = mskpixels +offset;
LinePD = dstpixels +offset;
LinePA = adjpixels +offset;
for (X = 0; X < width; X ++)
{
unsigned char M=*LinePM;
if(M==0xFF){
LinePD[0]=LinePS[0];
LinePD[1]=LinePS[1];
LinePD[2]=LinePS[2];
}else if(M==0x00){
LinePD[0]=LinePA[0];
LinePD[1]=LinePA[1];
LinePD[2]=LinePA[2];
}else{
//ColorBlend_Alpha(LinePD,LinePS,LinePA,M);
LinePD[0]=LinePS[0]*M>>8;
LinePD[1]=LinePS[1]*M>>8;
LinePD[2]=LinePS[2]*M>>8;
}
LinePD[3]=M;
LinePS += 4; LinePM += 4; LinePD += 4; LinePA += 4;
}
}
}
void BlendImageAdjustWithAlpha(CBitmap* bmp,CBitmap* adj,CBitmap* dst ,int alpha,int mode){
unsigned char* bmppixels=(unsigned char*)bmp->pixels;
unsigned char* dstpixels=(unsigned char*)dst->pixels;
unsigned char* adjpixels=(unsigned char*)adj->pixels;
int stride=bmp->stride;
int width=bmp->width;
int height=bmp->height;
int X,Y;
unsigned char M=CLAMPCOLOR(alpha);
unsigned char *LinePS , *LinePD , *LinePA ;
#pragma omp parallel for private(LinePS,LinePD,LinePA,X,Y)
for (Y = 0; Y < height; Y ++)
{
int offset=stride*Y;
LinePS = bmppixels +offset;
LinePD = dstpixels +offset;
LinePA = adjpixels +offset;
for (X = 0; X < width; X ++)
{
if(M==0xFF){
LinePD[0]=LinePS[0];
LinePD[1]=LinePS[1];
LinePD[2]=LinePS[2];
}else if(M==0x00){
LinePD[0]=LinePA[0];
LinePD[1]=LinePA[1];
LinePD[2]=LinePA[2];
}else{
ColorBlend_Alpha(LinePD,LinePS,LinePA,M);
}
LinePD[3]=LinePS[3];
LinePS += 4; LinePD += 4; LinePA += 4;
}
}
}
void BlendImageAdjustWithAlphaMask(CBitmap* bmp,CBitmap* adj,CBitmap* dst ,CBitmap* msk,int alpha,int mode){
unsigned char* bmppixels=(unsigned char*)bmp->pixels;
unsigned char* mskpixels=(unsigned char*)msk->pixels;
unsigned char* dstpixels=(unsigned char*)dst->pixels;
unsigned char* adjpixels=(unsigned char*)adj->pixels;
int stride=bmp->stride;
int width=bmp->width;
int height=bmp->height;
int X,Y;
unsigned char NM=CLAMPCOLOR(alpha);
unsigned char *LinePS , *LinePM , *LinePD , *LinePA ;
#pragma omp parallel for private(LinePS,LinePM,LinePD,LinePA,X,Y)
for (Y = 0; Y < height; Y ++)
{
int offset=stride*Y;
LinePS = bmppixels +offset;
LinePM = mskpixels +offset;
LinePD = dstpixels +offset;
LinePA = adjpixels +offset;
for (X = 0; X < width; X ++)
{
unsigned char M=*LinePM;
if(M==0xFF){
LinePD[0]=LinePS[0];
LinePD[1]=LinePS[1];
LinePD[2]=LinePS[2];
}else if(M==0x00){
if(NM==0xFF){
LinePD[0]=LinePS[0];
LinePD[1]=LinePS[1];
LinePD[2]=LinePS[2];
}else {
if(NM==0x00){
//none
LinePD[0]=LinePA[0];
LinePD[1]=LinePA[1];
LinePD[2]=LinePA[2];
}else{
ColorBlend_Alpha(LinePD,LinePS,LinePA,NM);
}
}
}else{
//
if(NM==0xFF){
LinePD[0]=LinePS[0];
LinePD[1]=LinePS[1];
LinePD[2]=LinePS[2];
}else{
if(NM==0x00){
ColorBlend_Alpha(LinePD,LinePS,LinePA,M);
}else{
ColorBlend_Alpha(LinePA,LinePS,LinePA,NM);
ColorBlend_Alpha(LinePD,LinePS,LinePA,M);
}
}
}
LinePD[3]=LinePS[3];
LinePS += 4; LinePM += 4; LinePD += 4; LinePA += 4;
}
}
}
void ReadAlphaBySrc(CBitmap* src,CBitmap* alpha){
memcpy(alpha,src,sizeof(CBitmap));
alpha->stride=src->width;
alpha->channel=1;
alpha->pixels=(CPixel*)malloc(alpha->width*alpha->height*sizeof(unsigned char));
unsigned char* bmppixels=(unsigned char*)src->pixels;
unsigned char* alapixels=(unsigned char*)alpha->pixels;
int stride=src->stride;
int width=src->width;
int height=src->height;
int X,Y;
unsigned char *LinePS , *LinePA;
//#pragma omp parallel for private(LinePS,LinePA)
for (Y = 0; Y < height; Y ++)
{
LinePS = bmppixels +stride*Y;
LinePA = alapixels +width*Y;
for (X = 0; X < width; X ++)
{
LinePA[0]=LinePS[3];
LinePS += 4; LinePA ++;
}
}
}
void CheckAlpha(CBitmap* bmp,CBitmap* alpha)
{
unsigned char* bmppixels=(unsigned char*)bmp->pixels;
unsigned char* alapixels=(unsigned char*)alpha->pixels;
int stride=bmp->stride;
int width=bmp->width;
int height=bmp->height;
int X,Y;
unsigned char *LinePS , *LinePA;
//#pragma omp parallel for private(LinePS,LinePA)
for (Y = 0; Y < height; Y ++)
{
LinePS = bmppixels +stride*Y;
LinePA = alapixels +width*Y;
for (X = 0; X < width; X ++)
{
//unsigned char M=LinePA[0];
if(*LinePA==0x00){
LinePS[0]=0;
LinePS[1]=0;
LinePS[2]=0;
LinePS[3]=0;
//}else if(M<0xff){
//if(LinePD[0]>M)LinePD[0]=M;
//if(LinePD[1]>M)LinePD[1]=M;
//if(LinePD[2]>M)LinePD[2]=M;
//LinePD[3]=M;
}else{
}
LinePS += 4; LinePA++;
}
}
}
*/

View File

@@ -1,287 +0,0 @@
#ifndef __BLENDGRAM_H__
#define __BLENDGRAM_H__
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
typedef unsigned char uchar;
#define CLAMPCOLOR(x) (uchar)((x)<(0)?(0):((x)>(255)?(255):(x)))
#define MMAX(A,B) ((A)>(B)?(A):(B))
#define MMIN(A,B) ((A)<(B)?(A):(B))
static int ConstBlend_Buffer = 0;
static int ConstBlend_Normal=ConstBlend_Buffer+1;
static int ConstBlend_Lighten=ConstBlend_Buffer+2;
static int ConstBlend_Darken=ConstBlend_Buffer+3;
static int ConstBlend_Multiply=ConstBlend_Buffer+4;
static int ConstBlend_Average=ConstBlend_Buffer+5;
static int ConstBlend_Add=ConstBlend_Buffer+6;
static int ConstBlend_Subtract=ConstBlend_Buffer+7;
static int ConstBlend_Difference=ConstBlend_Buffer+8;
static int ConstBlend_Negation=ConstBlend_Buffer+9;
static int ConstBlend_Screen=ConstBlend_Buffer+10;
static int ConstBlend_Exclusion=ConstBlend_Buffer+11;
static int ConstBlend_Overlay=ConstBlend_Buffer+12;
static int ConstBlend_SoftLight=ConstBlend_Buffer+13;
static int ConstBlend_HardLight=ConstBlend_Buffer+14;
static int ConstBlend_ColorDodge=ConstBlend_Buffer+15;
static int ConstBlend_ColorBurn=ConstBlend_Buffer+16;
static int ConstBlend_LinearDodge=ConstBlend_Buffer+17;
static int ConstBlend_LinearBurn=ConstBlend_Buffer+18;
static int ConstBlend_LinearLight=ConstBlend_Buffer+19;
static int ConstBlend_VividLight=ConstBlend_Buffer+20;
static int ConstBlend_PinLight=ConstBlend_Buffer+21;
static int ConstBlend_HardMix=ConstBlend_Buffer+22;
static int ConstBlend_Reflect=ConstBlend_Buffer+23;
static int ConstBlend_Glow=ConstBlend_Buffer+24;
static int ConstBlend_Phoenix=ConstBlend_Buffer+25;
//void BlendGram(CBitmap* immage,CBitmap* mask,int mode);
//#typedef unsigned char uint8
#define uint8 unsigned char
#define float64 double
#define TRUE 1
#define FALSE 0
inline uint8 mmin(uint8 A,uint8 B){
return A<B?A:B;
}
inline uint8 mmax(uint8 A,uint8 B){
return A>B?A:B;
}
#define ChannelBlend_Normal(A,B) ((uint8)(A))
#define ChannelBlend_Lighten(A,B) ((uint8)((B > A) ? B:A))
#define ChannelBlend_Darken(A,B) ((uint8)((B > A) ? A:B))
#define ChannelBlend_Multiply(A,B) ((uint8)((A * B) / 255))
#define ChannelBlend_Average(A,B) ((uint8)((A + B) / 2))
#define ChannelBlend_Add(A,B) ((uint8)(mmin(255, (A + B))))
#define ChannelBlend_Subtract(A,B) ((uint8)((A + B < 255) ? 0:(A + B - 255)))
#define ChannelBlend_Difference(A,B) ((uint8)(abs(A - B)))
#define ChannelBlend_Negation(A,B) ((uint8)(255 - abs(255 - A - B)))
#define ChannelBlend_Screen(A,B) ((uint8)(255 - (((255 - A) * (255 - B)) >> 8)))
#define ChannelBlend_Exclusion(A,B) ((uint8)(A + B - 2 * A * B / 255))
#define ChannelBlend_Overlay(A,B) ((uint8)((B < 128) ? (2 * A * B / 255):(255 - 2 * (255 - A) * (255 - B) / 255)))
#define ChannelBlend_SoftLight(A,B) ((uint8)((B < 128)?(2*((A>>1)+64))*((float)B/255):(255-(2*(255-((A>>1)+64))*(float)(255-B)/255))))
#define ChannelBlend_HardLight(A,B) (ChannelBlend_Overlay(B,A))
#define ChannelBlend_ColorDodge(A,B) ((uint8)((B == 255) ? B:mmin(255, ((A << 8 ) / (255 - B)))))
#define ChannelBlend_ColorBurn(A,B) ((uint8)((B == 0) ? B:mmax(0, (255 - ((255 - A) << 8 ) / B))))
#define ChannelBlend_LinearDodge(A,B)(ChannelBlend_Add(A,B))
#define ChannelBlend_LinearBurn(A,B) (ChannelBlend_Subtract(A,B))
#define ChannelBlend_LinearLight(A,B)((uint8)(B < 128)?ChannelBlend_LinearBurn(A,(2 * B)):ChannelBlend_LinearDodge(A,(2 * (B - 128))))
#define ChannelBlend_VividLight(A,B) ((uint8)(B < 128)?ChannelBlend_ColorBurn(A,(2 * B)):ChannelBlend_ColorDodge(A,(2 * (B - 128))))
#define ChannelBlend_PinLight(A,B) ((uint8)(B < 128)?ChannelBlend_Darken(A,(2 * B)):ChannelBlend_Lighten(A,(2 * (B - 128))))
#define ChannelBlend_HardMix(A,B) ((uint8)((ChannelBlend_VividLight(A,B) < 128) ? 0:255))
#define ChannelBlend_Reflect(A,B) ((uint8)((B == 255) ? B:mmin(255, (A * A / (255 - B)))))
#define ChannelBlend_Glow(A,B) (ChannelBlend_Reflect(B,A))
#define ChannelBlend_Phoenix(A,B) ((uint8)(mmin(A,B) - mmax(A,B) + 255))
#define ChannelBlend_SoftEx(A,B) (A*B/255+A*(255-((255-A)*(255-B)/255)-A*B/255)/255)
#define ChannelBlend_Alpha(A,B,O) ((uint8)(O * A + (1 - O) * B))
#define ChannelBlend_AlphaEx(A,B,O) ((uint8)((O * A + (255 - O) * B)/255))
#define ChannelBlend_AlphaF(A,B,F,O) (ChannelBlend_AlphaEx(F(A,B),A,O))
#define ColorBlend_Alpha(T,A,B,O) (T)[0] = ChannelBlend_AlphaEx((A)[0], (B)[0],O), (T)[1] = ChannelBlend_AlphaEx((A)[1], (B)[1],O), (T)[2] = ChannelBlend_AlphaEx((A)[2], (B)[2],O)
//, (T)[3] = ChannelBlend_AlphaEx((A)[3], (B)[3],O)
#define ColorBlend_AlphaF(T,A,B,F,O) (T)[0] = ChannelBlend_AlphaF((A)[0], (B)[0],F,O), (T)[1] = ChannelBlend_AlphaF((A)[1], (B)[1],F,O), (T)[2] = ChannelBlend_AlphaF((A)[2], (B )[2],F,O) , (T)[3] = ChannelBlend_AlphaEx((A)[3], (B)[3],O)
#define ColorBlend_Buffer(T,A,B,M) (T)[0] = ChannelBlend_##M((A)[0], (B)[0]), (T)[1] = ChannelBlend_##M((A)[1], (B)[1]), (T)[2] = ChannelBlend_##M((A)[2], (B)[2])
#define ColorBlend_Normal(T,A,B) (ColorBlend_Buffer(T,A,B,Normal))
#define ColorBlend_Lighten(T,A,B) (ColorBlend_Buffer(T,A,B,Lighten))
#define ColorBlend_Darken(T,A,B) (ColorBlend_Buffer(T,A,B,Darken))
#define ColorBlend_Multiply(T,A,B) (ColorBlend_Buffer(T,A,B,Multiply))
#define ColorBlend_Average(T,A,B) (ColorBlend_Buffer(T,A,B,Average))
#define ColorBlend_Add(T,A,B) (ColorBlend_Buffer(T,A,B,Add))
#define ColorBlend_Subtract(T,A,B) (ColorBlend_Buffer(T,A,B,Subtract))
#define ColorBlend_Difference(T,A,B) (ColorBlend_Buffer(T,A,B,Difference))
#define ColorBlend_Negation(T,A,B) (ColorBlend_Buffer(T,A,B,Negation))
#define ColorBlend_Screen(T,A,B) (ColorBlend_Buffer(T,A,B,Screen))
#define ColorBlend_Exclusion(T,A,B) (ColorBlend_Buffer(T,A,B,Exclusion))
#define ColorBlend_Overlay(T,A,B) (ColorBlend_Buffer(T,A,B,Overlay))
#define ColorBlend_SoftLight(T,A,B) (ColorBlend_Buffer(T,A,B,SoftLight))
#define ColorBlend_HardLight(T,A,B) (ColorBlend_Buffer(T,A,B,HardLight))
#define ColorBlend_ColorDodge(T,A,B) (ColorBlend_Buffer(T,A,B,ColorDodge))
#define ColorBlend_ColorBurn(T,A,B) (ColorBlend_Buffer(T,A,B,ColorBurn))
#define ColorBlend_LinearDodge(T,A,B) (ColorBlend_Buffer(T,A,B,LinearDodge))
#define ColorBlend_LinearBurn(T,A,B) (ColorBlend_Buffer(T,A,B,LinearBurn))
#define ColorBlend_LinearLight(T,A,B) (ColorBlend_Buffer(T,A,B,LinearLight))
#define ColorBlend_VividLight(T,A,B) (ColorBlend_Buffer(T,A,B,VividLight))
#define ColorBlend_PinLight(T,A,B) (ColorBlend_Buffer(T,A,B,PinLight))
#define ColorBlend_HardMix(T,A,B) (ColorBlend_Buffer(T,A,B,HardMix))
#define ColorBlend_Reflect(T,A,B) (ColorBlend_Buffer(T,A,B,Reflect))
#define ColorBlend_Glow(T,A,B) (ColorBlend_Buffer(T,A,B,Glow))
#define ColorBlend_Phoenix(T,A,B) (ColorBlend_Buffer(T,A,B,Phoenix))
#define ColorBlend_Hue(T,B,L) ColorBlend_Hls(T,B,L,HueL,LuminationB,SaturationB)
#define ColorBlend_Saturation(T,B,L) ColorBlend_Hls(T,B,L,HueB,LuminationB,SaturationL)
#define ColorBlend_Color(T,B,L) ColorBlend_Hls(T,B,L,HueL,LuminationB,SaturationL)
#define ColorBlend_Luminosity(T,B,L) ColorBlend_Hls(T,B,L,HueB,LuminationL,SaturationB)
#define ColorBlend_Hls(T,B,L,O1,O2,O3) { \
float64 HueB, LuminationB, SaturationB; \
float64 HueL, LuminationL, SaturationL; \
Color_RgbToHls((B)[2],(B)[1],(B)[0], &HueB, &LuminationB, &SaturationB); \
Color_RgbToHls((L)[2],(L)[1],(L)[0], &HueL, &LuminationL, &SaturationL); \
Color_HlsToRgb(O1,O2,O3,&(T)[2],&(T)[1],&(T)[0]); \
}
/*********************************************************************/
#define COLOR_OPAQUE (0)
#define COLOR_TRANSPARENT (127)
#define RGB_SIZE (3)
#define RGB_BPP (24)
#define RGB_MAXRED (255)
#define RGB_MAXGREEN (255)
#define RGB_MAXBLUE (255)
#define ARGB_SIZE (4)
#define ARGB_BPP (32)
#define ARGB_MAXALPHA (127)
#define ARGB_MAXRED (RGB_MAXRED)
#define ARGB_MAXGREEN (RGB_MAXGREEN)
#define ARGB_MAXBLUE (RGB_MAXBLUE)
/*********************************************************************/
#define Color_GetChannel(c,shift) ((uint8)((c) >> (shift)))
#define Color_Reverse(c,bpp) ((((uint8)(c) << 24) | ((uint8)((c) >> 8 ) << 16) | ((uint8)((c) >> 16) << 8 ) | \ ((uint8)((c) >> 24))) >> (32 - (bpp)))
#define Rgb_ByteWidth(width) ((width) * RGB_SIZE)
#define Rgb_PixelWidth(width) ((width) / RGB_SIZE)
#define Rgb_GetRed(rgb) (Color_GetChannel(rgb, 0))
#define Rgb_GetGreen(rgb) (Color_GetChannel(rgb, 8))
#define Rgb_GetBlue(rgb) (Color_GetChannel(rgb, 16))
#define Rgba_GetRed(rgba) (Color_GetChannel(rgba, 24))
#define Rgba_GetGreen(rgba) (Color_GetChannel(rgba, 16))
#define Rgba_GetBlue(rgba) (Color_GetChannel(rgba, 8))
#define Rgba_GetAlpha(rgba) (Color_GetChannel(rgba, 0))
#define Argb_GetAlpha(argb) (Color_GetChannel(argb, 24))
#define Argb_GetRed(argb) (Color_GetChannel(argb, 16))
#define Argb_GetGreen(argb) (Color_GetChannel(argb, 8))
#define Argb_GetBlue(argb) (Color_GetChannel(argb, 0))
#define MakeRgb(r,g,b) (((uint32)(uint8)(b) << 16) | ((uint16)(uint8)(g) << 8 ) | (uint8)(r))
#define MakeRgba(r,g,b,a) (((uint32)(uint8)(r) << 24) | ((uint16)(uint8)(g) << 16) | ((uint16)(uint8)(b) << 8 ) | (uint8)(a))
#define MakeArgb(a,r,g,b) (((uint32)(uint8)(a) << 24) | ((uint32)(uint8)(r) << 16) | ((uint16)(uint8)(g) << 8 ) | (uint8)(b))
#define HexToRgb(hex) (MakeRgb(((hex & 0xFF0000) >> 16), ((hex & 0x00FF00) >> 8 ), (hex & 0xFF)))
inline int Color_HueToRgb(float64 M1, float64 M2, float64 Hue, float64 *Channel)
{
if (Hue < 0.0)
Hue += 1.0;
else if (Hue > 1.0)
Hue -= 1.0;
if ((6.0 * Hue) < 1.0)
*Channel = (M1 + (M2 - M1) * Hue * 6.0);
else if ((2.0 * Hue) < 1.0)
*Channel = (M2);
else if ((3.0 * Hue) < 2.0)
*Channel = (M1 + (M2 - M1) * ((2.0F / 3.0F) - Hue) * 6.0);
else
*Channel = (M1);
return TRUE;
}
inline void Color_RgbToHls(uint8 Red, uint8 Green, uint8 Blue, float64 *Hue, float64 *Lumination, float64 *Saturation)
{
float64 Delta;
float64 Max, Min;
float64 Redf, Greenf, Bluef;
Redf = (float64)Red / 255.0;
Greenf = (float64)Green / 255.0;
Bluef = (float64)Blue / 255.0;
//Max = fmax(fmax(Redf, Greenf), Bluef);
//Min = fmin(fmin(Redf, Greenf), Bluef);
Max = MMAX(MMAX(Red, Green), Blue)/255.0;
Min = MMIN(MMIN(Red, Green), Blue)/255.0;
*Hue = 0;
*Lumination = (Max + Min) / 2.0F;
*Saturation = 0;
if (Max == Min)
return ;
Delta = (Max - Min);
if (*Lumination < 0.5)
*Saturation = Delta / (Max + Min);
else
*Saturation = Delta / (2.0 - Max - Min);
if (Redf == Max)
*Hue = (Greenf - Bluef) / Delta;
else if (Greenf == Max)
*Hue = 2.0 + (Bluef - Redf) / Delta;
else
*Hue = 4.0 + (Redf - Greenf) / Delta;
*Hue /= 6.0;
if (*Hue < 0.0)
*Hue += 1.0;
}
inline void Color_HlsToRgb(float64 Hue, float64 Lumination, float64 Saturation, uint8 *Red, uint8 *Green, uint8 *Blue)
{
float64 M1, M2;
float64 Redf, Greenf, Bluef;
if (Saturation == 0) {
Redf = Lumination;
Greenf = Lumination;
Bluef = Lumination;
} else {
if (Lumination <= 0.5)
M2 = Lumination * (1.0 + Saturation);
else
M2 = Lumination + Saturation - Lumination * Saturation;
M1 = (2.0 * Lumination - M2);
Color_HueToRgb(M1, M2, Hue + (1.0F / 3.0F), &Redf);
Color_HueToRgb(M1, M2, Hue, &Greenf);
Color_HueToRgb(M1, M2, Hue - (1.0F / 3.0F), &Bluef);
}
*Red = (uint8)(Redf * 255);
*Blue = (uint8)(Bluef * 255);
*Green = (uint8)(Greenf * 255);
}
void BlendGramSimp(unsigned char *Src,unsigned char* Mask, unsigned char *Dest, int Width, int Height, int Mode);
void BlendGramAlpha(unsigned char *Src,unsigned char* Mask, unsigned char *Dest, int Width, int Height);
void BlendGramAlpha3(unsigned char *Src,unsigned char* Mask, unsigned char *Dest, int Width, int Height);
void BlendGramAlphaRev(unsigned char *Src,unsigned char* Mask, unsigned char *Dest, int Width, int Height);
/*
void BlendImageAdjustWithMask(CBitmap* bmp,CBitmap* adj,CBitmap* dst ,CBitmap* msk,int mode);
void BlendImageAdjustWithMaskEx(CBitmap* bmp,CBitmap* adj,CBitmap* dst ,CBitmap* msk,int mode);
void BlendImageAdjustWithAlpha(CBitmap* bmp,CBitmap* adj,CBitmap* dst ,int alpha,int mode);
void BlendImageAdjustWithAlphaMask(CBitmap* bmp,CBitmap* adj,CBitmap* dst ,CBitmap* msk,int alpha,int mode);
void CheckAlpha(CBitmap* bmp,CBitmap* alpha);
void ReadAlphaBySrc(CBitmap* src,CBitmap* alpha);
*/
#endif

View File

@@ -1,114 +0,0 @@
#include "face_utils.h"
//#include <sys/timeb.h>
cv::Mat resize_image(cv::Mat srcimg, int height, int width, int* top, int* left){
cv::Mat dstimg;
int srch = srcimg.rows, srcw = srcimg.cols;
int neww = width;
int newh = height;
if (srch != srcw) {
float hw_scale = (float)srch / srcw;
if (hw_scale > 1) {
newh = height;
neww = int(width / hw_scale);
cv::resize(srcimg, dstimg, cv::Size(neww, newh), cv::INTER_AREA);
*left = int((width - neww) * 0.5);
cv::copyMakeBorder(dstimg, dstimg, 0, 0, *left, width - neww - *left, cv::BORDER_CONSTANT, 0);
}
else
{
newh = (int)height * hw_scale;
neww = width;
cv::resize(srcimg, dstimg,cv::Size(neww, newh), cv::INTER_AREA);
*top = (int)(height - newh) * 0.5;
cv::copyMakeBorder(dstimg, dstimg, *top, height - newh - *top, 0, 0, cv::BORDER_CONSTANT, 0);
}
} else {
cv::resize(srcimg, dstimg, cv::Size(neww, newh), cv::INTER_AREA);
}
return dstimg;
}
int dumpfile(char* file,char** pbuf){
std::string fname(file);
std::ifstream cache(fname,std::ios::binary);
cache.seekg(0,std::ios::end);
const int engSize = cache.tellg();
cache.seekg(0,std::ios::beg);
char *modelMem = (char*)malloc(engSize+8000);
cache.read(modelMem,engSize);
cache.close();
*pbuf = modelMem;
return engSize;
}
void dumpchar(char* abuf,int len){
uint8_t* buf = (uint8_t*)abuf;
printf("\n----------------------chardump------------------------\n");
int i;
for(i = 0; i < len; i++) {
printf("=%u=", buf[i]);
if( (i+1) % 16 == 0) {
printf("\n");
}
}
if(i%16 != 0) {
printf("\n");
}
printf("\n----------------------chardump------------------------\n");
}
void dumpfloat(float* abuf,int len){
printf("\n----------------------floatdump------------------------\n");
int i;
for(i = 0; i < len; i++) {
printf("=%f=", abuf[i]);
if( (i+1) % 16 == 0) {
printf("\n");
}
}
if(i%16 != 0) {
printf("\n");
}
printf("\n----------------------floatdump------------------------\n");
}
void dumphex(char* abuf,int len){
unsigned char* buf = (unsigned char*)abuf;
int i = 0;
printf("\n----------------------hexdump------------------------\n");
for(i = 0; i < len; i++) {
printf("=%02x=", buf[i]);
if( (i+1) % 16 == 0) {
printf("\n");
}
}
if(i%16 != 0) {
printf("\n");
}
printf("---------------------hexdump-------------------------\n\n");
}
int diffbuf(char* abuf,char* bbuf,int size){
char* pa = abuf;
char* pb = bbuf;
int diff = 0;
for(int k= 0;k<size;k++){
if(*pa++==*pb++){
}else{
diff++;
}
}
return diff;
}
uint64_t timer_msstamp() {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (ts.tv_sec*1000l) + (ts.tv_nsec/CLOCKS_PER_SEC);
}

View File

@@ -1,20 +0,0 @@
#pragma once
#include <fstream>
#include <sstream>
#include <iostream>
#include <vector>
//#include <opencv2/dnn.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
cv::Mat resize_image(cv::Mat srcimg, int height, int width, int* top, int* left);
void dumpchar(char* abuf,int len);
void dumphex(char* abuf,int len);
void dumpfloat(float* abuf,int len);
void dumpdouble(double* abuf,int len);
int dumpfile(char* file,char** pbuf);
int diffbuf(char* abuf,char* bbuf,int size);
uint64_t timer_msstamp();

View File

@@ -1,31 +0,0 @@
#pragma once
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef LIB_JNI
#include <jni.h>
#include <android/log.h>
#define LOG_TAG "tooken"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#else
#define LOGE(...) printf(__VA_ARGS__)
#define LOGI(...) printf(__VA_ARGS__)
#define LOGD(...) printf(__VA_ARGS__)
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -1,409 +0,0 @@
#include "jmat.h"
extern "C"{
#pragma pack(push)
#pragma pack(4)
#pragma pack(pop)
typedef struct _gpg_hdr {
char head[4];
int box[4];
int size[4];
int width[4];
int height[4];
uint8_t channel[4];
uint8_t bit[4];
}gpg_hdr;
}
int JBuf::zeros(){
memset(m_buf,0,m_size);
return m_size;
}
int JBuf::forceref(int bref){
if(m_ref!=bref){
m_ref = bref;
}
return 0;
}
JBuf::JBuf(uint32_t size,void* buf ){
if(buf){
m_ref = true;
m_buf = buf;
m_size = size;
}else{
m_ref = false;
m_size = size;
m_buf = malloc(size+1024);
}
}
JBuf::~JBuf(){
if(!m_ref){
free(m_buf);
m_buf = nullptr;
}
}
JBuf::JBuf(){
m_size = 0;
m_buf = nullptr;
}
JMat::JMat(){
init_tagarr();
}
void JMat::init_tagarr(){
memset(m_tagarr,0,512*sizeof(int));
}
int* JMat::tagarr(){
return m_tagarr;
}
int JMat::savegpg(std::string gpgfile){
gpg_hdr ghead;
memset(&ghead,0,sizeof(gpg_hdr));
ghead.head[0]='g';
ghead.head[1]='p';
ghead.head[2]='g';
ghead.head[3]='1';
ghead.size[0]=m_size;
ghead.width[0]=m_width;
ghead.height[0]=m_height;
ghead.channel[0]=m_channel;
ghead.bit[0]=m_bit;
FILE *gpgFile = NULL;
const char* fn = gpgfile.c_str();
if ((gpgFile = fopen(fn, "wb")) == NULL)return -1;
fwrite(&ghead,sizeof(gpg_hdr),1,gpgFile);
fwrite(m_buf, m_size, 1, gpgFile);
fclose(gpgFile);
return 0;
}
int JMat::load(std::string picfile){
const char* fn = picfile.c_str();
int len = strlen(fn);
if(len<4)return -1;
fn+= len-3;
int gpg = (fn[0]=='g')&&(fn[1]=='p')&&(fn[2]=='g');
if(gpg){
return loadgpg(picfile);
}else{
return loadjpg(picfile);
}
}
int JMat::loadgpg(std::string gpgfile){
FILE *gpgFile = NULL;
const char* fn = gpgfile.c_str();
if ((gpgFile = fopen(fn, "rb")) == NULL)return -1;
int rst = 0;
while(1){
gpg_hdr ghead;
memset(&ghead,0,sizeof(gpg_hdr));
fread(&ghead,sizeof(gpg_hdr),1,gpgFile);
char* arr=ghead.head;
if((arr[0]=='g')&&
(arr[1]=='p')&&
(arr[2]=='g')){
int imgSize = ghead.size[0];
if(m_size<imgSize){
if((!m_ref)&&m_buf)free(m_buf);
m_buf = malloc(imgSize);
}
m_size = imgSize;
m_width = ghead.width[0];
m_height = ghead.height[0];
m_channel = ghead.channel[0];
m_bit = ghead.bit[0];
fread(m_buf, m_size, 1, gpgFile);
}else{
rst = -11;
}
break;
}
fclose(gpgFile);
return rst;
}
#ifdef USE_TURBOJPG
#include "turbojpeg.h"
int JMat::loadjpg(std::string picfile,int flag){
tjhandle tjInstance = NULL;
int rst = 0;
size_t jpegSize = 0;
size_t imgSize = 0;
int newbuf = 0;
unsigned char *jpegBuf = NULL;
if(1){
long size;
FILE *jpegFile = NULL;
const char* fn = picfile.c_str();
if ((jpegFile = fopen(fn, "rb")) == NULL)return -1;
if (fseek(jpegFile, 0, SEEK_END) < 0 || ((size = ftell(jpegFile)) < 0) || (fseek(jpegFile, 0, SEEK_SET) < 0)){
fclose(jpegFile);
return -2;
}
if (size == 0){
fclose(jpegFile);
return -3;
}
jpegSize = size;
jpegBuf = (unsigned char*)tj3Alloc(jpegSize);
fread(jpegBuf, jpegSize, 1, jpegFile);
fclose(jpegFile);
}
if ((tjInstance = tj3Init(TJINIT_DECOMPRESS)) == NULL)return -11;
while(1){
unsigned char *imgBuf = NULL;
int w, h;
int inSubsamp, inColorspace;
int pixelFormat = TJPF_BGR;
rst = tj3DecompressHeader(tjInstance, jpegBuf, jpegSize);
if(rst<0){
rst = -12;
break;
}
w = tj3Get(tjInstance, TJPARAM_JPEGWIDTH);
h = tj3Get(tjInstance, TJPARAM_JPEGHEIGHT);
inSubsamp = tj3Get(tjInstance, TJPARAM_SUBSAMP);
inColorspace = tj3Get(tjInstance, TJPARAM_COLORSPACE);
imgSize = w * h * tjPixelSize[pixelFormat];
if(imgSize <0){
rst = -13;
break;
}
//printf("===imgSize %d m_size %d\n",imgSize,m_size);
if(m_size<imgSize){
if((!m_ref)&&m_buf)free(m_buf);
m_buf = malloc(imgSize);
m_ref = 0;
}
m_size = imgSize;
imgBuf = (unsigned char *)m_buf;
if(tj3Decompress8(tjInstance, jpegBuf, jpegSize, imgBuf, 0, pixelFormat) < 0){
rst = -15;
break;
}
m_ref = 0;
m_bit = 1;
m_channel = 3;
m_stride = w*3;
m_width = w;
m_height = h;
break;
}
if(jpegBuf)tj3Free(jpegBuf);
jpegBuf = NULL;
tj3Destroy(tjInstance);
tjInstance = NULL;
return rst;
}
#else
int JMat::loadjpg(std::string picfile,int flag){
return -1;
}
#endif
JMat::JMat(int w,int h,float *buf ,int c ,int d ):JBuf(){
m_bit = sizeof(float);
m_width = w;
m_height = h;
m_channel = c;
m_stride = d?d:w*c;
m_size = m_bit*m_stride*m_height;
m_buf = buf;
m_ref = 1;
init_tagarr();
}
JMat::JMat(int w,int h,uint8_t *buf ,int c ,int d ):JBuf(){
m_bit = 1;
m_width = w;
m_height = h;
m_channel = c;
m_stride = d?d:w*c;
m_size = m_bit*m_stride*m_height;
m_buf = buf;
m_ref = 1;
init_tagarr();
}
JMat::JMat(int w,int h,int c ,int d ,int b):JBuf(){
m_bit = b==0?sizeof(float):b;
m_width = w;
m_height = h;
m_channel = c;
m_stride = d?d:w*c;
m_size = m_bit*m_stride*m_height;
//printf("===mat %d size %d\n",m_bit,m_size);
m_buf = malloc(m_size+m_bit*m_stride);
memset(m_buf,0,m_size+m_bit*m_stride);
m_ref = 0;
init_tagarr();
}
#ifdef USE_OPENCV
cv::Mat JMat::cvmat(){
if(m_channel == 3){
cv::Mat rrr(m_height,m_width,m_bit==1?CV_8UC3:CV_32FC3,m_buf);
return rrr;
}else if(m_channel == 1){
cv::Mat rrr(m_height,m_width,m_bit==1?CV_8UC1:CV_32FC1,m_buf);
return rrr;
}else{
cv::Mat rrr(m_height,m_width*m_channel,m_bit==1?CV_8UC1:CV_32FC1,m_buf);
return rrr;
}
}
int JMat::show(const char* title){
std::string name(title);
cv::Mat mat(m_height,m_width,m_channel==3?CV_8UC3:CV_8UC1,m_buf);
cv::imshow(name,mat);
return 0;
}
int JMat::tojpg(const char* fn){
cv::Mat mat(m_height,m_width,CV_8UC3,m_buf);
std::string name(fn);
return cv::imwrite(name,mat);
}
#else
int JMat::show(const char* title){
return 0;
}
int JMat::tojpg(const char* fn){
return 0;
}
#endif
int JMat::tobin(const char* fn){
FILE* file = fopen(fn, "w");
if(!file)return 0;
fwrite(m_buf, m_size, 1, file);
fclose(file);
return 1;
}
JMat* JMat::refclone(int ref){
if(ref){
if(m_bit==1){
return new JMat(m_width,m_height,(uint8_t*)m_buf,m_channel,m_stride);
}else{
return new JMat(m_width,m_height,(float*)m_buf,m_channel,m_stride);
}
}else{
JMat* cm = new JMat(m_width,m_height,m_channel,m_stride,m_bit);
memcpy(cm->m_buf,m_buf,m_size);
memcpy(cm->m_tagarr,m_tagarr,512*sizeof(int));
return cm;
}
}
JMat JMat::clone(){
JMat cm(m_width,m_height,m_channel,m_stride,m_bit);
memcpy(cm.m_buf,m_buf,m_size);
memcpy(cm.m_tagarr,m_tagarr,512*sizeof(int));
return cm;
}
#ifdef USE_OPENCV
JMat::JMat(std::string picfile,int flag):JBuf(){
cv::Mat image = cv::imread(picfile);
m_bit = flag?1:sizeof(float);
m_width = image.cols;
m_height = image.rows;
m_channel = 3;//image.channels();
//printf("===channels %d\n",m_channel);
m_stride = m_width*m_channel;
m_size = m_bit*m_stride*m_height;
m_buf = malloc(m_size+m_bit*m_stride);
m_ref = 0;
if(flag){
memcpy(m_buf,image.data,m_size);
//printf("===w %d h %d\n",image.cols,image.rows);
//cv::imshow("aaa",image);
//cv::waitKey(0);
//cv::Mat fmat(m_height,m_width,CV_8UC3,m_buf);
//float scale = 1.0f/255.0f;
//image.convertTo(fmat,CV_32F,scale);
}else{
cv::Mat fmat(m_height,m_width,CV_32FC3,m_buf);
float scale = 1.0f/255.0f;
image.convertTo(fmat,CV_32F,scale);
}
image.release();
init_tagarr();
}
#else
JMat::JMat(std::string& picfile,int flag):JBuf(){
}
#endif
JMat::~JMat(){
}
float* JMat::fdata(){
return (float*)m_buf;
}
float* JMat::frow(int row){
return ((float*)m_buf)+ row*m_stride;
}
float* JMat::fitem(int row,int col){
return ((float*)m_buf)+ row*m_stride + col;
}
uint8_t* JMat::udata(){
return (uint8_t*)m_buf;
}
/*
nc::NdArray<float> JMat::ncarray(){
bool own = false;
nc::NdArray<float> arr = nc::NdArray<float>((float*)m_buf, m_height, m_width, own);
return arr;
}
*/
#ifdef USE_NCNN
ncnn::Mat JMat::packingmat(){
ncnn::Mat in_pack(m_width,m_height,1,(void*)m_buf,(size_t)4u*3,3);
ncnn::Mat in ;
ncnn::convert_packing(in_pack,in,1);
return in;
}
ncnn::Mat JMat::ncnnmat(){
unsigned char* data = (unsigned char*)m_buf;
if(m_channel == 3){
ncnn::Mat mat = ncnn::Mat::from_pixels(data, ncnn::Mat::PIXEL_BGR, m_width, m_height);
return mat;
}else if(m_channel == 4){
ncnn::Mat mat = ncnn::Mat::from_pixels(data, ncnn::Mat::PIXEL_BGRA, m_width, m_height);
return mat;
}else if(m_channel == 1){
ncnn::Mat mat = ncnn::Mat::from_pixels(data, ncnn::Mat::PIXEL_GRAY, m_width, m_height);
return mat;
}else {
ncnn::Mat mat = ncnn::Mat::from_pixels(data, ncnn::Mat::PIXEL_GRAY, m_width*m_channel, m_height);
return mat;
}
}
#endif

View File

@@ -1,91 +0,0 @@
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <memory>
#include <vector>
#include <string.h>
//#include "NumCpp.hpp"
#define USE_OPENCV
#define USE_NCNN
#define USE_TURBOJPG
#ifdef USE_OPENCV
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#endif
#ifdef USE_NCNN
#include "ncnn/ncnn/mat.h"
#endif
#ifdef USE_EIGEN
#include "eigen3/Eigen/Core"
typedef Eigen::Matrix<float, 1, Eigen::Dynamic, Eigen::RowMajor> Vectorf;
typedef Eigen::Matrix<std::complex<float>, 1, Eigen::Dynamic, Eigen::RowMajor> Vectorcf;
typedef Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> Matrixf;
typedef Eigen::Matrix<std::complex<float>, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> Matrixcf;
#endif
class JBuf{
protected:
bool m_ref = 0;
uint32_t m_size = 0;
void* m_buf = NULL;
public:
uint32_t size(){return m_size;} ;
void* data(){return m_buf;};
bool ref(){return m_ref;};
int zeros();
int forceref(int bref);
JBuf();
JBuf(uint32_t size,void* buf = nullptr);
virtual ~JBuf();
};
class JMat:public JBuf{
protected:
int m_bit = 0;
int m_width = 0;
int m_height = 0;
int m_channel = 0;
int m_stride = 0;
int m_tagarr[512];
void init_tagarr();
public:
int height(){return m_height;}
int width(){return m_width;}
int stride(){return m_stride;}
int channel(){return m_channel;}
JMat(int w,int h,float *buf ,int c = 3 ,int d = 0);
JMat(int w,int h,uint8_t *buf ,int c = 3 ,int d = 0);
JMat(int w,int h,int c = 3,int d = 0,int b=0);
JMat(std::string picfile,int flag=0);
JMat();
int load(std::string picfile);
int loadjpg(std::string picfile,int flag=0);
int savegpg(std::string gpgfile);
int loadgpg(std::string gpgfile);
float* fdata();
float* frow(int row);
float* fitem(int row,int col);
int tojpg(const char* fn);
int tobin(const char* fn);
int show(const char* title);
JMat clone();
JMat* refclone(int ref=1);
uint8_t* udata();
virtual ~JMat();
int* tagarr();
//nc::NdArray<float> ncarray();
#ifdef USE_OPENCV
cv::Mat cvmat();
#endif
#ifdef USE_NCNN
ncnn::Mat ncnnmat();
ncnn::Mat packingmat();
#endif
//Matrixf tomatrix();
};

View File

@@ -1,229 +0,0 @@
#include "malpha.h"
#include "blendgram.h"
#include "face_utils.h"
MWorkMat::MWorkMat(JMat* pic,JMat* msk,const int* boxs){
m_boxx = boxs[0];
m_boxy=boxs[1];
m_boxwidth=boxs[2]-m_boxx;
m_boxheight=boxs[3]-m_boxy;
//printf("x %d y %d w %d h %d \n",m_boxx,m_boxy,m_boxwidth,m_boxheight);
m_pic = pic;
m_msk = msk;
pic_real160 = new JMat(160,160,3,0,1);
pic_mask160 = new JMat(160,160,3,0,1);
//pic_crop160 = new JMat(160,160,3,0,1);
msk_real160 = new JMat(160,160,1,0,1);
//msk_mask160 = new JMat(160,160,3,0,1);
}
MWorkMat::~MWorkMat(){
matpic_org168.release();
matpic_roirst.release();
delete pic_real160;
delete pic_mask160;
delete msk_real160;
if(pic_clone160) delete pic_clone160;
}
int MWorkMat::munet(JMat** ppic,JMat** pmsk){
*ppic = pic_real160;
*pmsk = pic_mask160;
return 0;
}
int MWorkMat::premunet(){
matpic_roisrc = cv::Mat(m_pic->cvmat(),cv::Rect(m_boxx,m_boxy,m_boxwidth,m_boxheight));
cv::resize(matpic_roisrc , matpic_org168, cv::Size(168, 168), cv::INTER_AREA);
//vtacc
matpic_roi160 = cv::Mat(matpic_org168,cv::Rect(4,4,160,160));
cv::Mat cvmask = pic_mask160->cvmat();
cv::Mat cvreal = pic_real160->cvmat();
matpic_roi160.copyTo(cvmask);
matpic_roi160.copyTo(cvreal);
//cv::rectangle(cvmask,cv::Rect(5,5,150,150),cv::Scalar(0,0,0),-1);//,cv::LineTypes::FILLED);
cv::rectangle(cvmask,cv::Rect(5,5,150,145),cv::Scalar(0,0,0),-1);//,cv::LineTypes::FILLED);
//cv::rectangle(cvmask,cv::Rect(4,4,152,152),cv::Scalar(0,0,0),-1);//,cv::LineTypes::FILLED);
//cv::imwrite("cvmask.bmp",cvmask);
//cv::waitKey(0);
pic_clone160 = pic_real160->refclone(0);
return 0;
}
int MWorkMat::finmunet(JMat* fgpic){
cv::Mat cvreal = pic_real160->cvmat();
cvreal.copyTo(matpic_roi160);
//cv::imwrite("accpre.bmp",matpic_org168);
if(m_msk) vtacc((uint8_t*)matpic_org168.data,168*168);
//cv::imwrite("accend.bmp",matpic_org168);
cv::resize(matpic_org168, matpic_roirst, cv::Size(m_boxwidth, m_boxheight), cv::INTER_AREA);
if(fgpic){
matpic_roisrc = cv::Mat(fgpic->cvmat(),cv::Rect(m_boxx,m_boxy,m_boxwidth,m_boxheight));
matpic_roirst.copyTo(matpic_roisrc);
}else{
matpic_roirst.copyTo(matpic_roisrc);
}
return 0;
}
int MWorkMat::alpha(JMat** preal,JMat** pimg,JMat** pmsk){
*preal = pic_clone160;
*pimg = pic_real160;
*pmsk = msk_real160;
return 0;
}
int MWorkMat::prealpha(){
printf("x %d y %d w %d h %d \n",m_boxx,m_boxy,m_boxwidth,m_boxheight);
//m_msk->show("cba");
//cv::waitKey(0);
matmsk_roisrc = cv::Mat(m_msk->cvmat(),cv::Rect(m_boxx,m_boxy,m_boxwidth,m_boxheight));
cv::resize(matmsk_roisrc , matmsk_org168, cv::Size(168, 168), cv::INTER_AREA);
matmsk_roi160 = cv::Mat(matmsk_org168,cv::Rect(4,4,160,160));
cv::Mat cvmask = msk_real160->cvmat();
cv::cvtColor(matmsk_roi160,cvmask,cv::COLOR_RGB2GRAY);
//BlendGramAlphaRev(pic_clone160->udata(),msk_real160->udata(),pic_crop160->udata(),160,160);
//pic_crop160->show("aaa");
//cv::waitKey(0);
//pic_crop160
//
return 0;
}
int MWorkMat::finalpha(){
cv::Mat cvmask = msk_real160->cvmat();
cv::cvtColor(cvmask,matmsk_roi160,cv::COLOR_GRAY2RGB);
//
cv::resize(matmsk_org168, matmsk_roirst, cv::Size(m_boxwidth, m_boxheight), cv::INTER_AREA);
matmsk_roirst.copyTo(matmsk_roisrc);
return 0;
}
int MWorkMat::vtacc(uint8_t* buf,int count){
/*
int avgr = 0;
int avgb = 0;
int avgg = 0;
if(1){
uint8_t* pb = m_pic->udata();
for(int k=0;k<10;k++){
avgr += *pb++;
avgg += *pb++;
avgb += *pb++;
}
avgr =avgr/10 +10;
avgg =avgg/10 -20;
if(avgg<0)avgg=0;
avgb =avgb/10 + 10;
}
*/
uint8_t* pb = buf;
for(int k=0;k<count;k++){
int sum = (pb[0]+ pb[2])/2.0f;
if(pb[1]>=sum){
pb[1]=sum;
//pb[0]=0;
//pb[2]=0;
// }else if((pb[0]<avgr)&&(pb[1]>avgg)&&(pb[2]<avgb)){
//pb[1]=0;
//pb[0]=0;
//pb[2]=0;
}
pb+=3;
}
/*
long sum = 0l;
float mean = sum*0.5f/count;
uint8_t maxg = (mean>255.f)?255:mean;
//printf("sum %ld mean %f maxg %d\n",sum,mean,maxg);
//getchar();
pb = buf +1;
for(int k=0;k<count;k++){
if(*pb>maxg){
*pb = maxg;
}
pb+=3;
}
*/
return 0;
}
int MAlpha::doModel(JMat* real,JMat* img,JMat* pha){
if(1)return 0;
/*
if(1)return 0;
JMat picimg(160,160,3,0,1);
JMat picreal(160,160,3,0,1);
cv::cvtColor(real->cvmat(),picreal.cvmat(),cv::COLOR_RGB2BGR);
cv::cvtColor(img->cvmat(),picimg.cvmat(),cv::COLOR_RGB2BGR);
*/
float mean_vals[3] = {127.5f, 127.5f, 127.5f};
float norm_vals[3] = {1 / 127.5f, 1 / 127.5f, 1 / 127.5f};
ncnn::Mat inimg = ncnn::Mat::from_pixels(img->udata(), ncnn::Mat::PIXEL_BGR2RGB, 160, 160);
inimg.substract_mean_normalize(mean_vals, norm_vals);
ncnn::Mat inreal = ncnn::Mat::from_pixels(real->udata(), ncnn::Mat::PIXEL_BGR2RGB, 160, 160);
inreal.substract_mean_normalize(mean_vals, norm_vals);
ncnn::Mat inpha = ncnn::Mat::from_pixels(pha->udata(), ncnn::Mat::PIXEL_GRAY, 160, 160);
float gmean_vals[3] = {0.0f, 0.0f, 0.0f};
float gnorm_vals[3] = {1 / 255.0f, 1 / 255.0f, 1 / 255.0f};
inpha.substract_mean_normalize(gmean_vals, gnorm_vals);
ncnn::Mat inpic(160,160,7);
//printf("===in %d %d all %d %d pha %d %d\n",inreal.cstep,inreal.elempack,inpic.cstep,inpic.elempack,inpha.cstep,inpha.elempack);
//JMat picin(160,160,7);
float* buf = (float*)inpic.data;
memcpy(buf,inreal.data,inreal.cstep*inreal.c*sizeof(float));
buf += inpic.cstep*inreal.c;
memcpy(buf,inimg.data,inimg.cstep*inimg.c*sizeof(float));
buf += inimg.cstep*inimg.c;
memcpy(buf, inpha.data,inpha.cstep*sizeof(float));
//ncnn::Mat inpic(160,160,7,pd,4);
//ncnn::Mat inpack(160,160,1,pd,(size_t)4u*7,7);
//ncnn::Mat inpic;
//ncnn::convert_packing(inpack,inpic,1);
ncnn::Mat outpic;
ncnn::Extractor ex = net.create_extractor();
int rst = ex.input("input", inpic);
//printf("input %d\n",rst);
rst = ex.extract("output", outpic);
//printf("output %d\n",rst);
float outmean_vals[3] = {0.0f, 0.0f, 0.0f};
float outnorm_vals[3] = { 255.0f, 255.0f, 255.0f};
outpic.substract_mean_normalize(outmean_vals, outnorm_vals);
outpic.to_pixels(pha->udata(),ncnn::Mat::PIXEL_GRAY);
//pha->show("mmm");
//cv::waitKey(0);
//dumpfloat((float*)outpic.data+160*159,10);
//ncnn::Mat pakpic;
//ncnn::convert_packing(outpic,pakpic,1);
//dumpfloat((float*)pakpic.data,160*160*1);
//getchar();
/*
cv::Mat cvadj(160,160,CV_32FC1,outpic.data);
cv::Mat cvout;//(160,160,CV_8UC1);
float scale = 255.0f;//255.0f;
cvadj.convertTo(cvout,CV_8UC1,scale);
cvout.copyTo(pha->cvmat());
*/
//cv::imshow("pha",cvout);
//pha->show("pha");
//cv::waitKey(0);
return 0;
}
MAlpha::MAlpha(const char* fnbin,const char* fnparam):NcnnModel(160,160){
std::string fb(fnbin);
std::string fp(fnparam);
initModel(fb,fp);
}
MAlpha::~MAlpha(){
}

View File

@@ -1,59 +0,0 @@
#pragma once
#include "jmat.h"
#include "ncnn/ncnn/net.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <stdio.h>
#include <vector>
#include "aimodel.h"
class MWorkMat{
private:
int m_boxx;
int m_boxy;
int m_boxwidth;
int m_boxheight;
JMat* m_pic;
JMat* m_msk;
JMat* pic_real160;//blendimg
JMat* pic_mask160;
cv::Mat matpic_roisrc;//box area
cv::Mat matpic_org168;
cv::Mat matpic_roi160;
JMat* pic_clone160;//blendimg
cv::Mat matpic_roirst;
//JMat* pic_crop160;
//
JMat* msk_real160;
//JMat* msk_mask160;
cv::Mat matmsk_roisrc;//box area
cv::Mat matmsk_org168;
cv::Mat matmsk_roi160;
cv::Mat matmsk_roirst;
int vtacc(uint8_t* buf,int count);
public:
MWorkMat(JMat* pic,JMat* msk,const int* boxs);
int premunet();
int munet(JMat** ppic,JMat** pmsk);
int finmunet(JMat* fgpic=NULL);
int prealpha();
int alpha(JMat** preal,JMat** pimg,JMat** pmsk);
int finalpha();
virtual ~MWorkMat();
};
class MAlpha:public NcnnModel{
private:
public:
int doModel(JMat* real,JMat* img,JMat* pha);
MAlpha(const char* fnbin,const char* fnparam);
virtual ~MAlpha();
};

View File

@@ -1,375 +0,0 @@
#pragma once
#ifndef SERVICESUPERVISOR_IIR_FILTER_H
#define SERVICESUPERVISOR_IIR_FILTER_H
//E(t,f) is computed using a first-order in-finite impulse response (IIR) filter
#define UES_IIR_I
//#define UES_IIR_II
#ifdef UES_IIR_I
class IIR_I
{
private:
double *m_pNum;
double *m_pDen;
double *m_px;
double *m_py;
int m_num_order;
int m_den_order;
public:
IIR_I();
~IIR_I();
void reset();
void setPara(double num[], int num_order, double den[], int den_order);
void resp(double data_in[], int m, double data_out[], int n);
void filter(double data_in[], double data_out[], int len);
};
/** \brief 将滤波器的内部状态清零,滤波器的系数保留
* \return
*/
void IIR_I::reset()
{
for(int i = 0; i <= m_num_order; i++)
{
m_pNum[i] = 0.0;
}
for(int i = 0; i <= m_den_order; i++)
{
m_pDen[i] = 0.0;
}
}
IIR_I::IIR_I()
{
m_pNum = NULL;
m_pDen = NULL;
m_px = NULL;
m_py = NULL;
m_num_order = -1;
m_den_order = -1;
};
IIR_I::~IIR_I()
{
delete[] m_pNum;
delete[] m_pDen;
delete[] m_px;
delete[] m_py;
m_pNum = NULL;
m_pDen = NULL;
m_px = NULL;
m_py = NULL;
};
/** \brief
*
* \param num 分子多项式的系数,升序排列,num[0] 为常数项
* \param m 分子多项式的阶数
* \param den 分母多项式的系数,升序排列,den[0] 为常数项
* \param m 分母多项式的阶数
* \return
*/
void IIR_I::setPara(double num[], int num_order, double den[], int den_order)
{
delete[] m_pNum;
delete[] m_pDen;
delete[] m_px;
delete[] m_py;
m_pNum = new double[num_order + 1];
m_pDen = new double[den_order + 1];
m_num_order = num_order;
m_den_order = den_order;
m_px = new double[num_order + 1];
m_py = new double[den_order + 1];
for(int i = 0; i < m_num_order; i++)
{
m_pNum[i] = num[i];
m_px[i] = 0.0;
}
m_pNum[m_num_order] = 0.0;
m_px[m_num_order] = 0.0;
for(int i = 0; i < m_den_order; i++)
{
m_pDen[i] = den[i];
m_py[i] = 0.0;
}
m_pDen[m_den_order] = 0.0;
m_py[m_den_order] = 0.0;
}
/** \brief 计算 IIR 滤波器的时域响应,不影响滤波器的内部状态
* \param data_in 为滤波器的输入0 时刻之前的输入默认为 0data_in[M] 及之后的输入默认为data_in[M-1]
* \param data_out 滤波器的输出
* \param M 输入数据的长度
* \param N 输出数据的长度
* \return
*/
void IIR_I::resp(double data_in[], int M, double data_out[], int N)
{
int i, k, il;
for(k = 0; k < N; k++)
{
data_out[k] = 0.0;
for(i = 0; i <= m_num_order; i++)
{
if( k - i >= 0)
{
il = ((k - i) < M) ? (k - i) : (M - 1);
data_out[k] = data_out[k] + m_pNum[i] * data_in[il];
}
}
for(i = 1; i <= m_den_order; i++)
{
if( k - i >= 0)
{
data_out[k] = data_out[k] - m_pDen[i] * data_out[k - i];
}
}
}
}
/** \brief 滤波函数采用直接I型结构
* 注该函数内部修改过移植librosa.pcen时参照scipy.signal.lfilter所做的设计。
*
* \param data_in[] 输入数据
* \param data_out[] 保存滤波后的数据
* \param len 数组的长度
* \return
*/
void IIR_I::filter(double data_in[], double data_out[], int len)
{
int i, k;
m_py[1] = 1; //修改的地方因为公式中y[n-k]当为第一个元素时会出现y[-1]pcen中y[-1]会被认为为1。
for(k = 0; k < len; k++)
{
m_px[0] = data_in[k];
m_py[0] = 0.0;
for(i = 0; i <= m_num_order; i++)
{
m_py[0] = m_py[0] + m_pNum[i] * m_px[i];
}
for(i = 1; i <= m_den_order; i++)
{
m_py[0] = m_py[0] - m_pDen[i] * m_py[i];
}
for(i = m_num_order; i >= 1; i--)
{
m_px[i] = m_px[i-1];
}
for(i = m_den_order; i >= 1; i--)
{
m_py[i] = m_py[i-1];
}
data_out[k] = m_py[0];
}
}
#endif
#ifdef UES_IIR_II
/**< IIR 滤波器直接II型实现 */
class IIR_II
{
public:
IIR_II();
void reset();
void setPara(double num[], int num_order, double den[], int den_order);
void resp(double data_in[], int m, double data_out[], int n);
double filter(double data);
void filter(double data[], int len);
void filter(double data_in[], double data_out[], int len);
protected:
private:
double *m_pNum;
double *m_pDen;
double *m_pW;
int m_num_order;
int m_den_order;
int m_N;
};
class IIR_BODE
{
private:
double *m_pNum;
double *m_pDen;
int m_num_order;
int m_den_order;
std::complex<double> poly_val(double p[], int order, double omega);
public:
IIR_BODE();
void setPara(double num[], int num_order, double den[], int den_order);
std::complex<double> bode(double omega);
void bode(double omega[], int n, std::complex<double> resp[]);
};
IIR_II::IIR_II()
{
//ctor
m_pNum = NULL;
m_pDen = NULL;
m_pW = NULL;
m_num_order = -1;
m_den_order = -1;
m_N = 0;
};
/** \brief 将滤波器的内部状态清零,滤波器的系数保留
* \return
*/
void IIR_II::reset()
{
for(int i = 0; i < m_N; i++)
{
m_pW[i] = 0.0;
}
}
/** \brief
*
* \param num 分子多项式的系数,升序排列,num[0] 为常数项
* \param m 分子多项式的阶数
* \param den 分母多项式的系数,升序排列,den[0] 为常数项
* \param m 分母多项式的阶数
* \return
*/
void IIR_II::setPara(double num[], int num_order, double den[], int den_order)
{
delete[] m_pNum;
delete[] m_pDen;
delete[] m_pW;
m_num_order = num_order;
m_den_order = den_order;
m_N = fmax(num_order, den_order) + 1;
m_pNum = new double[m_N];
m_pDen = new double[m_N];
m_pW = new double[m_N];
for(int i = 0; i < m_N; i++)
{
m_pNum[i] = 0.0;
m_pDen[i] = 0.0;
m_pW[i] = 0.0;
}
for(int i = 0; i <= num_order; i++)
{
m_pNum[i] = num[i];
}
for(int i = 0; i <= den_order; i++)
{
m_pDen[i] = den[i];
}
}
/** \brief 计算 IIR 滤波器的时域响应,不影响滤波器的内部状态
* \param data_in 为滤波器的输入0 时刻之前的输入默认为 0data_in[M] 及之后的输入默认为data_in[M-1]
* \param data_out 滤波器的输出
* \param M 输入数据的长度
* \param N 输出数据的长度
* \return
*/
void IIR_II::resp(double data_in[], int M, double data_out[], int N)
{
int i, k, il;
for(k = 0; k < N; k++)
{
data_out[k] = 0.0;
for(i = 0; i <= m_num_order; i++)
{
if( k - i >= 0)
{
il = ((k - i) < M) ? (k - i) : (M - 1);
data_out[k] = data_out[k] + m_pNum[i] * data_in[il];
}
}
for(i = 1; i <= m_den_order; i++)
{
if( k - i >= 0)
{
data_out[k] = data_out[k] - m_pDen[i] * data_out[k - i];
}
}
}
}
/** \brief 滤波函数采用直接II型结构
*
* \param data 输入数据
* \return 滤波后的结果
*/
double IIR_II::filter(double data)
{
m_pW[0] = data;
for(int i = 1; i <= m_den_order; i++) // 先更新 w[n] 的状态
{
m_pW[0] = m_pW[0] - m_pDen[i] * m_pW[i];
}
data = 0.0;
for(int i = 0; i <= m_num_order; i++)
{
data = data + m_pNum[i] * m_pW[i];
}
for(int i = m_N - 1; i >= 1; i--)
{
m_pW[i] = m_pW[i-1];
}
return data;
}
/** \brief 滤波函数采用直接II型结构
*
* \param data[] 传入输入数据,返回时给出滤波后的结果
* \param len data[] 数组的长度
* \return
*/
void IIR_II::filter(double data[], int len)
{
int i, k;
for(k = 0; k < len; k++)
{
m_pW[0] = data[k];
for(i = 1; i <= m_den_order; i++) // 先更新 w[n] 的状态
{
m_pW[0] = m_pW[0] - m_pDen[i] * m_pW[i];
}
data[k] = 0.0;
for(i = 0; i <= m_num_order; i++)
{
data[k] = data[k] + m_pNum[i] * m_pW[i];
}
for(i = m_N - 1; i >= 1; i--)
{
m_pW[i] = m_pW[i-1];
}
}
}
/** \brief 滤波函数采用直接II型结构
*
* \param data_in[] 输入数据
* \param data_out[] 保存滤波后的数据
* \param len 数组的长度
* \return
*/
void IIR_II::filter(double data_in[], double data_out[], int len)
{
int i, k;
for(k = 0; k < len; k++)
{
m_pW[0] = data_in[k];
for(i = 1; i <= m_den_order; i++) // 先更新 w[n] 的状态
{
m_pW[0] = m_pW[0] - m_pDen[i] * m_pW[i];
}
data_out[k] = 0.0;
for(i = 0; i <= m_num_order; i++)
{
data_out[k] = data_out[k] + m_pNum[i] * m_pW[i];
}
for(i = m_N - 1; i >= 1; i--)
{
m_pW[i] = m_pW[i-1];
}
}
}
#endif
#endif //SERVICESUPERVISOR_IIR_FILTER_H

View File

@@ -1,441 +0,0 @@
#pragma once
#include "AudioFFT.hpp"
//#include"../third/numcpp/NumCpp.hpp"
#include "opencv2/opencv.hpp"
#include "iir_filter.hpp"
#include "sas_util.h"
int nSamplesPerSec = 16000; //采样率(每秒样本数) //Sample rate.(keda, thchs30, aishell)
int length_DFT = 1024;//2048; //傅里叶点数 //fft points (samples)
int hop_length = 160;//int(0.05 * nSamplesPerSec); //步长 //下一帧取数据相对于这一帧的右偏移量
int win_length = 800;// int(0.1 * nSamplesPerSec); //帧长 //假设16000采样率则取取0.1s时间的数据
int number_filterbanks = 80; //过滤器数量 //Number of Mel banks to generate
float preemphasis = 0.97; //预加重(高通滤波器比例值)
int max_db = 100;
int ref_db = 20;
int r = 1; //librosa里的r=1暂未深入分析其作用
double pi = 3.14159265358979323846;
cv::Mat_<double> mel_basis;
cv::Mat_<float> hannWindow;
std::shared_ptr<IIR_I> filter;
//"""Convert Hz to Mels"""
double hz_to_mel(double frequencies, bool htk = false) {
if (htk) {
return 2595.0 * log10(1.0 + frequencies / 700.0);
}
// Fill in the linear part
double f_min = 0.0;
double f_sp = 200.0 / 3;
double mels = (frequencies - f_min) / f_sp;
// Fill in the log-scale part
double min_log_hz = 1000.0; // beginning of log region (Hz)
double min_log_mel = (min_log_hz - f_min) / f_sp; // same (Mels)
double logstep = log(6.4) / 27.0; // step size for log region
// 对照Python平台的librosa库移植
//如果是多维数列
// if (frequencies.ndim) {
// // If we have array data, vectorize
// log_t = (frequencies >= min_log_hz)
// mels[log_t] = min_log_mel + np.log(frequencies[log_t] / min_log_hz) / logstep
// } else
if (frequencies >= min_log_hz) {
// If we have scalar data, heck directly
mels = min_log_mel + log(frequencies / min_log_hz) / logstep;
}
return mels;
}
//"""Convert mel bin numbers to frequencies"""
cv::Mat_<double> mel_to_hz(cv::Mat_<double> mels, bool htk = false) {
// if (htk) {
// return //python://700.0 * (10.0**(mels / 2595.0) - 1.0);
// }
// Fill in the linear scale
double f_min = 0.0;
double f_sp = 200.0 / 3;
cv::Mat_<double> freqs = mels * f_sp + f_min;
// And now the nonlinear scale
double min_log_hz = 1000.0; // beginning of log region (Hz)
double min_log_mel = (min_log_hz - f_min) / f_sp; // same (Mels)
double logstep = log(6.4) / 27.0; // step size for log region
// 对照Python平台的librosa库移植
//if (mels.ndim) {
// If we have vector data, vectorize
cv::Mat_<bool> log_t = (mels >= min_log_mel);
for (int i = 0; i < log_t.cols; i++) {
if (log_t(0, i)) {
freqs(0, i) = cv::exp((mels(0, i) - min_log_mel) * logstep) * min_log_hz;
}
}
//}
return freqs;
}
// 生成等差数列类似np.linspace
cv::Mat_<double> cvlinspace(double min_, double max_, int length) {
auto cvmat = cv::Mat_<double>(1, length);
for (int i = 0; i < length; i++) {
cvmat(0, i) = ((max_ - min_) / (length - 1) * i) + min_;
}
return cvmat;
}
//"""Create a Filterbank matrix to combine FFT bins into Mel-frequency bins"""
cv::Mat_<double> mel_spectrogram_create(int nps, int n_fft, int n_mels) {
double f_max = nps / 2.0;
double f_min = 0;
int n_fft_2 = 1 + n_fft / 2;
// Initialize the weights
//auto weights = nc::zeros<double>(nc::uint32(n_mels), nc::uint32(n_fft_2));
auto weights = cv::Mat_<double>(n_mels, n_fft_2, 0.0);
// Center freqs of each FFT bin
//auto fftfreqs_ = nc::linspace<double>(f_min, f_max, nc::uint32(n_fft_2), true);
auto fftfreqs = cvlinspace(f_min, f_max, n_fft_2);
// 'Center freqs' of mel bands - uniformly spaced between limits
double min_mel = hz_to_mel(f_min, false);
double max_mel = hz_to_mel(f_max, false);
//auto mels_ = nc::linspace(min_mel, max_mel, nc::uint32(n_mels + 2));
auto mels = cvlinspace(min_mel, max_mel, n_mels + 2);
auto mel_f = mel_to_hz(mels, false);
//auto fdiff_ = nc::diff(mel_f_); //沿着指定轴计算第N维的离散差值(后一个元素减去前一个元素)
cv::Mat_<double> d1(1, mel_f.cols * mel_f.rows - 1, (double *) (mel_f.data) + 1);
cv::Mat_<double> d2(1, mel_f.cols * mel_f.rows - 1, (double *) (mel_f.data));
cv::Mat_<double> fdiff = d1 - d2;
//auto ramps = nc::subtract.outer(mel_f, fftfreqs); //nc没有subtract.outer
//nc::NdArray<double> ramps = nc::zeros<double>(mel_f.cols, fftfreqs.cols);
auto ramps = cv::Mat_<double>(mel_f.cols, fftfreqs.cols);
for (int i = 0; i < mel_f.cols; i++) {
for (int j = 0; j < fftfreqs.cols; j++) {
ramps(i, j) = mel_f(0, i) - fftfreqs(0, j);
}
}
for (int i = 0; i < n_mels; i++) {
// lower and upper slopes for all bins
//auto ramps_1 = nc::NdArray<double>(1, ramps.cols);
auto ramps_1 = cv::Mat_<double>(1, ramps.cols);
for (int j = 0; j < ramps.cols; j++) {
ramps_1(0, j) = ramps(i, j);
}
//auto ramps_2 = nc::NdArray<double>(1, ramps.cols);
auto ramps_2 = cv::Mat_<double>(1, ramps.cols);
for (int j = 0; j < ramps.cols; j++) {
ramps_2(0, j) = ramps(i + 2, j);
}
cv::Mat_<double> lower = ramps_1 * -1 / fdiff(0, i);
cv::Mat_<double> upper = ramps_2 / fdiff(0, i + 1);
// .. then intersect them with each other and zero
//auto weights_1 = nc::maximum(nc::zeros<double>(1, ramps.cols), nc::minimum(lower, upper));
cv::Mat c1 = lower;//(cv::Mat_<double>(1,5) << 1,2,-3,4,-5);
cv::Mat c2 = upper;
cv::Mat weights_1 = cv::Mat_<double>(1, lower.cols);
cv::min(c1, c2, weights_1);
cv::max(weights_1, 0, weights_1);
for (int j = 0; j < n_fft_2; j++) {
weights(i, j) = weights_1.at<double_t>(0, j);
}
}
// Slaney-style mel is scaled to be approx constant energy per channel
auto enorm = cv::Mat_<double>(1, n_mels);
for (int j = 0; j < n_mels; j++) {
enorm(0, j) = 2.0 / (mel_f(0, j + 2) - mel_f(0, j));
}
for (int j = 0; j < n_mels; j++) {
for (int k = 0; k < n_fft_2; k++) {
weights(j, k) *= enorm(0, j);
}
}
return weights;
}
//"""Short-time Fourier transform (STFT)""": 默认center=True, window='hann', pad_mode='reflect'
cv::Mat_<double> MagnitudeSpectrogram(const cv::Mat_<float> *emphasis_data, int n_fft = 2048, int hop_length = 0,
int win_length = 0) {
if (win_length == 0) {
win_length = n_fft;
}
if (hop_length == 0) {
hop_length = win_length / 4;
}
// reflect对称填充
int pad_lenght = n_fft / 2;
// 使用opencv里的copyMakeBorder来完成reflect填充
cv::Mat_<float> cv_padbuffer;
cv::copyMakeBorder(*emphasis_data, cv_padbuffer, 0, 0, pad_lenght, pad_lenght, cv::BORDER_REFLECT_101);
// windowing加窗将每一帧乘以汉宁窗以增加帧左端和右端的连续性。
// 生成一个1600长度的hannWindow并居中到2048长度的
if (hannWindow.empty()) {
hannWindow = cv::Mat_<float>(1, n_fft, 0.0f);
int insert_cnt = 0;
if (n_fft > win_length) {
insert_cnt = (n_fft - win_length) / 2;
} else {
//std::cout << "\tn_fft:" << n_fft << " > win_length:" << n_fft << std::endl;
return cv::Mat_<double>(0, 0);
}
for (int k = 1; k <= win_length; k++) {
hannWindow(0, k - 1 + insert_cnt) = float(0.5 * (1 - cos(2 * pi * k / (win_length + 1))));
}
}
// opencv虽然有Hann窗生成函数但是必须要求width > 1height > 1
//cv::Mat_<double> cv_hannWindow;
//cv::createHanningWindow(cv_hannWindow, cv::Size(1, win_length), CV_64FC1);
int size = cv_padbuffer.rows * cv_padbuffer.cols;//padbuffer.size()
int number_feature_vectors = (size - n_fft) / hop_length + 1;
int number_coefficients = n_fft / 2 + 1;
cv::Mat_<float> feature_vector(number_feature_vectors, number_coefficients, 0.0f);
audiofft::AudioFFT fft; //将FFT初始化放在循环外可达到最优速度
fft.init(size_t(n_fft));
for (int i = 0; i <= size - n_fft; i += hop_length) {
// 每次取一段数据
cv::Mat_<float> framef = cv::Mat_<float>(1, n_fft, (float *) (cv_padbuffer.data) + i).clone();
// 加hann窗
framef = framef.mul(hannWindow);
// 复数Xrf实数Xif虚数。
cv::Mat_<float> Xrf(1, number_coefficients);
cv::Mat_<float> Xif(1, number_coefficients);
fft.fft((float *) (framef.data), (float *) (Xrf.data), (float *) (Xif.data));
// 求模
cv::pow(Xrf, 2, Xrf);
cv::pow(Xif, 2, Xif);
cv::Mat_<float> cv_feature(1, number_coefficients, &(feature_vector[i / hop_length][0]));
cv::sqrt(Xrf + Xif, cv_feature);
}
cv::Mat_<float> cv_mag;
cv::transpose(feature_vector, cv_mag);
cv::Mat_<double> mag;
cv_mag.convertTo(mag, CV_64FC1);
return mag;
}
/*********************************************
* 名称log_mel
* 功能传入音频数据输出log-mel方式提取的特征数据。
* 参数:@ifile_data 传入的音频数据
* @nSamples_per_sec 音频采样率
* 返回cv::Mat_<double> 特征数据
*********************************************/
//cv::Mat_<double> log_mel(std::vector<uint8_t> &ifile_data, int nSamples_per_sec) {
int log_mel(float* ifile_data, int ifile_length,int nSamples_per_sec,float* ofile_data) {
if (nSamples_per_sec != nSamplesPerSec) {
//std::cout << R"(the "nSamples_per_sec" is not 16000.)" << std::endl;
return -1;//cv::Mat_<double>(0, 0);
}
//int ifile_length = int(ifile_data.size() / 4);
// pre-emphasis 预加重 //高通滤波
//cv::Mat_<float> d1(1, ifile_length - 1, (float *) (ifile_data.data()) + 1);
//cv::Mat_<float> d2(1, ifile_length-1 , (float *) (ifile_data.data()));
cv::Mat_<float> d1(1, ifile_length - 1, (float *) (ifile_data) + 1);
cv::Mat_<float> d2(1, ifile_length-1 , (float *) (ifile_data));
//std::cout<<ifile_length<<"====="<<d1[0][960000-1]<<std::endl;
cv::Mat_<float> cv_emphasis_data;
cv::hconcat(cv::Mat_<float>::zeros(1, 1), d1 - d2 * preemphasis, cv_emphasis_data);
//cv::print(cv_emphasis_data);
//std::cout<<ifile_length<<"====="<< cv_emphasis_data[0][960000-1]<<std::endl;
// magnitude spectrogram 幅度谱图
auto mag = MagnitudeSpectrogram(&cv_emphasis_data, length_DFT, hop_length, win_length);
auto magb = cv::abs(mag);
cv::pow(magb,2,mag);
//tooken
// 生成梅尔谱图 mel spectrogram //3ms
if (mel_basis.empty()) {
mel_basis = mel_spectrogram_create(nSamplesPerSec, length_DFT, number_filterbanks);
}
//cv::print(mel_basis);
//std::cout<<mel_basis.cols<<"=====cv_mel"<<mel_basis.rows<<std::endl;
// doc
cv::Mat cv_mel = mel_basis * mag;
//cv::Mat cv_mel = mel_basis.dot( mag);
// to decibel
//mel = 20 * np.log10(np.maximum(1e-5, mel))
//mag = 20 * np.log10(np.maximum(1e-5, mag))
//由于后续没用用到mag了所以不再对mag做运算。
// 使用opencv来实现
//cv::log(cv::max(cv_mel, 1e-5), cv_mel);
//cv::log(cv::max(cv_mel, 1e-5), cv_mel);
cv::log(cv_mel+ 1e-5, cv_mel);
// opencv没有log10()所以使用log(x)/log(10)来运算。
cv_mel = cv_mel / 2.3025850929940459 * 10; // 2.3025850929940459=log(10)
// normalize
//mel = np.clip((mel - hp.ref_db + hp.max_db) / hp.max_db, 1e-8, 1)
//mag = np.clip((mag - hp.ref_db + hp.max_db) / hp.max_db, 1e-8, 1)
//cv::normalize(cv_mel, cv_mel, 1e-8, 1.0, cv::NORM_MINMAX); // cv::normalize无法实现
//cv_mel = (cv_mel - ref_db + max_db) / max_db;
//cv_mel = cv::max(cv::min(cv_mel, 1.0), 1e-8);
cv_mel = cv_mel - ref_db;
//cv::print(cv_mel);
//std::cout<<cv_mel.cols<<"=====cv_mel"<<cv_mel.rows<<std::endl;
//std::cout<<"=====cv_mel"<<std::endl;
//getchar();
// Transpose
//mel = mel.T.astype(np.float32)
//mag = mag.T.astype(np.float32)
// 使用opencv的transpose
cv::Mat cv_mel_r;//(cv_mel.cols,cv_mel.rows,CV_64FC1,ofile_data);
cv::transpose(cv_mel, cv_mel_r);
//cv::Mat rcv(cv_mel_r.cols,cv_mel_r.rows, CV_32FC1,ofile_data);
cv::Mat rrr(cv_mel.cols,cv_mel.rows,CV_32FC1,ofile_data);
cv_mel_r.convertTo(rrr, CV_32FC1);
if (r == 1) {
// 原计算公式是:
// mel = mel[:len(mel) // hp.r * hp.r].reshape([len(mel) // hp.r, hp.r * hp.n_mels])
// 当r=1的时候公式运算无任何数值改变。
} else {
//std::cout << R"(the "r" is not 1.)" << std::endl;
}
// 返回mel特征向量
return 0;
}
/**--------------------------------- 以下是pcen运算方法 ---------------------------------**/
// scipy.signal.lfilter_zi()
cv::Mat_<double> cvlfilter_zi(cv::Mat_<double> b, cv::Mat_<double> a) {
if ((b.rows != 1) || (a.rows != 1)) {
//std::cout << "Numerator b and Denominator a must be 1-D." << std::endl;
}
if (a(0, 0) != 1) {
// Normalize the coefficients so a[0] == 1.
b = b / a(0, 0);
a = a / a(0, 0);
}
int len_a = a.cols * a.rows;
int len_b = b.cols * b.rows;
int n = len_a > len_b ? len_a : len_b;
if (len_a < n) {
cv::hconcat(a, cv::Mat_<float>::zeros(1, n - len_a), a);
} else if (len_b < n) {
cv::hconcat(b, cv::Mat_<float>::zeros(1, n - len_b), b);
}
return cv::Mat_<double>(0, 0);
}
/*
// scipy.signal.lfilter()
// Filter data along one-dimension with an IIR or FIR filter.
cv::Mat_<double> cvlfilter(cv::Mat_<double> &b, cv::Mat_<double> &a, cv::Mat_<double> &x,
cv::Mat_<double> &zi, int axis = -1) {
if (a.rows * a.cols == 1) {
// This path only supports types fdgFDGO to mirror _linear_filter below.
// Any of b, a, x, or zi can set the dtype, but there is no default
// casting of other types; instead a NotImplementedError is raised.
// 后续如果需要,则进行补充
} else {
// return sigtools._linear_filter(b, a, x, axis, zi)
// sigtools._linear_filter()
// (y,Vf) = _linear_filter(b,a,X,Dim=-1,Vi=None) implemented using Direct Form II transposed flow diagram.
// If Vi is not given, Vf is not returned.
;
}
}
*/
/*********************************************
* 名称pcen
* 功能传入音频数据输出pcen方式提取的特征数据。
* 参数:@ifile_data 传入的音频数据
* @nSamples_per_sec 音频采样率
* 返回cv::Mat_<double> 特征数据
*********************************************/
cv::Mat_<double> pcen(std::vector<uint8_t> &ifile_data, int nSamples_per_sec) {
//if (!(&ifile_data) || ifile_data.empty()) {
if (ifile_data.empty()) {
//std::cout << "error: invalid paramter: ifile_data" << std::endl;
return cv::Mat_<double>(0, 0);
}
if (nSamples_per_sec != nSamplesPerSec) {
// std::cout << R"(error: the "nSamples_per_sec" is not 16000.)" << std::endl;
return cv::Mat_<double>(0, 0);
}
int ifile_length = int(ifile_data.size() / 4);
cv::Mat_<float> cv_emphasis_data(1, ifile_length, (float *) (ifile_data.data()));
// std::cout<<ifile_length<<"====="<<cv_emphasis_data[0][960000-1]<<std::endl;
//getchar();
// magnitude spectrogram 幅度谱图
auto mag = MagnitudeSpectrogram(&cv_emphasis_data, length_DFT, hop_length, win_length);
mag = cv::abs(mag) * std::pow(2, 31);
// 生成梅尔谱图 mel spectrogram //3ms
if (mel_basis.empty()) {
mel_basis = mel_spectrogram_create(nSamplesPerSec, length_DFT, number_filterbanks);
}
// doc
cv::Mat_<double> mel = mel_basis * mag;
// 计算pcen特征
// double time_constant = 0.400;
// int sr = 22050;
// int hop_length = 512;
// double t_frames = time_constant * sr / double(hop_length);
// double b = (sqrt(1 + 4 * t_frames * t_frames) - 1) / (2 * t_frames * t_frames);
// cv::Mat_<double> zi = (cv::Mat_<double>(1, 1) << 0.94361056);
//
// cv::Mat_<double> in_b = (cv::Mat_<double>(1, 1) << b);
// cv::Mat_<double> in_a = (cv::Mat_<double>(1, 2) << 1, b - 1);
// cv::Mat_<double> zi = cvlfilter_zi(in_b, in_a);
// 第二个公式计算
// cv::Mat_<double> S_smooth = cvlfilter(in_b, in_a, mel, zi);
#if 1 // IIR滤波器
if (!filter) {
filter = std::make_shared<IIR_I>();
double iir_b[1] = {0.05638943879134889};
double iir_a[2] = {1.0, -0.9436105612086512};
//filter.reset();
filter->setPara(iir_b, 1, iir_a, 2);
}
cv::Mat_<double> S_smooth = cv::Mat_<double>(mel.rows, mel.cols);
for (int i = 0; i < mel.rows; i++) {
filter->filter(mel[i], S_smooth[i], mel.cols);
}
#endif
// 第一个公式计算
double gain = 0.98;
double bias = 2.0;
double power = 0.5;
double eps = 1e-6;
//python: smooth = np.exp(-gain * (np.log(eps) + np.log1p(S_smooth / eps)))
cv::Mat_<double> S_smooth_log1p;
cv::log(S_smooth / eps + 1, S_smooth_log1p);
cv::Mat_<double> smooth;
cv::exp((S_smooth_log1p + cv::log(eps)) * (-gain), smooth);
//python: S_out = (bias ** power) * np.expm1(power * np.log1p(ref * smooth / bias))
cv::Mat_<double> smooth_log1p;
cv::Mat_<double> smooth_log1p_exp;
cv::log(mel.mul(smooth) / bias + 1, smooth_log1p);
cv::exp(power * smooth_log1p, smooth_log1p_exp);
cv::Mat_<double> S_out = (smooth_log1p_exp - 1) * pow(bias, power);
// transpose
cv::Mat_<double> pcen;
cv::transpose(S_out, pcen);
return pcen;
}

View File

@@ -1,123 +0,0 @@
#pragma once
#include <string>
#include <chrono>
#include <vector>
#include <assert.h>
#include <memory>
#include <fstream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace std::chrono;
class parambase
{
public:
string name;
string help;
string strval;
parambase(){}
virtual ~parambase(){}
virtual bool set(const char* value) {return true;};
};
/**
* 引擎参数
*/
class EnginePar
{
public:
static int cs_timeout; //叫号服务完成的超时时间(默认情况下下一次叫号代表上一次完成,默认值5分钟)
static int cs_detecthandsup_time; //叫号后持续检测举手的时间(默认10s)
static int cs_detecthandsup_interval ; //叫号后持续检测举手的时间间隔(默认1秒1次)
static int cs_detectsmile_interval; //叫号后微笑检测的时间间隔(默认1秒1次)
static int cs_detectspeech_interval;//叫号后语音检测的时间间隔(默认20秒)
static int cs_detectpose_interval; //叫号后姿态检测的时间间隔(默认5秒1次)
static int detectpose_interval; //非叫号期间姿态检测的时间间隔(默认5秒1次)
static int detectsmile_interval; //非叫号期间微笑检测的时间间隔(默认1秒1次)
static int detectappearance_interval; //着装检测间隔
static float action_turnpen_thrd; //转笔阈值
static float action_turnchair_thrd; //转椅阈值
static float action_record_time; //动作录制时长
static float sit_supporthead_thrd; //撑头阈值
static float sit_layondesk_thrd; //趴桌阈值
static float sit_relyingonchair_thrd;//靠椅阈值
static string log_path;
static string log_level;
static string temp_path;
static bool set(const char* key, const char* val);
static bool haskey(const char* key);
static const char* getvalue(const char* key);
};
/**
* 摄像头分析场景
*/
enum VideoScene
{
SCENE_counter, // 柜台
SCENE_financial, // 理财
SCENE_lobby, // 大堂
SCENE_hall // 门厅
};
/**
* 摄像头分析参数
*/
class VideoPar
{
private:
vector<shared_ptr<parambase>> params;
public:
VideoScene scene; //场景: 1柜台, 2理财, 3大堂, 4进门(着装检测)
bool audio_enable ; //音频开关 1开,0关
int audio_channels ; //音频通道数 0,1,2,4,6
int audio_sample_rate ; // 采样率 44100, 48000, 96000, 192000
bool video_enable ; // 视频开关 1开,0关
//int video_analyse_rate ; //视频分析速率: 数字>0,每秒分析帧数
bool video_sample_keyframe; //只解码关键帧
bool video_record; //启用录制视频 1开,0关
int video_record_duration; //视频录制时长,默认10s
int video_record_reviewtime; //视频录制回溯时长,默认5s
int face_minsize; //最小人脸大小
VideoPar();
//~VideoPar();
bool set(const char* key, const char* val);
static bool haskey(const char* key);
};
template<class T>
inline int64_t NowTime()
{
return std::chrono::time_point_cast<T>(std::chrono::system_clock::now()).time_since_epoch().count();
}
/**--------------------------------- 以下是models各个模型所用到的方法 ---------------------------------**/
inline bool detectFileExist(char *file_path) {
std::ifstream _ifstream;
_ifstream.open(file_path, std::ios::in);
if (!_ifstream) {
return false;
}
_ifstream.close();
return true;
}
// 矩阵变换对向量xy进行旋转
inline cv::Mat_<double> rotate_point(cv::Mat_<double> xy, double angle) {
cv::Mat rotate_matrix = (cv::Mat_<double>(2, 2) << cos(angle), -sin(angle), sin(angle), cos(angle));
cv::transpose(rotate_matrix, rotate_matrix);
auto rotate_xy = xy * rotate_matrix;
return rotate_xy;
}
// 检查点是否在框内
inline bool check_point_in_rect(cv::Point point, cv::Rect rect) {
if ((rect.x < point.x && point.x < rect.x + rect.width) &&
(rect.y < point.y && point.y < rect.y + rect.height)) {
return true;//在rect内部
} else {
return false;//在rect边上或外部
}
}

View File

@@ -1,346 +0,0 @@
#include "munet.h"
#include "ncnn/ncnn/cpu.h"
#include "face_utils.h"
#include "blendgram.h"
Mobunet::Mobunet(const char* fnbin,const char* fnparam,const char* fnmsk){
initModel(fnbin,fnparam,fnmsk);
}
Mobunet::Mobunet(const char* modeldir,const char* modelid){
char fnbin[1024];
char fnparam[1024];
char fnmsk[1024];
sprintf(fnbin,"%s/%s.bin",modeldir,modelid);
sprintf(fnparam,"%s/%s.param",modeldir,modelid);
sprintf(fnmsk,"%s/weight_168u.bin",modeldir);
initModel(fnbin,fnparam,fnmsk);
}
int Mobunet::initModel(const char* binfn,const char* paramfn,const char* mskfn){
unet.clear();
//ncnn::set_cpu_powersave(2);
//ncnn::set_omp_num_threads(ncnn::get_big_cpu_count());
unet.opt = ncnn::Option();
//unet.opt.use_vulkan_compute = true;
unet.opt.num_threads =1;// ncnn::get_big_cpu_count();
//unet.load_param("model/mobileunet_v5_wenet_sim.param");
//unet.load_model("model/mobileunet_v5_wenet_sim.bin");
unet.load_param(paramfn);
unet.load_model(binfn);
char* wbuf = NULL;
dumpfile((char*)mskfn,&wbuf);
mat_weights = new JMat(160,160,(uint8_t*)wbuf,1);
mat_weights->forceref(0);
//mat_weights->show("weight");
//cv::waitKey(0);
return 0;
}
Mobunet::~Mobunet(){
unet.clear();
if(mat_weights){
delete mat_weights;
mat_weights = nullptr;
}
}
int Mobunet::domodelold(JMat* pic,JMat* msk,JMat* feat){
JMat picall(160*160,2,3,0,1);
uint8_t* buf = picall.udata();
int width = pic->width();
int height = pic->height();
cv::Mat c1(height,width,CV_8UC3,buf);
cv::Mat c2(height,width,CV_8UC3,buf+width*height*3);
cv::cvtColor(pic->cvmat(),c1,cv::COLOR_RGB2BGR);
cv::cvtColor(msk->cvmat(),c2,cv::COLOR_RGB2BGR);
ncnn::Mat inall = ncnn::Mat::from_pixels(buf, ncnn::Mat::PIXEL_BGR, 160*160, 2);
inall.substract_mean_normalize(mean_vals, norm_vals);
//inall.reshape(160,160,6);
ncnn::Mat inwenet(256,20,1,feat->data());
ncnn::Mat outpic;
ncnn::Extractor ex = unet.create_extractor();
ex.input("face", inall);
ex.input("audio", inwenet);
ex.extract("output", outpic);
float outmean_vals[3] = {-1.0f, -1.0f, -1.0f};
float outnorm_vals[3] = { 0.5f, 0.5f, 0.5f};
outpic.substract_mean_normalize(outmean_vals, outnorm_vals);
ncnn::Mat pakpic;
ncnn::convert_packing(outpic,pakpic,3);
cv::Mat cvadj(160,160,CV_32FC3,pakpic.data);
//dumpfloat((float*)cvadj.data,160*160*3);
cv::Mat cvreal;
float scale = 255.0f;
cvadj.convertTo(cvreal,CV_8UC3,scale);
cv::Mat cvmask;
cv::cvtColor(cvreal,cvmask,cv::COLOR_RGB2BGR);
cv::imshow("cvreal",cvreal);
cv::imshow("cvmask",cvmask);
//cv::waitKey(0);
//getchar();
BlendGramAlpha((uchar*)cvmask.data,(uchar*)mat_weights->data(),(uchar*)pic->data(),160,160);
return 0;
}
int Mobunet::domodel(JMat* pic,JMat* msk,JMat* feat){
//convert to bgr
//pic->tojpg("eee.bmp");
//JMat picmask(160,160,3,0,1);
//JMat picreal(160,160,3,0,1);
//cv::cvtColor(pic->cvmat(),picreal.cvmat(),cv::COLOR_RGB2BGR);
//cv::cvtColor(msk->cvmat(),picmask.cvmat(),cv::COLOR_RGB2BGR);
ncnn::Mat inmask = ncnn::Mat::from_pixels(msk->udata(), ncnn::Mat::PIXEL_BGR2RGB, 160, 160);
inmask.substract_mean_normalize(mean_vals, norm_vals);
ncnn::Mat inreal = ncnn::Mat::from_pixels(pic->udata(), ncnn::Mat::PIXEL_BGR2RGB, 160, 160);
inreal.substract_mean_normalize(mean_vals, norm_vals);
//
//JMat picin(160*160,6);
//char* pd = (char*)picin.data();
//memcpy(pd,inreal.data,160*160*3*4);
//memcpy(pd+ 160*160*3*4,inmask.data,160*160*3*4);
//
//ncnn::Mat inpack(160,160,1,pd,(size_t)4u*6,6);
//ncnn::Mat inpic;
//ncnn::convert_packing(inpack,inpic,1);
ncnn::Mat inpic(160,160,6);
//printf("===in %d %d all %d %d\n",inreal.cstep,inreal.elempack,inpic.cstep,inpic.elempack);
float* buf = (float*)inpic.data;
float* pr = (float*)inreal.data;
//printf("==%d==%f\n",pic->udata()[2],*pr);
memcpy(buf,pr,inreal.cstep*sizeof(float)*inreal.c);
/*
for(int k=0;k<3;k++){
memcpy(buf,pr,inreal.cstep*sizeof(float));
buf += inpic.cstep;
pr += inreal.cstep;
}
*/
buf+= inpic.cstep*inreal.c;
float* pm = (float*)inmask.data;
//printf("=%d===%f\n",msk->udata()[2],*pm);
memcpy(buf,pm,inmask.cstep*sizeof(float)*inmask.c);
/*
for(int k=0;k<3;k++){
memcpy(buf,pm,inreal.cstep*sizeof(float));
buf += inpic.cstep;
pm += inmask.cstep;
}
*/
ncnn::Mat inwenet(256,20,1,feat->data());
//ncnn::Mat inwenet(20,256,1,feat->data());
ncnn::Mat outpic;
ncnn::Extractor ex = unet.create_extractor();
ex.set_num_threads(1);
ex.input("face", inpic);
ex.input("audio", inwenet);
ex.extract("output", outpic);
float outmean_vals[3] = {-1.0f, -1.0f, -1.0f};
float outnorm_vals[3] = { 127.5f, 127.5f, 127.5f};
outpic.substract_mean_normalize(outmean_vals, outnorm_vals);
cv::Mat cvout(160,160,CV_8UC3);
outpic.to_pixels(cvout.data,ncnn::Mat::PIXEL_RGB2BGR);
BlendGramAlpha((uchar*)cvout.data,(uchar*)mat_weights->data(),(uchar*)pic->data(),160,160);
// ex.clear();
// inmask.release();
// inreal.release();
// inpic.release();
// buf=nullptr;
// pr=nullptr;
// pm=nullptr;
// inwenet.release();
// outpic.release();
//pic->tojpg("fff.bmp");
//getchar();
/*
ncnn::Mat pakpic;
ncnn::convert_packing(outpic,pakpic,3);
cv::Mat cvadj(160,160,CV_32FC3,pakpic.data);
//dumpfloat((float*)cvadj.data,160*160*3);
float scale = 255.0f;
cvadj.convertTo(picreal.cvmat(),CV_8UC3,scale);
cv::cvtColor(picreal.cvmat(),picmask.cvmat(),cv::COLOR_RGB2BGR);
*/
//getchar();
//getchar();
//cv::Mat cout;
//cv::cvtColor(picreal.cvmat(),cout,cv::COLOR_RGB2BGR);
//BlendGramAlpha((uchar*)cout.data,(uchar*)mat_weights->data(),(uchar*)pic->data(),160,160);
/*
float outmean_vals[3] = {-1.0f, -1.0f, -1.0f};
// float outnorm_vals[3] = { 2.0f, 2.0f, 2.0f};
float outnorm_vals[3] = { 127.5f, 127.5f, 127.5f};
outpic.substract_mean_normalize(outmean_vals, outnorm_vals);
ncnn::Mat pakpic;
ncnn::convert_packing(outpic,pakpic,3);
//
cv::Mat cvadj(160,160,CV_32FC3,pakpic.data);
//
float scale = 1.0f;
cvadj.convertTo(picreal.cvmat(),CV_8UC3,scale);
cv::Mat cout;
cv::cvtColor(picreal.cvmat(),cout,cv::COLOR_RGB2BGR);
BlendGramAlpha((uchar*)cout.data,(uchar*)mat_weights->data(),(uchar*)pic->data(),160,160);
//BlendGramAlpha((uchar*)picreal.udata(),(uchar*)mat_weights->data(),(uchar*)pic->data(),160,160);
//cv::cvtColor(picreal.cvmat(),pic->cvmat(),cv::COLOR_RGB2BGR);
*/
return 0;
}
int Mobunet::preprocess(JMat* pic,JMat* feat){
//pic 168
cv::Mat roipic(pic->cvmat(),cv::Rect(4,4,160,160));
JMat picmask(160,160,3,0,1);
JMat picreal(160,160,3,0,1);
cv::Mat cvmask = picmask.cvmat();
cv::Mat cvreal = picreal.cvmat();
roipic.copyTo(cvmask);
roipic.copyTo(cvreal);
cv::rectangle(cvmask,cv::Rect(5,5,150,145),cv::Scalar(0,0,0),-1);//,cv::LineTypes::FILLED);
domodel(&picreal,&picmask,feat);
cvreal.copyTo(roipic);
return 0;
}
int Mobunet::fgprocess(JMat* pic,const int* boxs,JMat* feat,JMat* fg){
int boxx, boxy ,boxwidth, boxheight ;
boxx = boxs[0];boxy=boxs[1];boxwidth=boxs[2]-boxx;boxheight=boxs[3]-boxy;
int stride = pic->stride();
cv::Mat roisrc(pic->cvmat(),cv::Rect(boxx,boxy,boxwidth,boxheight));
cv::Mat cvorig;
cv::resize(roisrc , cvorig, cv::Size(168, 168), cv::INTER_AREA);
JMat pic168(168,168,(uint8_t*)cvorig.data);
preprocess(&pic168,feat);
cv::Mat cvrst;;
cv::resize(cvorig , cvrst, cv::Size(boxwidth, boxheight), cv::INTER_AREA);
cv::Mat roidst(fg->cvmat(),cv::Rect(boxx,boxy,boxwidth,boxheight));
cvrst.copyTo(roidst);
return 0;
}
int Mobunet::process(JMat* pic,const int* boxs,JMat* feat){
int boxx, boxy ,boxwidth, boxheight ;
boxx = boxs[0];boxy=boxs[1];boxwidth=boxs[2]-boxx;boxheight=boxs[3]-boxy;
int stride = pic->stride();
cv::Mat roisrc(pic->cvmat(),cv::Rect(boxx,boxy,boxwidth,boxheight));
cv::Mat cvorig;
cv::resize(roisrc , cvorig, cv::Size(168, 168), cv::INTER_AREA);
JMat pic168(168,168,(uint8_t*)cvorig.data);
preprocess(&pic168,feat);
cv::Mat cvrst;;
cv::resize(cvorig , cvrst, cv::Size(boxwidth, boxheight), cv::INTER_AREA);
cvrst.copyTo(roisrc);
return 0;
}
int Mobunet::process2(JMat* pic,const int* boxs,JMat* feat){
int boxx, boxy ,boxwidth, boxheight ;
boxx = boxs[0];boxy=boxs[1];boxwidth=boxs[2]-boxx;boxheight=boxs[3]-boxy;
int stride = pic->stride();
cv::Mat cvsrc = pic->cvmat();
printf("cvsrc %d %d \n",cvsrc.cols,cvsrc.rows);
cv::Mat roisrc(cvsrc,cv::Rect(boxx,boxy,boxwidth,boxheight));
cv::Mat cvorig;
cv::resize(roisrc , cvorig, cv::Size(168, 168), cv::INTER_AREA);
/*
uint8_t* data =(uint8_t*)pic->data() + boxy*stride + boxx*pic->channel();
int scale_w = 168;
int scale_h = 168;
ncnn::Mat prepic = ncnn::Mat::from_pixels_resize(data, ncnn::Mat::PIXEL_BGR, boxwidth, boxheight, stride,scale_w, scale_h);
//pic 168
cv::Mat cvorig(168,168,CV_8UC3,prepic.data);
*/
cv::Mat roimask(cvorig,cv::Rect(4,4,160,160));
JMat picmask(160,160,3,0,1);
JMat picreal(160,160,3,0,1);
cv::Mat cvmask = picmask.cvmat();
cv::Mat cvreal = picreal.cvmat();
roimask.copyTo(cvmask);
roimask.copyTo(cvreal);
cv::rectangle(cvmask,cv::Rect(5,5,150,150),cv::Scalar(0,0,0),-1);//,cv::LineTypes::FILLED);
// cv::imshow("000",cvorig);
// cv::imshow("aaa",cvmask);
// cv::imshow("bbb",cvreal);
// cv::waitKey(0);
ncnn::Mat inmask = ncnn::Mat::from_pixels(picmask.udata(), ncnn::Mat::PIXEL_BGR2RGB, 160, 160);
inmask.substract_mean_normalize(mean_vals, norm_vals);
ncnn::Mat inreal = ncnn::Mat::from_pixels(picreal.udata(), ncnn::Mat::PIXEL_BGR2RGB, 160, 160);
inreal.substract_mean_normalize(mean_vals, norm_vals);
JMat picin(160*160,2,3);
char* pd = (char*)picin.data();
memcpy(pd,inreal.data,160*160*3*4);
memcpy(pd+ 160*160*3*4,inmask.data,160*160*3*4);
// char* pinpic = NULL;
// dumpfile("pic.bin",&pinpic);
// dumpfloat((float*)pd,10);
// dumpfloat((float*)pinpic,10);
//ncnn::Mat inpic(160,160,6,pd,4);
ncnn::Mat inpack(160,160,1,pd,(size_t)4u*6,6);
ncnn::Mat inpic;
ncnn::convert_packing(inpack,inpic,1);
// char* pwenet = NULL;
// dumpfile("wenet.bin",&pwenet);
ncnn::Mat inwenet(256,20,1,feat->data(),4);
ncnn::Mat outpic;
ncnn::Extractor ex = unet.create_extractor();
ex.input("face", inpic);
ex.input("audio", inwenet);
ex.extract("output", outpic);
float outmean_vals[3] = {-1.0f, -1.0f, -1.0f};
// float outnorm_vals[3] = { 2.0f, 2.0f, 2.0f};
float outnorm_vals[3] = { 127.5f, 127.5f, 127.5f};
outpic.substract_mean_normalize(outmean_vals, outnorm_vals);
ncnn::Mat pakpic;
ncnn::convert_packing(outpic,pakpic,3);
cv::Mat cvadj(160,160,CV_32FC3,pakpic.data);
cv::Mat cvout(160,160,CV_8UC3);
float scale = 1.0f;
cvadj.convertTo(cvout,CV_8UC3,scale);
//cv::imwrite("cvout.jpg",cvout);
cv::cvtColor(cvout,roimask,cv::COLOR_RGB2BGR);
// cvout.copyTo(roimask);
//cv::imwrite("roimask.jpg",roimask);
//cv::imwrite("cvorig.jpg",cvorig);
//cv::waitKey(0);
cv::resize(cvorig , roisrc, cv::Size(boxwidth, boxheight), cv::INTER_AREA);
//cv::imwrite("roisrc.jpg",roisrc);
//cv::imshow("cvsrc",cvsrc);
// cv::imshow("roisrc",roisrc);
// cv::imshow("cvorig",cvorig);
// cv::waitKey(20);
/*
{
uint8_t *pr = (uint8_t *) cvoutc.data;
printf("==%u %u %u\n", pr[0], pr[1], pr[2]);
}
//
float* p = (float*)cvadj.data;
printf("==%f %f %f\n",p[0],p[1],p[2]);
p+=160*160;
printf("==%f %f %f\n",p[0],p[1],p[2]);
p+=160*160;
printf("==%f %f %f\n",p[0],p[1],p[2]);
*/
return 0;
}

View File

@@ -1,28 +0,0 @@
#pragma once
#include "jmat.h"
#include "ncnn/ncnn/net.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <stdio.h>
#include <vector>
class Mobunet{
private:
ncnn::Net unet;
float mean_vals[3] = {127.5f, 127.5f, 127.5f};
float norm_vals[3] = {1 / 127.5f, 1 / 127.5f, 1 / 127.5f};
JMat* mat_weights = nullptr;
int initModel(const char* binfn,const char* paramfn,const char* mskfn);
public:
int domodel(JMat* pic,JMat* msk,JMat* feat);
int domodelold(JMat* pic,JMat* msk,JMat* feat);
int preprocess(JMat* pic,JMat* feat);
int process(JMat* pic,const int* boxs,JMat* feat);
int fgprocess(JMat* pic,const int* boxs,JMat* feat,JMat* fg);
int process2(JMat* pic,const int* boxs,JMat* feat);
Mobunet(const char* modeldir,const char* modelid);
Mobunet(const char* fnbin,const char* fnparam,const char* fnmsk);
~Mobunet();
};

View File

@@ -1,275 +0,0 @@
#include "netwav.h"
#include "face_utils.h"
#include "jlog.h"
#include "wavreader.h"
int KWav::initbuf(int pcmsample){
m_pcmsample = pcmsample;
m_wavsample = pcmsample + 2*MFCC_OFFSET;
m_seca = m_wavsample / MFCC_WAVCHUNK;
m_secb = m_wavsample % MFCC_WAVCHUNK;
m_mellast = m_secb?(m_secb /160 +1):0;
m_bnflast = m_secb?((m_mellast*0.25f)-0.75f):0;
m_wavsize = m_seca*MFCC_WAVCHUNK + m_secb;
m_melsize = m_seca*MFCC_MELBASE+m_mellast;
m_bnfsize = m_seca*MFCC_BNFBASE+m_bnflast;
//m_calcsize = m_seca+m_secb?1:0;
m_calcsize = m_seca+(m_secb?1:0);
m_wavmat = new JMat(MFCC_WAVCHUNK,m_calcsize,1);
m_wavmat->zeros();
m_melmat = new JMat(MFCC_MELCHUNK*MFCC_MELBASE,m_calcsize,1);
m_melmat->zeros();
//m_bnfmat = new JMat(MFCC_BNFCHUNK*MFCC_BNFBASE,m_calcsize,1);
//m_bnfmat->zeros();
m_bnfblock = m_duration*MFCC_FPS;
if(m_bnfblock>(m_bnfsize-10))m_bnfblock = m_bnfsize-10;
LOGD("==seca %d secb %d\n",m_seca,m_secb);
LOGD("==melsize %d bnfsize %d\n",m_melsize,m_bnfsize);
return 0;
}
int KWav::initinx(){
m_curwav = m_wavmat->fdata() + MFCC_OFFSET;
m_leftsample = m_pcmsample;
m_waitsample = MFCC_OFFSET;
/*
int* arr = m_bnfmat->tagarr();
arr[0] = m_pcmsample*2;
arr[1] = m_pcmsample;
arr[2] = m_seca;
arr[3] = m_secb;
arr[4] = m_melsize;
arr[5] = m_bnfsize;
*/
float secs = m_pcmsample*1.0f/ MFCC_RATE;
int bnfblock = secs*MFCC_FPS;
if(bnfblock>(m_bnfsize-10))bnfblock = m_bnfsize-10;
//arr[6] = bnfblock;//m_bnfblock;
//
//LOGD("my==bnfblock %d arr6 %d",bnfblock,arr[6]);
//LOGD("myarr %d %d %d %d %d %d %d",arr[0],arr[1],arr[2],arr[3],arr[4],arr[5],arr[6]);
return 0;
}
int KWav::incsample(int sample){
if(sample<1)return 0;
m_leftsample -= sample;
m_waitsample += sample;
//LOGD("===incsample %d left %d wait %d\n",sample,m_leftsample,m_waitsample);
while(m_waitsample>MFCC_WAVCHUNK){
m_waitsample -= MFCC_WAVCHUNK;
m_waitcnt += 1;
LOGD("===tooken calc %d waitcnt %d calc %d\n",m_calcsize,m_waitcnt,m_calccnt);
LOGD("===tooken m_ldftsample %d\n",m_leftsample);
}
if(m_leftsample<=0){
m_waitcnt = m_calcsize;
LOGD("===tooken m_ldftsample %d\n",m_leftsample);
LOGD("===tooken calc %d waitcnt %d\n",m_calcsize,m_waitcnt);
}
return 0;
}
int KWav::pushpcm(uint8_t* pcm,int size){
uint8_t* pstart = pcm;
int psize = size;
if(m_alonecnt){
pstart++;
psize--;
m_alonearr[1]=*pcm;
float* ps = (float*)m_alonearr;
*m_curwav++ = (float)(*ps++/32767.f);
incsample(1);
m_alonecnt = 0;
}
int sample = psize / 2;
//LOGD("push pcm %d left_sample %d\n",sample,m_leftsample);
int left = psize % 2;
if(sample>m_leftsample){
sample = m_leftsample;
left = 0;
}
short* ps = (short*)pstart;
float* pf = m_curwav;
for(int k=0;k<sample;k++){
*pf++ = (float)(*ps++/32767.f);
}
m_curwav = pf;
//LOGD("push pcm %d\n",sample);
incsample(sample);
if(left){
uint8_t* pc = (uint8_t*)ps;
m_alonearr[0] = *pc;
m_alonecnt = 1;
}
return sample;
}
/*
int KWav::loadfn(const char* wavfile){
int format, channels, sr, bits_per_sample;
unsigned int data_length;
void* fhnd = wav_read_open(wavfile);
if(!fhnd)return -1;
int res = wav_get_header(fhnd, &format, &channels, &sr, &bits_per_sample, &data_length);
if(data_length<1) return -2;
//init
initbuf(data_length/2);
//
wav_read_close(fhnd);
return 0;
}
*/
KWav::KWav(const char* filename,MBnfCache* bnfcache,float duration){
m_bnfcache = bnfcache;
std::string wavfile(filename);
int format, channels, sr, bits_per_sample;
unsigned int data_length;
void* fhnd = wav_read_open(wavfile.c_str());
if(!fhnd){
m_duration = 0;
return;
}
int res = wav_get_header(fhnd, &format, &channels, &sr, &bits_per_sample, &data_length);
if(duration>0)
{
data_length=duration*(channels *bits_per_sample*sr/8);
}
if(data_length<1) {
m_duration = 0;
return;
}
int sample = data_length/2;
m_duration = sample*1.0f/16000.0f;
initbuf(sample);
initinx();
JBuf* pcmbuf = new JBuf(data_length);
int rst = wav_read_data(fhnd,(unsigned char*)pcmbuf->data(),data_length);
//
short* ps = (short*)pcmbuf->data();
float* pd = (float*)m_wavmat->data();
float* pf = pd+MFCC_OFFSET;
for(int k=0;k<sample;k++){
*pf++ = (float)(*ps++/ 32767.f);
}
incsample(sample);
readyall();
delete pcmbuf;
}
KWav::KWav(float duration,MBnfCache* bnfcache){
m_bnfcache = bnfcache;
m_duration = duration;
int sample = duration*16000;
initbuf(sample);
initinx();
}
KWav::~KWav(){
if(m_wavmat){
delete m_wavmat;
m_wavmat = nullptr;
}
if(m_melmat){
delete m_melmat;
m_melmat = nullptr;
}
//if(m_bnfmat){
//delete m_bnfmat;
//m_bnfmat = nullptr;
//}
}
int KWav::bnfblocks(){
return m_bnfblock;
}
/*
JMat* KWav::bnfmat(){
return m_bnfmat;
}
*/
int KWav::finishone(int index){
m_resultcnt = index;
//int* arr = m_bnfmat->tagarr();
float secs = index*MFCC_WAVCHUNK *1.0f/ MFCC_RATE;
if(m_resultcnt==m_calccnt){
secs = m_pcmsample*1.0f/ MFCC_RATE;
}else{
secs = index*MFCC_WAVCHUNK *1.0f/ MFCC_RATE;
}
int bnfblock = secs*MFCC_FPS;
if(bnfblock>(m_bnfsize-10))bnfblock = m_bnfsize-10;
//arr[7] = bnfblock;
return 0;
}
int KWav::isfinish(){
if((m_waitcnt == m_calcsize)&&(m_calcsize== m_calccnt)){
return m_resultcnt==m_calccnt;
}else{
return 0;
}
}
int KWav::readyall(){
m_waitcnt=m_calcsize;
return 0;
}
int KWav::isready(){
if(m_waitcnt>m_calccnt){
return ++m_calccnt;
}else{
return 0;
}
}
int KWav::calcbuf(int calcinx,float** ppwav,float** ppmfcc,float** ppbnf,int* pmel,int* pbnf){
if(calcinx>m_calcsize)return -1;
if(calcinx<1)return -2;
int index = calcinx -1;
//LOGD("===tooken calcbuf %d\n",index);
*ppwav = m_wavmat->frow(index);
*ppmfcc = m_melmat->frow(index);
//*ppbnf = m_bnfmat->frow(index);
*ppbnf = m_bnfcache->secBuf(index)->fdata();
if(calcinx==m_calcsize){
*pmel = m_mellast;
*pbnf = m_bnflast;
}else{
*pmel = MFCC_MELBASE;
*pbnf = MFCC_BNFBASE;
}
return calcinx;
}
float KWav::duration(){
return m_duration;
}
int KWav::resultcnt(){
return m_resultcnt;
}
int KWav::debug(){
//dumpfloat(m_bnfmat->fdata(),10);
return 0;
}

View File

@@ -1,56 +0,0 @@
#pragma once
#include "jmat.h"
#include "aicommon.h"
#include "wavcache.h"
class KWav{
private:
float m_duration = 0;
int m_pcmsample = 0;;
int m_wavsample = 0;;
int m_seca = 0;
int m_secb = 0;
int m_mellast = 0;
int m_bnflast = 0;
int m_wavsize = 0;
int m_melsize = 0;
int m_bnfsize = 0;
int m_calcsize = 0;
int m_bnfblock = 0;
uint8_t m_alonearr[2] ;
int m_alonecnt = 0;
int m_leftsample = 0;
float *m_curwav = nullptr;
int m_waitsample = 0;
int m_waitcnt = 0;
int m_calccnt = 0;
int m_resultcnt = 0;
int incsample(int sample);
JMat *m_wavmat = nullptr;
JMat *m_melmat = nullptr;
//JMat *m_bnfmat = nullptr;
MBnfCache *m_bnfcache = nullptr;
int initbuf(int pcmsample);
int initinx();
public:
KWav(float duration,MBnfCache* bnfcache);
KWav(const char* filename,MBnfCache* bnfcache,float duration);
//KWav(const char* wavfn);
~KWav();
int pushpcm(uint8_t* pcm,int size);
int isready();
int readyall();
int isfinish();
int finishone(int index);
int bnfblocks();
float duration();
int resultcnt();
//JMat* bnfmat();
int calcbuf(int calcinx,float** ppwav,float** ppmfcc,float** ppbnf,int* pmel,int* pbnf);
int debug();
};

View File

@@ -1,200 +0,0 @@
#include "pfpld.h"
#include "ncnn/ncnn/cpu.h"
static int pts68_pfpld(float* arr_pts98,float* arr_pts68){
float* arr = arr_pts98;
float* dst = arr_pts68;
for(int j=0;j<17;j++){
*dst++ = arr[j*4];
*dst++ = arr[j*4 + 1];
}
for(int j=33;j<38;j++){
*dst++ = arr[j*2];
*dst++ = arr[j*2 + 1];
}
for(int j=42;j<47;j++){
*dst++ = arr[j*2];
*dst++ = arr[j*2 + 1];
}
for(int j=51;j<61;j++){
*dst++ = arr[j*2];
*dst++ = arr[j*2 + 1];
}
float* points = arr;
float point_38_x = (float(points[60 * 2 + 0]) + float(points[62 * 2 + 0])) / 2.0;
float point_38_y = (float(points[60 * 2 + 1]) + float(points[62 * 2 + 1])) / 2.0;
float point_39_x = (float(points[62 * 2 + 0]) + float(points[64 * 2 + 0])) / 2.0;
float point_39_y = (float(points[62 * 2 + 1]) + float(points[64 * 2 + 1])) / 2.0;
float point_41_x = (float(points[64 * 2 + 0]) + float(points[66 * 2 + 0])) / 2.0;
float point_41_y = (float(points[64 * 2 + 1]) + float(points[66 * 2 + 1])) / 2.0;
float point_42_x = (float(points[60 * 2 + 0]) + float(points[66 * 2 + 0])) / 2.0;
float point_42_y = (float(points[60 * 2 + 1]) + float(points[66 * 2 + 1])) / 2.0;
float point_44_x = (float(points[68 * 2 + 0]) + float(points[70 * 2 + 0])) / 2.0;
float point_44_y = (float(points[68 * 2 + 1]) + float(points[70 * 2 + 1])) / 2.0;
float point_45_x = (float(points[70 * 2 + 0]) + float(points[72 * 2 + 0])) / 2.0;
float point_45_y = (float(points[70 * 2 + 1]) + float(points[72 * 2 + 1])) / 2.0;
float point_47_x = (float(points[72 * 2 + 0]) + float(points[74 * 2 + 0])) / 2.0;
float point_47_y = (float(points[72 * 2 + 1]) + float(points[74 * 2 + 1])) / 2.0;
float point_48_x = (float(points[68 * 2 + 0]) + float(points[74 * 2 + 0])) / 2.0;
float point_48_y = (float(points[68 * 2 + 1]) + float(points[74 * 2 + 1])) / 2.0;
*dst++ = point_38_x;
*dst++ = point_38_y;
*dst++ = point_39_x;
*dst++ = point_39_y;
*dst++ = points[64 * 2 + 0];
*dst++ = points[64 * 2 + 1];
*dst++ = point_41_x;
*dst++ = point_41_y;
*dst++ = point_42_x;
*dst++ = point_42_y;
*dst++ = points[68 * 2 + 0];
*dst++ = points[68 * 2 + 1];
*dst++ = point_44_x;
*dst++ = point_44_y;
*dst++ = point_45_x;
*dst++ = point_45_y;
*dst++ = points[72 * 2 + 0];
*dst++ = points[72 * 2 + 1];
*dst++ = point_47_x;
*dst++ = point_47_y;
*dst++ = point_48_x;
*dst++ = point_48_y;
for(int j = 76; j<96;j++){
*dst++ = points[j * 2 + 0];
*dst++ = points[j * 2 + 1];
}
int len = dst-arr_pts68;
printf("====%d\n",len);
return len;
}
int Pfpld::detect(JMat* pic,int* arrboxs,int* arrlands){
int w = arrboxs[0];
int h = arrboxs[1];
int boxx, boxy ,boxwidth, boxheight ;
int* boxs = arrboxs+6;
boxx = boxs[0];boxy=boxs[1];boxwidth=boxs[2]-boxx;boxheight=boxs[3]-boxy;
printf("===pfpld %d %d %d %d\n",boxx,boxy,boxwidth,boxheight);
//boxx=192; boxy =245 ; boxwidth=908 -boxx;boxheight=1203 - boxy;
int stride = pic->stride();
uint8_t* data =(uint8_t*)pic->data() + boxy*stride + boxx*pic->channel();
ncnn::Mat in = ncnn::Mat::from_pixels_resize(data, ncnn::Mat::PIXEL_BGR2RGB, boxwidth, boxheight, stride,scale_w, scale_h);
in.substract_mean_normalize(mean_vals, norm_vals);
ncnn::Extractor ex = pfpld.create_extractor();
ex.input("input", in);
ncnn::Mat pose_blob, landms_blob;
ex.extract("pose", pose_blob);
ex.extract("landms", landms_blob);
float* arr = (float*)landms_blob.data;
float tmpdst[512];
float* dst = tmpdst;
pts68_pfpld(arr,dst);
int len = 68*2;
int* apts = arrlands;
int axmin = 10000,aymin = 10000,axmax = 0,aymax = 0;
for(int j=0;j<len/2;j++){
float x = *dst++ * boxwidth + boxx;
float y = *dst++ * boxheight + boxy;
apts[0] = x;
apts[1] = y;
printf("==adj %d x %f y %f\n",j,x,y);
if(axmin>x) axmin = x;
if(axmax<x) axmax = x;
if(aymin>y) aymin = y;
if(aymax<y) aymax = y;
apts += 2;
}
printf("===all xmin %d ymin %d xmax %d ymax %d\n",axmin,aymin,axmax,aymax);
m_wh = (axmax-axmin)*1.0f/(aymax-aymin);
if(m_wh>1.0f)m_wh = 1.0f;
printf("====wh %f\n",m_wh);
float wh = m_wh;//0.8878923766816144;
int xmin = 10000,ymin = 10000,xmax = 0,ymax = 0;
apts = arrlands+2;
for(int j=1;j<16;j++){
int x = *apts++;
int y = *apts++;
if(xmin>x) xmin = x;
if(xmax<x) xmax = x;
if(ymin>y) ymin = y;
if(ymax<y) ymax = y;
printf("==min one %d x %d y %d\n",j,x,y);
}
printf("===b1 xmin %d ymin %d xmax %d ymax %d\n",xmin,ymin,xmax,ymax);
apts = arrlands+30*2;
for(int j=31;j<68;j++){
int x = *apts++;
int y = *apts++;
if(xmin>x) xmin = x;
if(xmax<x) xmax = x;
if(ymin>y) ymin = y;
if(ymax<y) ymax = y;
printf("==min two %d x %d y %d\n",j,x,y);
}
printf("===xmin %d ymin %d xmax %d ymax %d\n",xmin,ymin,xmax,ymax);
int rw = xmax-xmin;
int rh = ymax-ymin;
int x_c = xmin + rw/2;
float x1,x2,y1,y2;
x1 = x_c - rw*0.5f/wh;
x2 = x_c + rw*0.5f/wh;
y1 = ymin + rw*0.11f/wh;
y2 = ymin + rw*1.11f/wh;
if(x1<0)x1=0;
if(y1<0)y1=0;
if(x2>=m_width)x2=m_width-1;
if(y2>=m_height)y2=m_height-1;
boxs = arrboxs+10;
*boxs++ = x1;
*boxs++ = y1;
*boxs++ = x2;
*boxs++ = y2;
return 0;
}
void Pfpld::recal(int w,int h){
m_width = w;
m_height = h;
}
Pfpld::Pfpld(const char* modeldir,const char* modelid,int w,int h){
pfpld.clear();
ncnn::set_cpu_powersave(2);
ncnn::set_omp_num_threads(ncnn::get_big_cpu_count());
pfpld.opt = ncnn::Option();
//pfpld.opt.use_vulkan_compute = true;
pfpld.opt.num_threads = ncnn::get_big_cpu_count();
//pfpld.load_param("model/pfpld.param");
//pfpld.load_model("model/pfpld.bin");
char filepath[1024];
sprintf(filepath,"%s/%s.param",modeldir,modelid);
pfpld.load_param(filepath);
sprintf(filepath,"%s/%s.bin",modeldir,modelid);
pfpld.load_model(filepath);
recal(w,h);
}
Pfpld::~Pfpld(){
}
#ifdef _PFPLD_MAIN_
int main(int argc,char** argv){
Pfpld* pfpld = new Pfpld(1080,1920);
std::string picfile("1.jpg");
JMat* pic = new JMat(picfile,1);
int* arr = pic->tagarr();
pfpld->detect(pic,arr+6,arr+64);
printf("precess to exit\n");
getchar();
return 0;
}
#endif

View File

@@ -1,27 +0,0 @@
#pragma once
#include "jmat.h"
#include "ncnn/ncnn/net.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <stdio.h>
#include <vector>
class Pfpld{
private:
ncnn::Net pfpld;
JMat* m_mat112;
int scale_w = 112;
int scale_h = 112;
float mean_vals[3] = {0.f, 0.f, 0.f};
float norm_vals[3] = {1 / 255.f, 1 / 255.f, 1 / 255.f};
int m_width;
int m_height;
float m_wh;
int m_cnt;
void recal(int w,int h);
public:
int detect(JMat* pic,int* arrboxs,int* arrlands);
Pfpld(const char* modeldir,const char* modelid,int w,int h);
~Pfpld();
};

View File

@@ -1,487 +0,0 @@
#include "scrfd.h"
#include "ncnn/ncnn/cpu.h"
static int drawface(cv::Mat& rgb, const std::vector<FaceObject>& faceobjects)
{
int has_kps = 1;
for (size_t i = 0; i < faceobjects.size(); i++)
{
const FaceObject& obj = faceobjects[i];
// fprintf(stderr, "%.5f at %.2f %.2f %.2f x %.2f\n", obj.prob,
// obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height);
cv::rectangle(rgb, obj.rect, cv::Scalar(0, 255, 0));
if (has_kps)
{
cv::circle(rgb, obj.landmark[0], 2, cv::Scalar(255, 255, 0), -1);
cv::circle(rgb, obj.landmark[1], 2, cv::Scalar(255, 255, 0), -1);
cv::circle(rgb, obj.landmark[2], 2, cv::Scalar(255, 255, 0), -1);
cv::circle(rgb, obj.landmark[3], 2, cv::Scalar(255, 255, 0), -1);
cv::circle(rgb, obj.landmark[4], 2, cv::Scalar(255, 255, 0), -1);
}
char text[256];
sprintf(text, "%.1f%%", obj.prob * 100);
int baseLine = 0;
cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
int x = obj.rect.x;
int y = obj.rect.y - label_size.height - baseLine;
if (y < 0)
y = 0;
if (x + label_size.width > rgb.cols)
x = rgb.cols - label_size.width;
cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)), cv::Scalar(255, 255, 255), -1);
cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0), 1);
}
return 0;
}
static inline float intersection_area(const FaceObject& a, const FaceObject& b)
{
cv::Rect_<float> inter = a.rect & b.rect;
return inter.area();
}
static void qsort_descent_inplace(std::vector<FaceObject>& faceobjects, int left, int right)
{
int i = left;
int j = right;
float p = faceobjects[(left + right) / 2].prob;
while (i <= j)
{
while (faceobjects[i].prob > p)
i++;
while (faceobjects[j].prob < p)
j--;
if (i <= j)
{
// swap
std::swap(faceobjects[i], faceobjects[j]);
i++;
j--;
}
}
// #pragma omp parallel sections
{
// #pragma omp section
{
if (left < j) qsort_descent_inplace(faceobjects, left, j);
}
// #pragma omp section
{
if (i < right) qsort_descent_inplace(faceobjects, i, right);
}
}
}
static void qsort_descent_inplace(std::vector<FaceObject>& faceobjects)
{
if (faceobjects.empty())
return;
qsort_descent_inplace(faceobjects, 0, faceobjects.size() - 1);
}
static void nms_sorted_bboxes(const std::vector<FaceObject>& faceobjects, std::vector<int>& picked, float nms_threshold)
{
picked.clear();
const int n = faceobjects.size();
std::vector<float> areas(n);
for (int i = 0; i < n; i++)
{
areas[i] = faceobjects[i].rect.area();
}
for (int i = 0; i < n; i++)
{
const FaceObject& a = faceobjects[i];
int keep = 1;
for (int j = 0; j < (int)picked.size(); j++)
{
const FaceObject& b = faceobjects[picked[j]];
// intersection over union
float inter_area = intersection_area(a, b);
float union_area = areas[i] + areas[picked[j]] - inter_area;
// float IoU = inter_area / union_area
if (inter_area / union_area > nms_threshold)
keep = 0;
}
if (keep)
picked.push_back(i);
}
}
// insightface/detection/scrfd/mmdet/core/anchor/anchor_generator.py gen_single_level_base_anchors()
static ncnn::Mat generate_anchors(int base_size, const ncnn::Mat& ratios, const ncnn::Mat& scales)
{
int num_ratio = ratios.w;
int num_scale = scales.w;
ncnn::Mat anchors;
anchors.create(4, num_ratio * num_scale);
const float cx = 0;
const float cy = 0;
for (int i = 0; i < num_ratio; i++)
{
float ar = ratios[i];
int r_w = round(base_size / sqrt(ar));
int r_h = round(r_w * ar); //round(base_size * sqrt(ar));
for (int j = 0; j < num_scale; j++)
{
float scale = scales[j];
float rs_w = r_w * scale;
float rs_h = r_h * scale;
float* anchor = anchors.row(i * num_scale + j);
anchor[0] = cx - rs_w * 0.5f;
anchor[1] = cy - rs_h * 0.5f;
anchor[2] = cx + rs_w * 0.5f;
anchor[3] = cy + rs_h * 0.5f;
}
}
return anchors;
}
static void generate_proposals(const ncnn::Mat& anchors, int feat_stride, const ncnn::Mat& score_blob, const ncnn::Mat& bbox_blob, const ncnn::Mat& kps_blob, float prob_threshold, std::vector<FaceObject>& faceobjects)
{
int w = score_blob.w;
int h = score_blob.h;
// generate face proposal from bbox deltas and shifted anchors
const int num_anchors = anchors.h;
for (int q = 0; q < num_anchors; q++)
{
const float* anchor = anchors.row(q);
const ncnn::Mat score = score_blob.channel(q);
const ncnn::Mat bbox = bbox_blob.channel_range(q * 4, 4);
// shifted anchor
float anchor_y = anchor[1];
float anchor_w = anchor[2] - anchor[0];
float anchor_h = anchor[3] - anchor[1];
for (int i = 0; i < h; i++)
{
float anchor_x = anchor[0];
for (int j = 0; j < w; j++)
{
int index = i * w + j;
float prob = score[index];
if (prob >= prob_threshold)
{
// insightface/detection/scrfd/mmdet/models/dense_heads/scrfd_head.py _get_bboxes_single()
float dx = bbox.channel(0)[index] * feat_stride;
float dy = bbox.channel(1)[index] * feat_stride;
float dw = bbox.channel(2)[index] * feat_stride;
float dh = bbox.channel(3)[index] * feat_stride;
// insightface/detection/scrfd/mmdet/core/bbox/transforms.py distance2bbox()
float cx = anchor_x + anchor_w * 0.5f;
float cy = anchor_y + anchor_h * 0.5f;
float x0 = cx - dx;
float y0 = cy - dy;
float x1 = cx + dw;
float y1 = cy + dh;
FaceObject obj;
obj.rect.x = x0;
obj.rect.y = y0;
obj.rect.width = x1 - x0 + 1;
obj.rect.height = y1 - y0 + 1;
obj.prob = prob;
if (!kps_blob.empty())
{
const ncnn::Mat kps = kps_blob.channel_range(q * 10, 10);
obj.landmark[0].x = cx + kps.channel(0)[index] * feat_stride;
obj.landmark[0].y = cy + kps.channel(1)[index] * feat_stride;
obj.landmark[1].x = cx + kps.channel(2)[index] * feat_stride;
obj.landmark[1].y = cy + kps.channel(3)[index] * feat_stride;
obj.landmark[2].x = cx + kps.channel(4)[index] * feat_stride;
obj.landmark[2].y = cy + kps.channel(5)[index] * feat_stride;
obj.landmark[3].x = cx + kps.channel(6)[index] * feat_stride;
obj.landmark[3].y = cy + kps.channel(7)[index] * feat_stride;
obj.landmark[4].x = cx + kps.channel(8)[index] * feat_stride;
obj.landmark[4].y = cy + kps.channel(9)[index] * feat_stride;
}
faceobjects.push_back(obj);
}
anchor_x += feat_stride;
}
anchor_y += feat_stride;
}
}
}
int Scrfd::detect(JMat* pic,int* boxs){
recal(pic->width(),pic->height());
ncnn::Mat in = ncnn::Mat::from_pixels_resize(pic->udata(), ncnn::Mat::PIXEL_BGR2RGB, m_width, m_height, scale_w, scale_h);
ncnn::Mat in_pad;
ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, ncnn::BORDER_CONSTANT, 0.f);
in_pad.substract_mean_normalize(mean_vals, norm_vals);
int has_kps = 1;
ncnn::Extractor ex = scrfd.create_extractor();
ex.input("input.1", in_pad);
std::vector<FaceObject> faceobjects;
std::vector<FaceObject> faceproposals;
//std::vector<FaceObject>& faceobjects, float prob_threshold, float nms_threshold)
// stride 8
{
ncnn::Mat score_blob, bbox_blob, kps_blob;
ex.extract("score_8", score_blob);
ex.extract("bbox_8", bbox_blob);
if (has_kps)
ex.extract("kps_8", kps_blob);
const int base_size = 16;
const int feat_stride = 8;
ncnn::Mat ratios(1);
ratios[0] = 1.f;
ncnn::Mat scales(2);
scales[0] = 1.f;
scales[1] = 2.f;
ncnn::Mat anchors = generate_anchors(base_size, ratios, scales);
std::vector<FaceObject> faceobjects32;
generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects32);
faceproposals.insert(faceproposals.end(), faceobjects32.begin(), faceobjects32.end());
}
// stride 16
{
ncnn::Mat score_blob, bbox_blob, kps_blob;
ex.extract("score_16", score_blob);
ex.extract("bbox_16", bbox_blob);
if (has_kps)
ex.extract("kps_16", kps_blob);
const int base_size = 64;
const int feat_stride = 16;
ncnn::Mat ratios(1);
ratios[0] = 1.f;
ncnn::Mat scales(2);
scales[0] = 1.f;
scales[1] = 2.f;
ncnn::Mat anchors = generate_anchors(base_size, ratios, scales);
std::vector<FaceObject> faceobjects16;
generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects16);
faceproposals.insert(faceproposals.end(), faceobjects16.begin(), faceobjects16.end());
}
// stride 32
{
ncnn::Mat score_blob, bbox_blob, kps_blob;
ex.extract("score_32", score_blob);
ex.extract("bbox_32", bbox_blob);
if (has_kps)
ex.extract("kps_32", kps_blob);
const int base_size = 256;
const int feat_stride = 32;
ncnn::Mat ratios(1);
ratios[0] = 1.f;
ncnn::Mat scales(2);
scales[0] = 1.f;
scales[1] = 2.f;
ncnn::Mat anchors = generate_anchors(base_size, ratios, scales);
std::vector<FaceObject> faceobjects8;
generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects8);
faceproposals.insert(faceproposals.end(), faceobjects8.begin(), faceobjects8.end());
}
// sort all proposals by score from highest to lowest
qsort_descent_inplace(faceproposals);
// apply nms with nms_threshold
std::vector<int> picked;
nms_sorted_bboxes(faceproposals, picked, nms_threshold);
int face_count = picked.size();
printf("====face_count %d\n",face_count);
faceobjects.resize(face_count);
for (int i = 0; i < face_count; i++)
{
faceobjects[i] = faceproposals[picked[i]];
// adjust offset to original unpadded
float x0 = (faceobjects[i].rect.x - (wpad / 2)) / scale;
float y0 = (faceobjects[i].rect.y - (hpad / 2)) / scale;
float x1 = (faceobjects[i].rect.x + faceobjects[i].rect.width - (wpad / 2)) / scale;
float y1 = (faceobjects[i].rect.y + faceobjects[i].rect.height - (hpad / 2)) / scale;
x0 = std::max(std::min(x0, (float)m_width - 1), 0.f);
y0 = std::max(std::min(y0, (float)m_height - 1), 0.f);
x1 = std::max(std::min(x1, (float)m_width - 1), 0.f);
y1 = std::max(std::min(y1, (float)m_height - 1), 0.f);
faceobjects[i].rect.x = x0;
faceobjects[i].rect.y = y0;
faceobjects[i].rect.width = x1 - x0;
faceobjects[i].rect.height = y1 - y0;
if (has_kps)
{
float x0 = (faceobjects[i].landmark[0].x - (wpad / 2)) / scale;
float y0 = (faceobjects[i].landmark[0].y - (hpad / 2)) / scale;
float x1 = (faceobjects[i].landmark[1].x - (wpad / 2)) / scale;
float y1 = (faceobjects[i].landmark[1].y - (hpad / 2)) / scale;
float x2 = (faceobjects[i].landmark[2].x - (wpad / 2)) / scale;
float y2 = (faceobjects[i].landmark[2].y - (hpad / 2)) / scale;
float x3 = (faceobjects[i].landmark[3].x - (wpad / 2)) / scale;
float y3 = (faceobjects[i].landmark[3].y - (hpad / 2)) / scale;
float x4 = (faceobjects[i].landmark[4].x - (wpad / 2)) / scale;
float y4 = (faceobjects[i].landmark[4].y - (hpad / 2)) / scale;
faceobjects[i].landmark[0].x = std::max(std::min(x0, (float)m_width - 1), 0.f);
faceobjects[i].landmark[0].y = std::max(std::min(y0, (float)m_height - 1), 0.f);
faceobjects[i].landmark[1].x = std::max(std::min(x1, (float)m_width - 1), 0.f);
faceobjects[i].landmark[1].y = std::max(std::min(y1, (float)m_height - 1), 0.f);
faceobjects[i].landmark[2].x = std::max(std::min(x2, (float)m_width - 1), 0.f);
faceobjects[i].landmark[2].y = std::max(std::min(y2, (float)m_height - 1), 0.f);
faceobjects[i].landmark[3].x = std::max(std::min(x3, (float)m_width - 1), 0.f);
faceobjects[i].landmark[3].y = std::max(std::min(y3, (float)m_height - 1), 0.f);
faceobjects[i].landmark[4].x = std::max(std::min(x4, (float)m_width - 1), 0.f);
faceobjects[i].landmark[4].y = std::max(std::min(y4, (float)m_height - 1), 0.f);
}
break;
}
if(faceobjects.size()>0){
FaceObject fo = faceobjects[0];
cv::Rect_<float> rect = fo.rect;
//std::cout<<fo.rect<<std::endl;
int w = rect.width;
int h = rect.height;
int x1 = rect.x;
int y1 = rect.y;
int x2 = rect.x+w;
int y2 = rect.y+h;
printf("scrfd x1 %d y1 %d x2 %d y2 %d\n",x1,y1,x2,y2);
int* tag = boxs;//pic->tagarr();
int inx = 0;
tag[inx++] = w;
tag[inx++] = h;
tag[inx++] = x1;
tag[inx++] = y1;
tag[inx++] = x2;
tag[inx++] = y2;
float adj = w*0.1f;
x1 = x1 - adj;
if(x1<0)x1=0;
if(y1<0)y1=0;
adj = (x2-x1)*0.1f;
x2 = x2 + adj;
if(x2>=m_width)x2=m_width-1;
adj = (y2-y1)*0.1f;
y2 = y2 + adj;
if(y2>=m_height)y2=m_height-1;
tag[inx++] = x1;
tag[inx++] = y1;
tag[inx++] = x2;
tag[inx++] = y2;
printf("adj x1 %d y1 %d x2 %d y2 %d\n",x1,y1,x2,y2);
}
//cv::Mat drawmat(m_height,m_width,CV_8UC3,pic->udata());
//drawface(drawmat,faceobjects);
//cv::imshow("aaa",drawmat);
//cv::waitKey(0);
return 0;
}
void Scrfd::recal(int nw ,int nh){
if((nw==m_width)&&(nh==m_height))return;
m_width = nw;
m_height = nh;
int w = m_width;
int h = m_height;
scale = 1.f;
if (w > h) {
scale = (float)target_size / w;
w = target_size;
h = h * scale;
} else {
scale = (float)target_size / h;
h = target_size;
w = w * scale;
}
scale_h = h;
scale_w = w;
wpad = (w + 31) / 32 * 32 - w;
hpad = (h + 31) / 32 * 32 - h;
}
Scrfd::Scrfd(const char* modeldir,const char* modelid,int cols,int rows){
scrfd.clear();
ncnn::set_cpu_powersave(2);
ncnn::set_omp_num_threads(ncnn::get_big_cpu_count());
scrfd.opt = ncnn::Option();
//scrfd.opt.use_vulkan_compute = true;
scrfd.opt.num_threads = ncnn::get_big_cpu_count();
char filepath[1024];
sprintf(filepath,"%s/%s.param",modeldir,modelid);
scrfd.load_param(filepath);
sprintf(filepath,"%s/%s.bin",modeldir,modelid);
scrfd.load_model(filepath);
//scrfd.load_param("model/scrfd_500m_kps-opt2.param");
//scrfd.load_model("model/scrfd_500m_kps-opt2.bin");
//scrfd.load_param("model/scrfd.param");
//scrfd.load_model("model/scrfd.bin");
recal(cols,rows);
}
Scrfd::~Scrfd(){
}
#ifdef _SCRFD_MAIN_
int main(int argc,char** argv){
Scrfd* scrfd = new Scrfd(1080,1920);
std::string picfile("1.jpg");
JMat* pic = new JMat(picfile,1);
scrfd->detect(pic,pic->tagarr());
printf("precess to exit\n");
getchar();
return 0;
}
#endif

View File

@@ -1,38 +0,0 @@
#pragma once
#include "jmat.h"
#include "ncnn/ncnn/net.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <stdio.h>
#include <vector>
struct FaceObject
{
cv::Rect_<float> rect;
cv::Point2f landmark[5];
float prob;
};
class Scrfd{
private:
ncnn::Net scrfd;
int target_size = 640;
float prob_threshold = 0.3f;
float nms_threshold = 0.45f;
float mean_vals[3] = {127.5f, 127.5f, 127.5f};
float norm_vals[3] = {1 / 128.f, 1 / 128.f, 1 / 128.f};
float scale;
int scale_w;
int scale_h;
int wpad;
int hpad;
int m_width;
int m_height;
void recal(int nw ,int nh);
public:
int detect(JMat* pic,int* boxs);
Scrfd(const char* modeldir,const char* modelid,int cols,int rows);
~Scrfd();
};

View File

@@ -1,97 +0,0 @@
#include "wavcache.h"
#include "aicommon.h"
JMat* MBufCache::secBuf(int sec){
JMat* mat = NULL;
m_lock->lock();
if(sec<vec_buf.size()){
mat = vec_buf[sec];
}else{
mat = new JMat(m_secw,m_sech+1,1);
vec_buf.push_back(mat);
}
m_lock->unlock();
return mat;
}
void MBufCache::debug(){
}
JMat* MBufCache::inxBuf(int inx){
int seca = inx/m_sech;
int secb = inx%m_sech;
JMat* mat = NULL;
if(secb>=m_lineh){
mat= new JMat(m_secw,m_blockh,1);
JMat* sa = secBuf(seca);
int la = m_sech-secb;
int parta = la*m_secw;
float* pa = mat->fdata();
memcpy(pa,sa->frow(secb),parta*sizeof(float));
JMat* sb = secBuf(seca+1);
int lb = m_blockh - la;
float* pb = pa+parta;
int partb = lb*m_secw;
memcpy(pb,sa->frow(0),partb*sizeof(float));
}else{
JMat* src = secBuf(seca);
float* buf = src->frow(secb);
//printf("==dist %d\n",(buf-src->fdata())*4);
mat = new JMat(m_secw,m_blockh,buf,1);
//printf("==size %d %d = %d\n",m_secw,m_blockh,m_secw*m_blockh*4);
}
return mat;
}
int* MBufCache::tagarr(){
return m_tagarr;
}
MBufCache::MBufCache(int initsec,int secw,int sech,int blockh){
m_lock = new std::mutex();
m_secw = secw;
m_sech = sech;
m_blockh = blockh;
m_lineh = sech-blockh;
for(int k=0;k<initsec;k++){
JMat* mat = new JMat(m_secw,m_sech+1,1);
vec_buf.push_back(mat);
}
memset(m_tagarr,0,512*sizeof(int));
}
MBufCache::~MBufCache(){
m_lock->lock();
for(int k=0;k<vec_buf.size();k++){
JMat* mat = vec_buf[k];
delete mat;
}
vec_buf.clear();
m_lock->unlock();
delete m_lock;
}
#include "aicommon.h"
MBnfCache::MBnfCache():MBufCache(3,MFCC_BNFCHUNK,MFCC_BNFBASE,20){
}
MBnfCache::~MBnfCache(){
}
#ifdef _WAVTEST_
int main(int argc,char** argv){
MBnfCache cache;
for(int k=0;k<100;k++){
JMat* mat = cache.secBuf(k);
}
for(int k=816;k<817;k++){
printf("#%d# \n",k);
JMat* mat = cache.inxBuf(k);
JMat cm = mat->clone();
delete mat;
}
return 0;
}
#endif

View File

@@ -1,28 +0,0 @@
#pragma once
#include "jmat.h"
#include <vector>
#include <mutex>
class MBufCache{
protected:
int m_lineh;
int m_secw;
int m_sech;
int m_blockh;
std::mutex *m_lock;
std::vector<JMat*> vec_buf ;
int m_tagarr[512];
public:
JMat* secBuf(int sec);
JMat* inxBuf(int inx);
int* tagarr();
MBufCache(int initsec,int secw,int sech,int blockh);
virtual ~MBufCache();
void debug();
};
class MBnfCache:public MBufCache{
public:
MBnfCache();
virtual ~MBnfCache();
};

View File

@@ -1,209 +0,0 @@
#include "wavreader.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define TAG(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
struct wav_reader {
FILE *wav;
long data_pos;
uint32_t data_length;
uint32_t data_left;
int format;
int sample_rate;
int bits_per_sample;
int channels;
int byte_rate;
int block_align;
int streamed;
};
static uint32_t read_tag(struct wav_reader* wr) {
uint32_t tag = 0;
char c1 = fgetc(wr->wav);
char c2 = fgetc(wr->wav);
char c3 = fgetc(wr->wav);
char c4 = fgetc(wr->wav);
tag = (tag << 8) | c1;
tag = (tag << 8) | c2;
tag = (tag << 8) | c3;
tag = (tag << 8) | c4;
printf("===tag %c %c %c %c\n",c1,c2,c3,c4);
return tag;
}
static uint32_t read_int32(struct wav_reader* wr) {
uint32_t value = 0;
value |= fgetc(wr->wav) << 0;
value |= fgetc(wr->wav) << 8;
value |= fgetc(wr->wav) << 16;
value |= fgetc(wr->wav) << 24;
return value;
}
static uint16_t read_int16(struct wav_reader* wr) {
uint16_t value = 0;
value |= fgetc(wr->wav) << 0;
value |= fgetc(wr->wav) << 8;
return value;
}
static void skip(FILE *f, int n) {
int i;
for (i = 0; i < n; i++)
fgetc(f);
}
void* wav_read_open(const char *filename) {
struct wav_reader* wr = (struct wav_reader*) malloc(sizeof(*wr));
memset(wr, 0, sizeof(*wr));
if (!strcmp(filename, "-"))
wr->wav = stdin;
else
wr->wav = fopen(filename, "rb");
if (wr->wav == NULL) {
free(wr);
return NULL;
}
while (1) {
uint32_t tag, tag2, length;
tag = read_tag(wr);
if (feof(wr->wav))
break;
length = read_int32(wr);
if (!length || length >= 0x7fff0000) {
wr->streamed = 1;
length = ~0;
}
if (tag != TAG('R', 'I', 'F', 'F') || length < 4) {
fseek(wr->wav, length, SEEK_CUR);
continue;
}
tag2 = read_tag(wr);
length -= 4;
if (tag2 != TAG('W', 'A', 'V', 'E')) {
fseek(wr->wav, length, SEEK_CUR);
continue;
}
// RIFF chunk found, iterate through it
while (length >= 8) {
uint32_t subtag, sublength;
subtag = read_tag(wr);
//char* fff = (char*)&subtag;
if (feof(wr->wav))
break;
sublength = read_int32(wr);
printf("==== subleng %d\n",sublength );
length -= 8;
if (length < sublength)
break;
if (subtag == TAG('f', 'm', 't', ' ')) {
if (sublength < 16) {
// Insufficient data for 'fmt '
break;
}
wr->format = read_int16(wr);
wr->channels = read_int16(wr);
wr->sample_rate = read_int32(wr);
wr->byte_rate = read_int32(wr);
wr->block_align = read_int16(wr);
wr->bits_per_sample = read_int16(wr);
if (wr->format == 0xfffe) {
if (sublength < 28) {
// Insufficient data for waveformatex
break;
}
skip(wr->wav, 8);
wr->format = read_int32(wr);
skip(wr->wav, sublength - 28);
}
else {
skip(wr->wav, sublength - 16);
}
}
else if (subtag == TAG('d', 'a', 't', 'a')) {
wr->data_pos = ftell(wr->wav);
wr->data_length = sublength;
printf("==== data subleng %d\n",sublength );
wr->data_left = wr->data_length;
if (!wr->data_length || wr->streamed) {
wr->streamed = 1;
return wr;
}
fseek(wr->wav, sublength, SEEK_CUR);
}
else {
skip(wr->wav, sublength);
}
length -= sublength;
}
if (length > 0) {
// Bad chunk?
fseek(wr->wav, length, SEEK_CUR);
}
}
fseek(wr->wav, wr->data_pos, SEEK_SET);
return wr;
}
void wav_read_close(void* obj) {
struct wav_reader* wr = (struct wav_reader*) obj;
if (wr->wav != stdin)
fclose(wr->wav);
free(wr);
}
int wav_get_header(void* obj, int* format, int* channels, int* sample_rate, int* bits_per_sample, unsigned int* data_length) {
struct wav_reader* wr = (struct wav_reader*) obj;
if (format)
*format = wr->format;
if (channels)
*channels = wr->channels;
if (sample_rate)
*sample_rate = wr->sample_rate;
if (bits_per_sample)
*bits_per_sample = wr->bits_per_sample;
printf("==== data subleng %d\n",wr->data_length );
if (data_length)
*data_length = wr->data_length;
return wr->format && wr->sample_rate;
}
int wav_read_data(void* obj, unsigned char* data, unsigned int length) {
struct wav_reader* wr = (struct wav_reader*) obj;
int n;
if (wr->wav == NULL)
return -1;
if (length > wr->data_left && !wr->streamed) {
int loop = 1;
if (loop) {
fseek(wr->wav, wr->data_pos, SEEK_SET);
wr->data_left = wr->data_length;
}
length = wr->data_left;
}
n = fread(data, 1, length, wr->wav);
wr->data_left -= length;
return n;
}
/*
int main(int argc,char** argv){
void* hnd = wav_read_open("../../mybin/errnv.wav");
int format;
int channels;
int sample_rate;
int bits_per_sample;
unsigned int data_length;
int rst = wav_get_header(hnd, &format, &channels, &sample_rate, &bits_per_sample, &data_length);
printf("===format %d channels %d sample_rate %d,bit %d,len %lu\n",format, channels, sample_rate, bits_per_sample, data_length);
return 0;
}
*/

View File

@@ -1,37 +0,0 @@
/* ------------------------------------------------------------------
* Copyright (C) 2009 Martin Storsjo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
#ifndef WAVREADER_H_
#define WAVREADER_H_
#ifdef __cplusplus
extern "C" {
#endif
void* wav_read_open(const char *filename);
void wav_read_close(void* obj);
int wav_get_header(void* obj, int* format, int* channels, int* sample_rate, int* bits_per_sample, unsigned int* data_length);
int wav_read_data(void* obj, unsigned char* data, unsigned int length);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,203 +0,0 @@
#include "wenet.h"
#include <stdio.h>
#include <memory>
#include <vector>
#include "wavreader.h"
#include "face_utils.h"
#include "mfcc/mfcc.hpp"
#include "jlog.h"
#include "aicommon.h"
void Wenet::initModel(const char* modelfn){
m_model = new OnnxModel();
string modelpath(modelfn);
m_model->initModel(modelpath);
//m_model->pushName("speech",1);
//m_model->pushName("speech_lengths",1);
//m_model->pushName("encoder_out",0);
}
int Wenet::calcbnf(float* melbin,int melnum,float* bnfbin,int bnfnum){
int rst = 0;
int chkmfcc = melnum;
int chkbnf = bnfnum;
auto onecfg = m_model->config();
auto cfg = &onecfg;
//cfg->dump();
cfg->shape_inputs[0][0] = 1;
cfg->shape_inputs[0][1] = chkmfcc;
cfg->size_inputs[0] = chkmfcc*MFCC_MELCHUNK;
cfg->shape_inputs[1][0] = 1;
cfg->size_inputs[1] = 1;
cfg->shape_outputs[0][0] = 1;
cfg->shape_outputs[0][1] = chkbnf;
cfg->shape_outputs[0][2] = MFCC_BNFCHUNK;
cfg->size_outputs[0] = chkbnf*MFCC_BNFCHUNK;
cfg->dump();
void* arrin[] = { melbin,&chkmfcc,NULL };
void* arrout[] = { bnfbin,NULL };
const char* namein[] = {"speech","speech_lengths",NULL};
const char* nameout[] = {"encoder_out",NULL};
cfg->names_in = namein;
cfg->names_out = nameout;
rst = m_model->runModel(arrin,arrout,NULL,cfg);
return rst;
}
Wenet::Wenet(const char* modeldir,const char* modelid){
char path[1024];
sprintf(path,"%s/%s.onnx",modeldir,modelid);
initModel((const char*)path);
}
Wenet::Wenet(const char* modelfn){
initModel(modelfn);
}
Wenet::~Wenet(){
delete m_model;
}
//int Wenet::nextwav(const char* wavfile,JMat** pmat){
int Wenet::nextwav(const char* wavfile,MBnfCache* bnfcache,float duration){
int m_pcmsample = 0;
JBuf *m_pcmbuf = nullptr;
JMat *m_wavmat = nullptr;
JMat *m_melmat = nullptr;
//JMat *m_bnfmat = nullptr;
int format, channels, sr, bits_per_sample;
unsigned int data_length;
void* fhnd = wav_read_open(wavfile);
if(!fhnd)return -1;
int res = wav_get_header(fhnd, &format, &channels, &sr, &bits_per_sample, &data_length);
if(duration>0)
{
data_length=duration*(channels *bits_per_sample*sr/8);
}
if(data_length<1) {
wav_read_close(fhnd);
return -2;
}
LOGD("data len %d\n",data_length);
m_pcmbuf = new JBuf(data_length);
int rst = wav_read_data(fhnd,(unsigned char*)m_pcmbuf->data(),data_length);
wav_read_close(fhnd);
int wavsample = data_length/2;
m_pcmsample = wavsample + 2*MFCC_OFFSET;
int seca = m_pcmsample / MFCC_WAVCHUNK;
int secb = m_pcmsample % MFCC_WAVCHUNK;
if(secb>0){
//m_pcmsample = wavsample + 2*MFCC_OFFSET + MFCC_WAVCHUNK - secb;
//seca++;
}
int mellast = secb?(secb /160 +1):0;
int bnflast = secb?((mellast*0.25f)-0.75f):0;
int wavsize = seca*MFCC_WAVCHUNK + secb;
int melsize = seca*MFCC_MELBASE+mellast;
int bnfsize = seca*MFCC_BNFBASE+bnflast;
//printf("===seca %d \n",seca);
//getchar();
//printf("===wavsample %d \n",wavsample);
int calcsize = seca+1;
m_wavmat = new JMat(MFCC_WAVCHUNK,calcsize,1);
m_wavmat->zeros();
short* ps = (short*)m_pcmbuf->data();
float* pd = (float*)m_wavmat->data();
float* pf = pd+MFCC_OFFSET;
for(int k=0;k<wavsample;k++){
*pf++ = (float)(*ps++/ 32767.f);
}
m_melmat = new JMat(MFCC_MELCHUNK,MFCC_MELBASE*calcsize,1);
m_melmat->zeros();
//m_bnfmat = new JMat(MFCC_BNFCHUNK,MFCC_BNFBASE*calcsize,1);
//m_bnfmat->zeros();
//
//printf("===seca %d secb %d mellast %d\n",seca,secb,mellast);
//getchar();
//m_bnfmat = new JMat(
calcmfcc(m_wavmat,m_melmat);
float* mel = m_melmat->fdata();
for(int k=0;k<seca;k++){
float* bnf = bnfcache->secBuf(k)->fdata();
calcbnf(mel,MFCC_MELBASE,bnf,MFCC_BNFBASE);
//dumpfloat(bnf,10);
mel+=MFCC_MELBASE*MFCC_MELCHUNK;
//bnf+=MFCC_BNFBASE*MFCC_BNFCHUNK;
}
if(mellast){
int inxsec = seca?(seca+1):0;
float* bnf = bnfcache->secBuf(inxsec)->fdata();
calcbnf(mel,mellast,bnf,bnflast);
//dumpfloat(bnf,10);
//calcbnf(mel,MFCC_MELBASE,bnf,MFCC_BNFBASE);
}
int* arr = bnfcache->tagarr();
//
arr[0] = wavsize;
arr[1] = m_pcmsample;
arr[2] = seca;
arr[3] = secb;
float secs = wavsample *1.0f/ MFCC_RATE;
int bnfblock = secs*MFCC_FPS;
if(bnfblock>(bnfsize-10))bnfblock = bnfsize-10;
arr[4] = melsize;
arr[5] = bnfsize;
arr[6] = bnfblock;
/*
for(int k=0;k<10;k++){
float* bnf = m_bnfmat->frow(k);
printf("==%d =bnf %f\n",k,*bnf);
}
*/
//*pmat = m_bnfmat;
delete m_pcmbuf;
delete m_wavmat;
delete m_melmat ;
return bnfblock;
}
float* Wenet::nextbnf(JMat* bnfmat,int index){
int* arr = bnfmat->tagarr();
int bnfsize = arr[5] ;
int bnfblock = arr[6] ;
LOGD("===index %d bnfsize %d bnfblock %d\n",index,bnfsize,bnfblock);
if(bnfblock>bnfsize)return NULL;
if(index>=bnfblock)return NULL;
float* buf = bnfmat->fdata();
buf += index*MFCC_BNFCHUNK+MFCC_BNFCHUNK;
return buf;
}
int Wenet::calcmfcc(float* fwav,float* mel2){
int rst = 0;
int melcnt = MFCC_WAVCHUNK/160+1;
rst = log_mel(fwav,MFCC_WAVCHUNK, 16000,mel2);
return rst;
}
int Wenet::calcmfcc(JMat* mwav,JMat* mmel){
int rst = 0;
int melcnt = MFCC_WAVCHUNK/160+1;
for(size_t k=0;k<mwav->height();k++){
float* fwav = mwav->frow(k);
float* mel2 = mmel->frow(k);
rst = log_mel(fwav,MFCC_WAVCHUNK, 16000,mel2);
}
return rst;
}
#ifdef WENET_MAIN
int main(int argc,char** argv){
Wenet net("../model","wenet");
net->nextwav("../mybin/a.wav");
return 0;
}
#endif

View File

@@ -1,22 +0,0 @@
#pragma once
#include "jmat.h"
#include "aimodel.h"
#include <vector>
#include "wavcache.h"
//#include <onnx/onnxruntime_cxx_api.h>
class Wenet{
private:
OnnxModel *m_model = nullptr;
void initModel(const char* modelfn);
public:
int calcmfcc(JMat* mwav,JMat* mmel);
int calcmfcc(float* fwav,float* mel2);
int calcbnf(float* melbin,int melnum,float* bnfbin,int bnfnum);
//int nextwav(const char* wavfile,JMat** pmat);
int nextwav(const char* wavfile,MBnfCache* bnfcache,float duration);
float* nextbnf(JMat* bnfmat,int index);
Wenet(const char* modeldir,const char* modelid);
Wenet(const char* modelfn);
~Wenet();
};

View File

@@ -1,343 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <memory>
#include <vector>
#include <string.h>
#include <mutex>
//#include "NumCpp.hpp"
#include "gjdigit.h"
#include "jmat.h"
#include "wenet.h"
#include "munet.h"
#include "malpha.h"
#include "blendgram.h"
#include "wavcache.h"
//#include "aesmain.h"
#include "netwav.h"
struct gjdigit_s{
Wenet *ai_wenet;
Mobunet *ai_munet;
MAlpha *ai_malpha;
//JMat *mat_wenet;
std::mutex *lock_munet;
std::mutex *lock_wenet;
MBnfCache *bnf_cache;
int cnt_wenet;
int inx_wenet;
JMat* mat_gpg;
};
int gjdigit_alloc(gjdigit_t** pdg){
gjdigit_t* dg = (gjdigit_t*)malloc(sizeof(gjdigit_t));
memset(dg,0,sizeof(gjdigit_t));
dg->lock_munet = new std::mutex();
dg->lock_wenet = new std::mutex();
dg->bnf_cache = new MBnfCache();
*pdg = dg;
return 0;
}
int gjdigit_initWenet(gjdigit_t* dg,char* fnwenet){
dg->lock_wenet->lock();
if(dg->ai_wenet){
delete dg->ai_wenet;
dg->ai_wenet = NULL;
}
dg->ai_wenet = new Wenet(fnwenet);
dg->lock_wenet->unlock();
return 0;
}
int gjdigit_initMalpha(gjdigit_t* dg,char* fnparam,char* fnbin){
if(1)return 0;
if(dg->ai_malpha){
delete dg->ai_malpha;
dg->ai_malpha = NULL;
}
std::string fb(fnbin);
std::string fp(fnparam);
dg->ai_malpha = new MAlpha(fb.c_str(),fp.c_str());
return 0;
}
int gjdigit_initMunet(gjdigit_t* dg,char* fnparam,char* fnbin,char* fnmsk){
dg->lock_munet->lock();
if(dg->ai_munet){
delete dg->ai_munet;
dg->ai_munet = NULL;
}
dg->ai_munet = new Mobunet(fnbin,fnparam,fnmsk);
dg->lock_munet->unlock();
return 0;
}
static int calcinx(gjdigit_t* dg, KWav* wavmat,int index){
float* pwav = NULL;
float* pmfcc = NULL;
float* pbnf = NULL;
int melcnt = 0;
int bnfcnt = 0;
int rst = wavmat->calcbuf(index, &pwav,&pmfcc,&pbnf,&melcnt,&bnfcnt);
//LOGE(TAG,"===tooken calcinx %d index %d \n",index,rst);
if(rst == index){
dg->ai_wenet->calcmfcc(pwav,pmfcc);
//double t0 = ncnn::get_current_time();
dg->ai_wenet->calcbnf(pmfcc,melcnt,pbnf,bnfcnt);
//double t1 = ncnn::get_current_time();
//float dist = t1-t0;
//dumpfloat(pbnf,10);
wavmat->finishone(index);
}
return 0;
}
static int calcall(gjdigit_t* dg, KWav* wavmat){
int rst =wavmat->readyall();
int cnt = 0;
while(cnt<1000){
rst = wavmat->isready();
if(!rst)break;
calcinx(dg,wavmat,rst);
}
return 0;
}
int gjdigit_onewav(gjdigit_t* dg,const char* wavfn,float duration){
if(!dg->ai_wenet)return -999;
/*
if(dg->mat_wenet){
delete dg->mat_wenet;
dg->mat_wenet = NULL;
}
*/
int rst = 0;
KWav* net_wavmat = new KWav(wavfn,dg->bnf_cache,duration);
if(net_wavmat->duration()>0){
calcall(dg,net_wavmat); //
rst = net_wavmat->bnfblocks();//net_curl->checked();
dg->cnt_wenet = rst;
dg->inx_wenet = 0;
}else{
rst = dg->ai_wenet->nextwav(wavfn,dg->bnf_cache,duration);
dg->bnf_cache->debug();
dg->cnt_wenet = rst;
dg->inx_wenet = 0;
}
delete net_wavmat;
return rst;
}
int gjdigit_picrst(gjdigit_t* dg,const char* picfn,int* box,int index){
if(!dg->ai_munet)return -999;
//if(!dg->mat_wenet)return -1;
if(index<0)return -2;
if(index>=dg->cnt_wenet)return -3;
/*
float* pwenet = dg->ai_wenet->nextbnf(dg->mat_wenet,index);
if(!pwenet){
return -11;
}
//JMat feat(256, 20, pwenet, 1);
*/
JMat* feat = dg->bnf_cache->inxBuf(index);
std::string picfile(picfn);
JMat* mat_pic = new JMat(picfile,1);
int* arr = mat_pic->tagarr();
arr[10] = box[0];
arr[11] = box[1];
arr[12] = box[2];
arr[13] = box[3];
dg->ai_munet->process(mat_pic, arr, feat);
delete mat_pic;
return 0;
}
int gjdigit_matrst(gjdigit_t* dg,uint8_t* buf,int width,int height,int* box,int index){
if(!dg->ai_munet)return -999;
//if(!dg->mat_wenet)return -1;
if(index<0)return -2;
if(index>=dg->cnt_wenet)return -3;
/*
float* pwenet = dg->ai_wenet->nextbnf(dg->mat_wenet,index);
if(!pwenet){
return -11;
}
JMat feat(256, 20, pwenet, 1);
*/
JMat* feat = dg->bnf_cache->inxBuf(index);
JMat* mat_pic = new JMat(width,height,buf);
/*
int* arr = mat_pic->tagarr();
arr[10] = box[0];
arr[11] = box[1];
arr[12] = box[2];
arr[13] = box[3];
*/
dg->lock_munet->lock();
dg->ai_munet->process(mat_pic, box, feat);
dg->lock_munet->unlock();
delete mat_pic;
delete feat;
return 0;
}
int gjdigit_simprst(gjdigit_t* dg,uint8_t* bpic,int width,int height,int* box,int index){
if(!dg->ai_munet)return -999;
//if(!dg->mat_wenet)return -1;
if(index<0)return -2;
if(index>=dg->cnt_wenet)return -3;
dg->bnf_cache->debug();
JMat* feat = dg->bnf_cache->inxBuf(index);
dg->bnf_cache->debug();
//JMat* feat = dg->bnf_cache->inxBuf(0);
JMat* mat_pic = new JMat(width,height,bpic);
MWorkMat wmat(mat_pic,NULL,box);
wmat.premunet();
JMat* mpic;
JMat* mmsk;
wmat.munet(&mpic,&mmsk);
dg->lock_munet->lock();
dg->ai_munet->domodel(mpic, mmsk, feat);
dg->lock_munet->unlock();
wmat.finmunet(mat_pic);
delete mat_pic;
delete feat;
return 0;
}
int gjdigit_maskrst(gjdigit_t* dg,uint8_t* bpic,int width,int height,int* box,uint8_t* bmsk,uint8_t* bfg,uint8_t* bbg,int index){
if(!dg->ai_munet)return -999;
//if(!dg->mat_wenet)return -1;
if(index<0)return -2;
if(index>=dg->cnt_wenet)return -3;
/*
float* pwenet = dg->ai_wenet->nextbnf(dg->mat_wenet,index);
if(!pwenet){
return -11;
}
JMat feat(256, 20, pwenet, 1);
*/
dg->bnf_cache->debug();
JMat* feat = dg->bnf_cache->inxBuf(index);
dg->bnf_cache->debug();
//JMat* feat = dg->bnf_cache->inxBuf(0);
JMat* mat_pic = new JMat(width,height,bpic);
JMat* mat_msk = new JMat(width,height,bmsk);
JMat* mat_fg = new JMat(width,height,bfg);
//int* arr = mat_pic->tagarr();
//arr[10] = box[0];
//arr[11] = box[1];
//arr[12] = box[2];
//arr[13] = box[3];
MWorkMat wmat(mat_pic,mat_msk,box);
wmat.premunet();
JMat* mpic;
JMat* mmsk;
wmat.munet(&mpic,&mmsk);
//JMat realb("real_B.bmp",1);
//JMat maskb("mask_B.bmp",1);
dg->lock_munet->lock();
dg->ai_munet->domodel(mpic, mmsk, feat);
dg->lock_munet->unlock();
//dg->ai_munet->domodel(&realb, &maskb, &feat);
wmat.finmunet(mat_fg);
//printf("===aaa\n");
//mat_fg->show("aaa");
//printf("===bfg %p mat %p\n",bfg,mat_fg->data());
//cv::waitKey(0);
/*
wmat.prealpha();
JMat* mreal;
JMat* mimg;
JMat* mpha;
wmat.alpha(&mreal,&mimg,&mpha);
dg->ai_malpha->doModel(mreal,mimg,mpha);
wmat.finalpha();
*/
//mat_msk->show("msk");
//mat_pic->show("picaaa");
if(bbg) BlendGramAlpha3(bbg,bmsk,bfg,width,height);
//mat_pic->show("picbbb");
//cv::waitKey(0);
delete mat_pic;
delete mat_msk;
delete mat_fg;
delete feat;
return 0;
}
int gjdigit_free(gjdigit_t** pdg){
if(!pdg)return -1;
gjdigit_t* dg = *pdg;
if(dg->lock_munet){
dg->lock_munet->lock();
dg->lock_munet->unlock();
delete dg->lock_munet;
}
if(dg->ai_wenet){
delete dg->ai_wenet;
dg->ai_wenet = NULL;
}
if(dg->ai_munet){
delete dg->ai_munet;
dg->ai_munet = NULL;
}
if(dg->bnf_cache){
delete dg->bnf_cache;
dg->bnf_cache = NULL;
}
if(dg->lock_wenet){
delete dg->lock_wenet;
dg->lock_wenet = NULL;
}
if(dg->mat_gpg){
delete dg->mat_gpg;
dg->mat_gpg = NULL;
}
free(dg);
*pdg = NULL;
return 0;
}
int gjdigit_test(gjdigit_t* dg){
dg->cnt_wenet = 10;
dg->inx_wenet = 0;
return 2;
}
//int gjdigit_processmd5(gjdigit_t* dg,int enc,const char* infn,const char* outfn){
// //
// std::string s_in(infn);
// std::string s_out(outfn);
// int rst = mainenc(enc,(char*)s_in.c_str(),(char*)s_out.c_str());
// return rst;
//}
int gjdigit_startgpg(gjdigit_t* dg,const char* infn,const char* outfn){
std::string s_in(infn);
std::string s_out(outfn);
if(!dg->mat_gpg)dg->mat_gpg = new JMat();
int rst = dg->mat_gpg->loadjpg(s_in);
if(rst)return rst;
rst = dg->mat_gpg->savegpg(s_out);
return rst;
}
int gjdigit_stopgpg(gjdigit_t* dg){
if(dg->mat_gpg){
delete dg->mat_gpg;
dg->mat_gpg = NULL;
}
return 0;
}

View File

@@ -1,40 +0,0 @@
#ifndef GJDIGIT
#define GJDIGIT
#ifdef __cplusplus
extern "C"{
#endif
typedef struct gjdigit_s gjdigit_t;
int gjdigit_alloc(gjdigit_t** pdg);
int gjdigit_initWenet(gjdigit_t* dg,char* fnwenet);
int gjdigit_initMunet(gjdigit_t* dg,char* fnparam,char* fnbin,char* fnmsk);
int gjdigit_initMalpha(gjdigit_t* dg,char* fnparam,char* fnbin);
int gjdigit_onewav(gjdigit_t* dg,const char* wavfn,float duration);
//int gjdigit_picrst(gjdigit_t* dg,const char* picfn,int* box,int index);
int gjdigit_matrst(gjdigit_t* dg,uint8_t* buf,int width,int height,int* box,int index);
int gjdigit_maskrst(gjdigit_t* dg,uint8_t* bpic,int width,int height,int* box,uint8_t* bmsk,uint8_t* bfg,uint8_t* bbg,int index);
int gjdigit_simprst(gjdigit_t* dg,uint8_t* bpic,int width,int height,int* box,int index);
//int gjdigit_processmd5(gjdigit_t* dg,int enc,const char* infn,const char* outfn);
int gjdigit_startgpg(gjdigit_t* dg,const char* infn,const char* outfn);
int gjdigit_stop(gjdigit_t* dg);
int gjdigit_free(gjdigit_t** pdg);
int gjdigit_test(gjdigit_t* dg);
#ifdef __cplusplus
}
#endif
#endif