face aligned github
该博客是转化这个里面的matlab程序为c++程序:
转换这个时候感觉遇到一个坑(不知道作者是不是故意这样的),传进去的图片要进行翻转,因为作者在写matlab的时候没有进行翻转就直接放进Blob中,直接导致图片有一个翻转,所以我在c++程序也进行了一个翻转。
现在只完成到第二个网络,后续再更新(已经更新,作者很懒,懒得把其中重复很多的代码写成函数,因此看起来冗余代码很多)。
#include "caffe/net.hpp"
#include <vector>
#include <string>
#include <fstream>
#include <opencv2/opencv.hpp>
void loaddata(boost::shared_ptr<caffe::Net<float> >& net, cv::Mat image);
void loaddata(boost::shared_ptr<caffe::Net<float> >& net, cv::Mat image, int batch_idx);
float maxf(float x1, float x2);
float minf(float x1, float x2);
int main(int argc, char** argv){
std::string net_path1("/home/yang/MTCNN_face_detection_alignment/code/codes/MTCNNv1/model/det1.prototxt");
std::string net_path2("/home/yang/MTCNN_face_detection_alignment/code/codes/MTCNNv1/model/det2.prototxt");
std::string net_path3("/home/yang/MTCNN_face_detection_alignment/code/codes/MTCNNv1/model/det3.prototxt");
std::string w_path1("/home/yang/MTCNN_face_detection_alignment/code/codes/MTCNNv1/model/det1.caffemodel");
std::string w_path2("/home/yang/MTCNN_face_detection_alignment/code/codes/MTCNNv1/model/det2.caffemodel");
std::string w_path3("/home/yang/MTCNN_face_detection_alignment/code/codes/MTCNNv1/model/det3.caffemodel");
caffe::Caffe::set_mode(caffe::Caffe::GPU);
boost::shared_ptr<caffe::Net<float> > net1(new caffe::Net<float>(net_path1, caffe::TEST));
boost::shared_ptr<caffe::Net<float> > net2(new caffe::Net<float>(net_path2, caffe::TEST));
boost::shared_ptr<caffe::Net<float> > net3(new caffe::Net<float>(net_path3, caffe::TEST));
net1->CopyTrainedLayersFromBinaryProto(w_path1);
net2->CopyTrainedLayersFromBinaryProto(w_path2);
net3->CopyTrainedLayersFromBinaryProto(w_path3);
//argv[1]表示要进行测试图片的路径txt
std::ifstream in(argv[1]);
//std::ifstream in("/home/yang/MTCNN_face_detection_alignment/code/codes/MTCNNv1/model/image.list");
std::string temp_image_path;
std::vector<std::string> image_paths;
//std::cout << "image_path" << std::endl;
while(in >> temp_image_path){
image_paths.push_back(temp_image_path);
//std::cout << temp_image_path << std::endl;
}
in.close();
int image_num = image_paths.size();
//param of face aligned
float factor = 0.79;
int min_size = 10;//min_size of face
std::vector<float> threshold;
threshold.push_back(0.9);
threshold.push_back(0.8);
threshold.push_back(0.7);
std::vector<float> scales;
for(int image_idx = 0; image_idx < image_num; ++image_idx){
cv::Mat image = cv::imread(image_paths[image_idx]);
std::cout << "process "<<image_idx <<" " << image_paths[image_idx] << std::endl;
/*if(image_idx == 0){
std::cout << "image data " << std::endl;
for(int tt = 0; tt < 100; ++tt){
std::cout << int(image.ptr<uchar>(0)[tt*3+2]) << " ";
}
std::cout << std::endl;
}*/
//std::cout << "image size " << image.rows << " " << image.cols << std::endl;
scales.clear();
float m = 12.0/min_size;
float minl = image.cols < image.rows ? image.cols : image.rows;
int count=0;
//scales.push_back(1.0);
while(minl > 12){
scales.push_back(m*pow(factor,count));
minl = minl*factor;
++count;
}
//std::cout << "scales size = " << scales.size() << std::endl;
/*for(int i = 0; i < scales.size(); ++i){
std::cout << scales[i] << " ";
}*/
//std::cout << std::endl;
std::vector<std::vector<float> > total_boxes;
for(int scales_idx = 0; scales_idx < scales.size(); ++scales_idx){
int hs = ceil(image.rows * scales[scales_idx]);
int ws = ceil(image.cols * scales[scales_idx]);
//std::cout << "resize hs ws " << hs << " "<< ws << std::endl;
cv::Mat image_s;
cv::resize(image, image_s, cv::Size(ws, hs));
//std::cout << "resize image hs ws " << image_s.rows << " "<< image_s.cols << std::endl;
/*if(scales_idx == 0){
std::cout << "resize image data " << std::endl;
for(int tt = 0; tt < 100; ++tt){
std::cout << int(image_s.ptr<uchar>(0)[tt*3+2]) << " ";
}
std::cout << std::endl;
}*/
std::vector<int> shape;
shape.push_back(1);
shape.push_back(3);
shape.push_back(ws);
shape.push_back(hs);
net1->input_blobs()[0]->Reshape(shape);
loaddata(net1, image_s);
/*if(scales_idx == 0){
std::ifstream data_in("/home/yang/MTCNN_face_detection_alignment/code/codes/MTCNNv1/test2.txt");
int tt_temp;
for(int tt = 0; tt < 431*450*3; ++tt){
data_in >> tt_temp;
int t1 = tt/(431*450);
int t2 = (tt - t1*431*450)/450;
int t3 = (tt - t1*431*450)%450;
//if(tt < 450)
// std::cout << t1 << " " << t2 << " " << t3 << " " << t1*431*450+t3*450+t2 <<std::endl;
net1->input_blobs()[0]->mutable_cpu_data()[t1*431*450+t3*431+t2] = (tt_temp-127.5)*0.0078125;
}
data_in.close();
std::cout << "end data "<<net1->input_blobs()[0]->mutable_cpu_data()[431*450*3 - 1] << " " << net1->input_blobs()[0]->mutable_cpu_data()[431*450*3 - 2] <<" " << net1->input_blobs()[0]->mutable_cpu_data()[431*450*3 - 3] << " " << net1->input_blobs()[0]->mutable_cpu_data()[431*450*3 - 4] << std::endl;
}
if(scales_idx == 0){
std::cout << "image data 111111111 " << std::endl;
std::cout << (148-127.5)*0.0078125 << std::endl;;
for(int tt = 0; tt < 100; ++tt)
std::cout << net1->input_blobs()[0]->cpu_data()[tt] << " ";
std::cout << std::endl;
}*/
net1->Forward();
caffe::Blob<float>* coord = net1->output_blobs()[0];
caffe::Blob<float>* conf = net1->output_blobs()[1];
/*std::cout << "confidence data " << std::endl;
for(int tt= 0; tt < 100; ++tt){
std::cout << conf->cpu_data()[tt] << " ";
}
std::cout << std::endl;
for(;;);
std::cout << std::endl;*/
const float* coord_cpu_data = coord->cpu_data();
const float* conf_cpu_data = conf->cpu_data()+conf->height()*conf->width();
//std::cout << net1->output_blobs()[0]->num() << " "<< net1->output_blobs()[0]->channels() << " "<< net1->output_blobs()[0]->height() << " "<< net1->output_blobs()[0]->width() << " "<<std::endl;
//std::cout << net1->output_blobs()[1]->num() << " "<< net1->output_blobs()[1]->channels() << " "<< net1->output_blobs()[1]->height() << " "<< net1->output_blobs()[1]->width() << " "<<std::endl;
std::vector<std::vector<float> > boxes;
//std::cout << "output size " << "(" << conf->height() << "," << conf->width() << ")" << std::endl;
for(int i = 0; i < conf->height(); ++i){
for(int j = 0; j < conf->width(); ++j){
if(conf_cpu_data[i*conf->width()+j] > threshold[0]){
//std::cout << "(" << i << "," << j <<")" << " ";
std::vector<float> temp;
temp.push_back(ceil((2*i)/scales[scales_idx]));//表示宽方向的坐标
temp.push_back(ceil((2*j)/scales[scales_idx]));//表示高方向的坐标
temp.push_back(ceil((2*i+11)/scales[scales_idx]));
temp.push_back(ceil((2*j+11)/scales[scales_idx]));
temp.push_back(conf_cpu_data[i*conf->width()+j]);
temp.push_back(coord_cpu_data[0*coord->height()*coord->width()+i*coord->width()+j]);
temp.push_back(coord_cpu_data[1*coord->height()*coord->width()+i*coord->width()+j]);
temp.push_back(coord_cpu_data[2*coord->height()*coord->width()+i*coord->width()+j]);
temp.push_back(coord_cpu_data[3*coord->height()*coord->width()+i*coord->width()+j]);
boxes.push_back(temp);
}
}
}
//std::cout << std::endl;
for(int i = 0; i < boxes.size(); ++i){
for(int j = boxes.size()-1; j > i; --j){
float temp1 = maxf(boxes[i][0], boxes[j][0]);
float temp2 = minf(boxes[i][2], boxes[j][2]);
float temp3 = maxf(boxes[i][1], boxes[j][1]);
float temp4 = minf(boxes[i][3], boxes[j][3]);
temp1 = temp2 - temp1;
temp3 = temp4 - temp3;
float iou;
if(temp1 < 0 || temp3 < 0){
iou = 0.0;
}else{
float area1 = (boxes[i][2] - boxes[i][0])*(boxes[i][3] - boxes[i][1]);
float area2 = (boxes[j][2] - boxes[j][0])*(boxes[j][3] - boxes[j][1]);
iou = temp1*temp3/(area1 + area2 - temp1*temp3);
}
if(iou > 0.5){
//std::cout << boxes[i][4] << " " << boxes[j][4] << std::endl;
if(boxes[i][4] > boxes[j][4]){
boxes.erase(boxes.begin()+j);
}else{
boxes.erase(boxes.begin()+i);
--i;
break;
}
}
}
}
//std::cout << boxes.size() << std::endl;
for(int k = 0; k < boxes.size(); ++k){
total_boxes.push_back(boxes[k]);
}
}
for(int i = 0; i < total_boxes.size(); ++i){
for(int j = total_boxes.size()-1; j > i; --j){
float temp1 = maxf(total_boxes[i][0], total_boxes[j][0]);
float temp2 = minf(total_boxes[i][2], total_boxes[j][2]);
float temp3 = maxf(total_boxes[i][1], total_boxes[j][1]);
float temp4 = minf(total_boxes[i][3], total_boxes[j][3]);
temp1 = temp2 - temp1;
temp3 = temp4 - temp3;
float iou;
if(temp1 < 0 || temp3 < 0){
iou = 0.0;
}else{
float area1 = (total_boxes[i][2] - total_boxes[i][0])*(total_boxes[i][3] - total_boxes[i][1]);
float area2 = (total_boxes[j][2] - total_boxes[j][0])*(total_boxes[j][3] - total_boxes[j][1]);
iou = temp1*temp3/(area1 + area2 - temp1*temp3);
}
if(iou > 0.7){
if(total_boxes[i][4] > total_boxes[j][4]){
total_boxes.erase(total_boxes.begin()+j);
}else{
total_boxes.erase(total_boxes.begin()+i);
--i;
break;
}
}
}
}
for(int i = 0; i < total_boxes.size(); ++i){
float regh = total_boxes[i][2] - total_boxes[i][0];
float regw = total_boxes[i][3] - total_boxes[i][1];
total_boxes[i][0] += total_boxes[i][5]*regh;
if(total_boxes[i][0] < 0) total_boxes[i][0] = 0;
total_boxes[i][1] += total_boxes[i][6]*regw;
if(total_boxes[i][1] < 0) total_boxes[i][1] = 0;
total_boxes[i][2] += total_boxes[i][7]*regh;
//if(total_boxes[i][2] > image.cols) total_boxes[i][2] = image.cols;
total_boxes[i][3] += total_boxes[i][8]*regw;
//if(total_boxes[i][3] > image.rows) total_boxes[i][3] = image.rows;
int max_coord = maxf(regh, regw);
total_boxes[i][0] += (regh*0.5-max_coord*0.5);
total_boxes[i][1] += (regw*0.5-max_coord*0.5);
total_boxes[i][2] = total_boxes[i][0]+max_coord;
total_boxes[i][3] = total_boxes[i][1]+max_coord;
if(total_boxes[i][2] > image.cols) total_boxes[i][2] = image.cols;
if(total_boxes[i][3] > image.rows) total_boxes[i][3] = image.rows;
cv::Point point1(total_boxes[i][0], total_boxes[i][1]);
cv::Point point2(total_boxes[i][2],total_boxes[i][3]);
//cv::rectangle(image, cv::Rect(point2,point1),cv::Scalar(0,255,255),1.0);
}
//cv::imshow("image", image);
//cv::waitKey(0);
//std::cout <<"net 1 boxes num = " <<total_boxes.size() << std::endl;
if(total_boxes.size() == 0) continue;
std::vector<int> shape;
shape.push_back(total_boxes.size());
shape.push_back(3);
shape.push_back(24);
shape.push_back(24);
net2->input_blobs()[0]->Reshape(shape);
for(int i = 0; i < total_boxes.size(); ++i){
//std::cout <<total_boxes[i][0] << " " << total_boxes[i][1] << " " << total_boxes[i][2] << " " << total_boxes[i][3] <<std::endl;
cv::Point p1(total_boxes[i][0], total_boxes[i][1]);
cv::Point p2(total_boxes[i][2], total_boxes[i][3]);
//cv::Mat image_roi = image(cv::Rect(int(total_boxes[i][1]), int(total_boxes[i][0]), int(total_boxes[i][3])-int(total_boxes[i][1]), int(total_boxes[i][2])-int(total_boxes[i][0])));
cv::Mat image_roi = image(cv::Rect(p1, p2));
cv::Mat temp;
//cv::imshow("image_temp", image_roi);
//cv::waitKey(0);
cv::resize(image_roi, temp, cv::Size(24,24));
//cv::imshow("image_temp", temp);
//cv::waitKey(0);
//std::cout << temp.rows << " " << temp.cols << std::endl;
loaddata(net2, temp, i);
}
net2->Forward();
//std::cout << net2->output_blobs()[0]->num() << " "<< net2->output_blobs()[0]->channels() << " "<< net2->output_blobs()[0]->height() << " "<< net2->output_blobs()[0]->width() << " "<<std::endl;
//std::cout << net2->output_blobs()[1]->num() << " "<< net2->output_blobs()[1]->channels() << " "<< net2->output_blobs()[1]->height() << " "<< net2->output_blobs()[1]->width() << " "<<std::endl;
const float* conf_data = net2->output_blobs()[1]->cpu_data();
const float* coor_data = net2->output_blobs()[0]->cpu_data();
for(int i = net2->output_blobs()[0]->num()-1 ; i >= 0; --i){
if(conf_data[i*2 + 1] >= threshold[1]){
total_boxes[i][4] = conf_data[i*2+1];
total_boxes[i][5] = coor_data[i*4+0];
total_boxes[i][6] = coor_data[i*4+1];
total_boxes[i][7] = coor_data[i*4+2];
total_boxes[i][8] = coor_data[i*4+3];
}else{
total_boxes.erase(total_boxes.begin()+i);
}
}
for(int i = 0; i < total_boxes.size(); ++i){
float regh = total_boxes[i][2] - total_boxes[i][0];
float regw = total_boxes[i][3] - total_boxes[i][1];
total_boxes[i][0] += total_boxes[i][5]*regh;
if(total_boxes[i][0] < 0) total_boxes[i][0] = 0;
total_boxes[i][1] += total_boxes[i][6]*regw;
if(total_boxes[i][1] < 0) total_boxes[i][1] = 0;
total_boxes[i][2] += total_boxes[i][7]*regh;
total_boxes[i][3] += total_boxes[i][8]*regw;
/*int max_coord = maxf(regh, regw);
total_boxes[i][0] += (regh*0.5-max_coord*0.5);
total_boxes[i][1] += (regw*0.5-max_coord*0.5);
total_boxes[i][2] = total_boxes[i][0]+max_coord;
total_boxes[i][3] = total_boxes[i][1]+max_coord;*/
if(total_boxes[i][2] > image.cols) total_boxes[i][2] = image.cols;
if(total_boxes[i][3] > image.rows) total_boxes[i][3] = image.rows;
}
for(int i = 0; i < total_boxes.size(); ++i){
for(int j = total_boxes.size()-1; j > i; --j){
float temp1 = maxf(total_boxes[i][0], total_boxes[j][0]);
float temp2 = minf(total_boxes[i][2], total_boxes[j][2]);
float temp3 = maxf(total_boxes[i][1], total_boxes[j][1]);
float temp4 = minf(total_boxes[i][3], total_boxes[j][3]);
temp1 = temp2 - temp1;
temp3 = temp4 - temp3;
float iou;
if(temp1 < 0 || temp3 < 0){
iou = 0.0;
}else{
float area1 = (total_boxes[i][2] - total_boxes[i][0])*(total_boxes[i][3] - total_boxes[i][1]);
float area2 = (total_boxes[j][2] - total_boxes[j][0])*(total_boxes[j][3] - total_boxes[j][1]);
//float area3 = minf(area1, area2);
iou = temp1*temp3/(area1+area2-temp1*temp3);
}
if(iou > 0.7){
if(total_boxes[i][4] > total_boxes[j][4]){
total_boxes.erase(total_boxes.begin()+j);
}else{
total_boxes.erase(total_boxes.begin()+i);
--i;
break;
}
}
}
}
for(int i = 0; i < total_boxes.size(); ++i){
cv::Point point1(total_boxes[i][0], total_boxes[i][1]);
cv::Point point2(total_boxes[i][2],total_boxes[i][3]);
//cv::rectangle(image, cv::Rect(point2,point1),cv::Scalar(0,255,255),1.0);
}
//cv::imshow("image", image);
//cv::waitKey(0);
//std::cout << "net 2 process boxes num = " << total_boxes.size() << std::endl;
if(total_boxes.size() == 0) continue;
std::vector<int> shape2;
shape2.push_back(total_boxes.size());
shape2.push_back(3);
shape2.push_back(48);
shape2.push_back(48);
net3->input_blobs()[0]->Reshape(shape2);
for(int i = 0; i < total_boxes.size(); ++i){
cv::Point point1(total_boxes[i][0], total_boxes[i][1]);
cv::Point point2(total_boxes[i][2],total_boxes[i][3]);
cv::Mat face_need_align = image(cv::Rect(point1, point2));
cv::resize(face_need_align, face_need_align, cv::Size(48,48));
loaddata(net3, face_need_align, i);
}
net3->Forward();
for(int i = total_boxes.size()-1; i >= 0; --i){
if(net3->output_blobs()[2]->cpu_data()[i*2+1] < threshold[2]){
total_boxes.erase(total_boxes.begin()+i);
}else{
float w = total_boxes[i][2] - total_boxes[i][0];
float h = total_boxes[i][3] - total_boxes[i][1];
total_boxes[i][5] = net3->output_blobs()[0]->cpu_data()[i*4+0];
total_boxes[i][6] = net3->output_blobs()[0]->cpu_data()[i*4+1];
total_boxes[i][7] = net3->output_blobs()[0]->cpu_data()[i*4+2];
total_boxes[i][8] = net3->output_blobs()[0]->cpu_data()[i*4+3];
total_boxes[i].push_back(net3->output_blobs()[1]->cpu_data()[i*10+0]*w+total_boxes[i][0]);
total_boxes[i].push_back(net3->output_blobs()[1]->cpu_data()[i*10+1]*w+total_boxes[i][0]);
total_boxes[i].push_back(net3->output_blobs()[1]->cpu_data()[i*10+2]*w+total_boxes[i][0]);
total_boxes[i].push_back(net3->output_blobs()[1]->cpu_data()[i*10+3]*w+total_boxes[i][0]);
total_boxes[i].push_back(net3->output_blobs()[1]->cpu_data()[i*10+4]*w+total_boxes[i][0]);
total_boxes[i].push_back(net3->output_blobs()[1]->cpu_data()[i*10+5]*h+total_boxes[i][1]);
total_boxes[i].push_back(net3->output_blobs()[1]->cpu_data()[i*10+6]*h+total_boxes[i][1]);
total_boxes[i].push_back(net3->output_blobs()[1]->cpu_data()[i*10+7]*h+total_boxes[i][1]);
total_boxes[i].push_back(net3->output_blobs()[1]->cpu_data()[i*10+8]*h+total_boxes[i][1]);
total_boxes[i].push_back(net3->output_blobs()[1]->cpu_data()[i*10+9]*h+total_boxes[i][1]);
}
}
for(int i = 0; i < total_boxes.size(); ++i){
for(int j = total_boxes.size()-1; j > i; --j){
float temp1 = maxf(total_boxes[i][0], total_boxes[j][0]);
float temp2 = minf(total_boxes[i][2], total_boxes[j][2]);
float temp3 = maxf(total_boxes[i][1], total_boxes[j][1]);
float temp4 = minf(total_boxes[i][3], total_boxes[j][3]);
temp1 = temp2 - temp1;
temp3 = temp4 - temp3;
float iou;
if(temp1 < 0 || temp3 < 0){
iou = 0.0;
}else{
float area1 = (total_boxes[i][2] - total_boxes[i][0])*(total_boxes[i][3] - total_boxes[i][1]);
float area2 = (total_boxes[j][2] - total_boxes[j][0])*(total_boxes[j][3] - total_boxes[j][1]);
float area3 = minf(area1, area2);
iou = temp1*temp3/(area3);
}
if(iou > 0.7){
if(total_boxes[i][4] > total_boxes[j][4]){
total_boxes.erase(total_boxes.begin()+j);
}else{
total_boxes.erase(total_boxes.begin()+i);
--i;
break;
}
}
}
}
for(int i = 0; i < total_boxes.size(); ++i){
//还没进行回归检测
float regh = total_boxes[i][2] - total_boxes[i][0];
float regw = total_boxes[i][3] - total_boxes[i][1];
total_boxes[i][0] += total_boxes[i][5]*regh;
if(total_boxes[i][0] < 0) total_boxes[i][0] = 0;
total_boxes[i][1] += total_boxes[i][6]*regw;
if(total_boxes[i][1] < 0) total_boxes[i][1] = 0;
total_boxes[i][2] += total_boxes[i][7]*regh;
total_boxes[i][3] += total_boxes[i][8]*regw;
/*int max_coord = maxf(regh, regw);
total_boxes[i][0] += (regh*0.5-max_coord*0.5);
total_boxes[i][1] += (regw*0.5-max_coord*0.5);
total_boxes[i][2] = total_boxes[i][0]+max_coord;
total_boxes[i][3] = total_boxes[i][1]+max_coord;*/
cv::Point point1(total_boxes[i][0], total_boxes[i][1]);
cv::Point point2(total_boxes[i][2],total_boxes[i][3]);
cv::rectangle(image, cv::Rect(point2,point1),cv::Scalar(0,255,255),1.0);
cv::rectangle(image, cv::Rect(total_boxes[i][9], total_boxes[i][14], 1, 1), cv::Scalar(255,255,0), 2.0);
cv::rectangle(image, cv::Rect(total_boxes[i][10], total_boxes[i][15], 1, 1), cv::Scalar(255,255,0), 2.0);
cv::rectangle(image, cv::Rect(total_boxes[i][11], total_boxes[i][16], 1, 1), cv::Scalar(255,255,0), 2.0);
cv::rectangle(image, cv::Rect(total_boxes[i][12], total_boxes[i][17], 1, 1), cv::Scalar(255,255,0), 2.0);
cv::rectangle(image, cv::Rect(total_boxes[i][13], total_boxes[i][18], 1, 1), cv::Scalar(255,255,0), 2.0);
}
cv::imshow("image", image);
cv::waitKey(1);
}
return 1;
}
void loaddata(boost::shared_ptr<caffe::Net<float> >& net, cv::Mat image){
caffe::Blob<float>* input_layer = net->input_blobs()[0];
int width, height;
width = input_layer->width();
height = input_layer->height();
int size = width*height;
float* input_data = input_layer->mutable_cpu_data();
int temp,idx;
for(int i = 0; i < width; ++i){
uchar* pdata = image.ptr<uchar>(i);
for(int j = 0; j < height; ++j){
temp = 3*j;
idx = j*width+i;
input_data[idx] = (pdata[temp+2]-127.5)*0.0078125;
input_data[idx+size] = (pdata[temp+1]-127.5)*0.0078125;
input_data[idx+2*size] = (pdata[temp+0]-127.5)*0.0078125;
}
}
}
void loaddata(boost::shared_ptr<caffe::Net<float> >& net, cv::Mat image, int batch_idx){
caffe::Blob<float>* input_layer = net->input_blobs()[0];
int width, height;
width = input_layer->width();
height = input_layer->height();
int size = width*height;
float* input_data = input_layer->mutable_cpu_data() + batch_idx*size*3;
int temp,idx;
for(int i = 0; i < width; ++i){
uchar* pdata = image.ptr<uchar>(i);
for(int j = 0; j < height; ++j){
temp = 3*j;
idx = j*width+i;
input_data[idx] = (pdata[temp+2]-127.5)*0.0078125;
input_data[idx+size] = (pdata[temp+1]-127.5)*0.0078125;
input_data[idx+2*size] = (pdata[temp+0]-127.5)*0.0078125;
}
}
}
float maxf(float x1, float x2){
if(x1 > x2)
return x1;
else
return x2;
}
float minf(float x1, float x2){
if(x1 > x2)
return x2;
else
return x1;
}