// // Created by xinyang on 19-4-19. // // 对本文件的大致描述请看classifier.h //#define LOG_LEVEL LOG_NONE #include #include #include #include vector> Classifier::load_conv_w(const string &file){ vector> result; FILE *fp = fopen(file.data(), "r"); if(fp == nullptr){ LOGE("%s open fail!", file.data()); state = false; return result; } int channel_in, channel_out, row, col; fscanf(fp, "%d %d %d %d", &channel_in, &channel_out, &row, &col); for(int o=0; o sub; for(int i=0; i Classifier::load_conv_b(const string &file){ vector result; FILE *fp = fopen(file.data(), "r"); if(fp == nullptr){ LOGE("%s open fail!", file.data()); state = false; return result; } int len; fscanf(fp, "%d", &len); for(int i=0; i> Classifier::max_pool(const vector> &input, int size){ vector> output; for(int sample=0; sample sub; for (int channel = 0; channel < input[0].size(); channel++) { MatrixXd tmp(input[0][0].rows() / size, input[0][0].cols() / size); for (int row = 0; row < input[0][0].rows() / size; row++) { for (int col = 0; col < input[0][0].cols() / size; col++) { double max = 0; for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { if(max < input[sample][channel](row * size + x, col * size + y)){ max = input[sample][channel](row * size + x, col * size + y); } } } tmp(row, col) = max; } } sub.emplace_back(tmp); } output.emplace_back(sub); } return output; } vector> Classifier::mean_pool(const vector> &input, int size){ vector> output; for(int sample=0; sample sub; for (int channel = 0; channel < input[0].size(); channel++) { MatrixXd tmp(input[0][0].rows() / size, input[0][0].cols() / size); for (int row = 0; row < input[0][0].rows() / size; row++) { for (int col = 0; col < input[0][0].cols() / size; col++) { double val = 0; for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { val += input[sample][channel](row * size + x, col * size + y); } } tmp(row, col) = val / size / size; } } sub.emplace_back(tmp); } output.emplace_back(sub); } return output; } vector> Classifier::apply_bias(const vector> &input, const vector &bias){ assert(input[0].size()==bias.size()); vector> result; for(int samples=0; samples sub; for(int channels=0; channels0)?(val):(0); }); } MatrixXd Classifier::leaky_relu(const MatrixXd &input, float alpha){ return input.unaryExpr([&](double val){ return (val>0)?(val):(alpha*val); }); } vector> Classifier::relu(const vector> &input){ vector> result; for(int samples=0; samples sub; for(int channels=0; channels> Classifier::leaky_relu(const vector> &input, float alpha){ vector> result; for(int samples=0; samples sub; for(int channels=0; channels> Classifier::pand(const vector> &input, int val){ vector> result; for(int sample=0; sample sub; for(int channels=0; channels> Classifier::conv2(const vector> &filter, const vector> &input){ if(filter.size() != input[0].size()){ LOGE("shape du not match, which is filter.size=%d, input[0].size()=%d", filter.size(), input[0].size()); exit(-1); } vector> result; int result_rows = input[0][0].rows()-filter[0][0].rows()+1; int result_cols = input[0][0].cols()-filter[0][0].cols()+1; for(int col=0; col sub; for(int row=0; row> &input){ int ones = input[0][0].rows()*input[0][0].cols(); int channels = input[0].size(); int samples = input.size(); int row = input[0][0].rows(); int col = input[0][0].cols(); MatrixXd output(channels*ones,samples); for(int s=0; s> &input) { vector> conv1_result = relu(apply_bias(conv2(conv1_w, input), conv1_b)); vector> pool1_result = mean_pool(conv1_result, 2); vector> conv2_result = relu(apply_bias(conv2(conv2_w, pool1_result), conv2_b)); vector> pool2_result = mean_pool(conv2_result, 2); vector> conv3_result = relu(apply_bias(conv2(conv3_w, pool2_result), conv3_b)); MatrixXd flattened = flatten(conv3_result); MatrixXd y1 = fc1_w * flattened; y1.colwise() += fc1_b; MatrixXd fc1 = relu(y1); MatrixXd y2 = fc2_w * fc1; y2.colwise() += fc2_b; MatrixXd fc2 = softmax(y2); return fc2; } Classifier::operator bool() const { return state; } int Classifier::operator()(const cv::Mat &image) { MatrixXd r, g, b; std::vector channels; cv::split(image, channels); cv2eigen(channels[0], b); cv2eigen(channels[1], g); cv2eigen(channels[2], r); r /= 255; g /= 255; b /= 255; vector sub = {b, g, r}; vector> in = {sub}; MatrixXd result = calculate(in); MatrixXd::Index minRow, minCol; result.maxCoeff(&minRow, &minCol); if(result(minRow, minCol) > 0.50){ return minRow; }else{ return 0; } }