create project
create project
This commit is contained in:
2
.gitattributes
vendored
Executable file
2
.gitattributes
vendored
Executable file
@@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
47
.gitignore
vendored
Normal file → Executable file
47
.gitignore
vendored
Normal file → Executable file
@@ -1,32 +1,15 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
.idea/
|
||||
cmake-build-debug/
|
||||
cmake-build-default/
|
||||
cmake-build-release/
|
||||
images/
|
||||
model/
|
||||
model_128/
|
||||
model_512/
|
||||
result.jpg
|
||||
Kong_Weiye.jpg
|
||||
Kong_Weiye1.jpg
|
||||
model_128.zip
|
||||
model_512.zip
|
||||
emb_csv/*.csv
|
||||
emb_img/*.jpg
|
||||
|
||||
11
CMakeLists.txt
Executable file
11
CMakeLists.txt
Executable file
@@ -0,0 +1,11 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(main)
|
||||
|
||||
set(QMAKE_CXXFLAGS "-std=c++11")
|
||||
|
||||
find_package(OpenCV REQUIRED)
|
||||
|
||||
#set(CMAKE_BUILD_TYPE Debug)
|
||||
AUX_SOURCE_DIRECTORY(./src DIR_SRCS)
|
||||
add_executable(main ${DIR_SRCS})
|
||||
target_link_libraries(main ${OpenCV_LIBS})
|
||||
7
README.md
Normal file → Executable file
7
README.md
Normal file → Executable file
@@ -1,2 +1,7 @@
|
||||
# MTCNN-FaceNet-light
|
||||
MTCNN-FaceNet-light c++
|
||||
|
||||
MTCNN-FaceNet-light with c++
|
||||
|
||||
2019-12-06 修改多处bug,卷积初始化后直接进行卷积
|
||||
|
||||
2019-12-24 添加BN层
|
||||
|
||||
1198
src/facenet.cpp
Executable file
1198
src/facenet.cpp
Executable file
File diff suppressed because it is too large
Load Diff
66
src/facenet.h
Executable file
66
src/facenet.h
Executable file
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// Created by Lenovo on 2019/10/17.
|
||||
//
|
||||
|
||||
#ifndef MAIN_FACENET_H
|
||||
#define MAIN_FACENET_H
|
||||
|
||||
#include "network.h"
|
||||
|
||||
|
||||
class facenet {
|
||||
public:
|
||||
facenet();
|
||||
|
||||
~facenet();
|
||||
|
||||
void run(Mat &image, mydataFmt *o, int count = 1);
|
||||
|
||||
void prewhiten(Mat &image);
|
||||
|
||||
private:
|
||||
void Stem(Mat &image, pBox *output);
|
||||
|
||||
void Inception_resnet_A(pBox *input, pBox *output, string filepath = "", float scale = 1.0);
|
||||
|
||||
void Reduction_A(pBox *input, pBox *output);
|
||||
|
||||
void Inception_resnet_B(pBox *input, pBox *output, string filepath = "", float scale = 1.0);
|
||||
|
||||
void Reduction_B(pBox *input, pBox *output);
|
||||
|
||||
void Inception_resnet_C(pBox *input, pBox *output, string filepath = "", float scale = 1.0);
|
||||
|
||||
void Inception_resnet_C_None(pBox *input, pBox *output, string filepath = "");
|
||||
|
||||
void AveragePooling(pBox *input, pBox *output);
|
||||
|
||||
void fully_connect(pBox *input, pBox *output, string filepath = "");
|
||||
|
||||
void conv_merge(pBox *output, pBox *c1 = 0, pBox *c2 = 0, pBox *c3 = 0, pBox *c4 = 0);
|
||||
|
||||
void conv_mergeInit(pBox *output, pBox *c1 = 0, pBox *c2 = 0, pBox *c3 = 0, pBox *c4 = 0);
|
||||
|
||||
void mulandaddInit(const pBox *inpbox, const pBox *temppbox, pBox *outpBox, float scale);
|
||||
|
||||
void mulandadd(const pBox *inpbox, const pBox *temppbox, pBox *outpBox, float scale = 1);
|
||||
|
||||
void Flatten(pBox *input, pBox *output);
|
||||
|
||||
void printData(pBox *output);
|
||||
|
||||
|
||||
|
||||
// Mat reImage;
|
||||
// float nms_threshold[3];
|
||||
// vector<float> scales_;
|
||||
// vector<struct Bbox> firstBbox_;
|
||||
// vector<struct orderScore> firstOrderScore_;
|
||||
// vector<struct Bbox> secondBbox_;
|
||||
// vector<struct orderScore> secondBboxScore_;
|
||||
// vector<struct Bbox> thirdBbox_;
|
||||
// vector<struct orderScore> thirdBboxScore_;
|
||||
|
||||
};
|
||||
|
||||
#endif //MAIN_FACENET_H
|
||||
659
src/mtcnn.cpp
Executable file
659
src/mtcnn.cpp
Executable file
@@ -0,0 +1,659 @@
|
||||
#include "mtcnn.h"
|
||||
|
||||
Pnet::Pnet() {
|
||||
Pthreshold = 0.6f;
|
||||
nms_threshold = 0.5;
|
||||
firstFlag = true;
|
||||
this->rgb = new pBox;
|
||||
|
||||
this->conv1 = new pBox;
|
||||
this->maxPooling1 = new pBox;
|
||||
this->conv2 = new pBox;
|
||||
this->conv3 = new pBox;
|
||||
this->score_ = new pBox;
|
||||
|
||||
this->location_ = new pBox;
|
||||
|
||||
this->conv1_wb = new Weight;
|
||||
this->prelu_gmma1 = new pRelu;
|
||||
this->conv2_wb = new Weight;
|
||||
this->prelu_gmma2 = new pRelu;
|
||||
this->conv3_wb = new Weight;
|
||||
this->prelu_gmma3 = new pRelu;
|
||||
this->conv4c1_wb = new Weight;
|
||||
this->conv4c2_wb = new Weight;
|
||||
// w sc lc ks s p
|
||||
long conv1 = initConvAndFc(this->conv1_wb, 10, 3, 3, 1, 0);
|
||||
initpRelu(this->prelu_gmma1, 10);
|
||||
long conv2 = initConvAndFc(this->conv2_wb, 16, 10, 3, 1, 0);
|
||||
initpRelu(this->prelu_gmma2, 16);
|
||||
long conv3 = initConvAndFc(this->conv3_wb, 32, 16, 3, 1, 0);
|
||||
initpRelu(this->prelu_gmma3, 32);
|
||||
long conv4c1 = initConvAndFc(this->conv4c1_wb, 2, 32, 1, 1, 0);
|
||||
long conv4c2 = initConvAndFc(this->conv4c2_wb, 4, 32, 1, 1, 0);
|
||||
long dataNumber[13] = {conv1, 10, 10, conv2, 16, 16, conv3, 32, 32, conv4c1, 2, conv4c2, 4};
|
||||
mydataFmt *pointTeam[13] = {this->conv1_wb->pdata, this->conv1_wb->pbias, this->prelu_gmma1->pdata, \
|
||||
this->conv2_wb->pdata, this->conv2_wb->pbias, this->prelu_gmma2->pdata, \
|
||||
this->conv3_wb->pdata, this->conv3_wb->pbias, this->prelu_gmma3->pdata, \
|
||||
this->conv4c1_wb->pdata, this->conv4c1_wb->pbias, \
|
||||
this->conv4c2_wb->pdata, this->conv4c2_wb->pbias};
|
||||
string filename = "../Pnet.txt";
|
||||
readData(filename, dataNumber, pointTeam, 13);
|
||||
}
|
||||
|
||||
Pnet::~Pnet() {
|
||||
freepBox(this->rgb);
|
||||
freepBox(this->conv1);
|
||||
freepBox(this->maxPooling1);
|
||||
freepBox(this->conv2);
|
||||
freepBox(this->conv3);
|
||||
freepBox(this->score_);
|
||||
freepBox(this->location_);
|
||||
|
||||
freeWeight(this->conv1_wb);
|
||||
freepRelu(this->prelu_gmma1);
|
||||
freeWeight(this->conv2_wb);
|
||||
freepRelu(this->prelu_gmma2);
|
||||
freeWeight(this->conv3_wb);
|
||||
freepRelu(this->prelu_gmma3);
|
||||
freeWeight(this->conv4c1_wb);
|
||||
freeWeight(this->conv4c2_wb);
|
||||
}
|
||||
|
||||
void Pnet::run(Mat &image, mydataFmt scale) {
|
||||
if (firstFlag) {
|
||||
image2MatrixInit(image, this->rgb);
|
||||
convolutionInit(this->conv1_wb, this->rgb, this->conv1);
|
||||
maxPoolingInit(this->conv1, this->maxPooling1, 2, 2);
|
||||
convolutionInit(this->conv2_wb, this->maxPooling1, this->conv2);
|
||||
convolutionInit(this->conv3_wb, this->conv2, this->conv3);
|
||||
convolutionInit(this->conv4c1_wb, this->conv3, this->score_);
|
||||
convolutionInit(this->conv4c2_wb, this->conv3, this->location_);
|
||||
firstFlag = false;
|
||||
}
|
||||
|
||||
image2Matrix(image, this->rgb);
|
||||
|
||||
|
||||
convolution(this->conv1_wb, this->rgb, this->conv1);
|
||||
prelu(this->conv1, this->conv1_wb->pbias, this->prelu_gmma1->pdata);
|
||||
//Pooling layer
|
||||
maxPooling(this->conv1, this->maxPooling1, 2, 2);
|
||||
|
||||
|
||||
convolution(this->conv2_wb, this->maxPooling1, this->conv2);
|
||||
prelu(this->conv2, this->conv2_wb->pbias, this->prelu_gmma2->pdata);
|
||||
//conv3
|
||||
|
||||
convolution(this->conv3_wb, this->conv2, this->conv3);
|
||||
prelu(this->conv3, this->conv3_wb->pbias, this->prelu_gmma3->pdata);
|
||||
//conv4c1 score
|
||||
|
||||
convolution(this->conv4c1_wb, this->conv3, this->score_);
|
||||
addbias(this->score_, this->conv4c1_wb->pbias);
|
||||
softmax(this->score_);
|
||||
// pBoxShow(this->score_);
|
||||
|
||||
//conv4c2 location
|
||||
convolution(this->conv4c2_wb, this->conv3, this->location_);
|
||||
addbias(this->location_, this->conv4c2_wb->pbias);
|
||||
//softmax layer
|
||||
generateBbox(this->score_, this->location_, scale);
|
||||
}
|
||||
|
||||
void Pnet::generateBbox(const struct pBox *score, const struct pBox *location, mydataFmt scale) {
|
||||
//for pooling
|
||||
int stride = 2;
|
||||
int cellsize = 12;
|
||||
int count = 0;
|
||||
//score p
|
||||
mydataFmt *p = score->pdata + score->width * score->height;
|
||||
mydataFmt *plocal = location->pdata;
|
||||
struct Bbox bbox;
|
||||
struct orderScore order;
|
||||
for (int row = 0; row < score->height; row++) {
|
||||
for (int col = 0; col < score->width; col++) {
|
||||
if (*p > Pthreshold) {
|
||||
bbox.score = *p;
|
||||
order.score = *p;
|
||||
order.oriOrder = count;
|
||||
/*
|
||||
bbox.x1 = round((stride*col + 1) / scale);
|
||||
bbox.y1 = round((stride*row + 1) / scale);
|
||||
bbox.x2 = round((stride*col + 1 + cellsize) / scale);
|
||||
bbox.y2 = round((stride*row + 1 + cellsize) / scale);
|
||||
*/
|
||||
|
||||
bbox.x1 = int(round((stride * row + 1) / scale));
|
||||
bbox.y1 = int(round((stride * col + 1) / scale));
|
||||
bbox.x2 = int(round((stride * row + 1 + cellsize) / scale));
|
||||
bbox.y2 = int(round((stride * col + 1 + cellsize) / scale));
|
||||
|
||||
bbox.exist = true;
|
||||
bbox.area = float((bbox.x2 - bbox.x1) * (bbox.y2 - bbox.y1));
|
||||
for (int channel = 0; channel < 4; channel++)
|
||||
bbox.regreCoord[channel] = *(plocal + channel * location->width * location->height);
|
||||
boundingBox_.push_back(bbox);
|
||||
bboxScore_.push_back(order);
|
||||
count++;
|
||||
}
|
||||
p++;
|
||||
plocal++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rnet::Rnet() {
|
||||
Rthreshold = 0.7f;
|
||||
|
||||
this->rgb = new pBox;
|
||||
this->conv1_out = new pBox;
|
||||
this->pooling1_out = new pBox;
|
||||
|
||||
this->conv2_out = new pBox;
|
||||
this->pooling2_out = new pBox;
|
||||
|
||||
this->conv3_out = new pBox;
|
||||
|
||||
this->fc4_out = new pBox;
|
||||
|
||||
this->score_ = new pBox;
|
||||
this->location_ = new pBox;
|
||||
|
||||
this->conv1_wb = new Weight;
|
||||
this->prelu_gmma1 = new pRelu;
|
||||
this->conv2_wb = new Weight;
|
||||
this->prelu_gmma2 = new pRelu;
|
||||
this->conv3_wb = new Weight;
|
||||
this->prelu_gmma3 = new pRelu;
|
||||
this->fc4_wb = new Weight;
|
||||
this->prelu_gmma4 = new pRelu;
|
||||
this->score_wb = new Weight;
|
||||
this->location_wb = new Weight;
|
||||
// // w sc lc ks s p
|
||||
long conv1 = initConvAndFc(this->conv1_wb, 28, 3, 3, 1, 0);
|
||||
initpRelu(this->prelu_gmma1, 28);
|
||||
long conv2 = initConvAndFc(this->conv2_wb, 48, 28, 3, 1, 0);
|
||||
initpRelu(this->prelu_gmma2, 48);
|
||||
long conv3 = initConvAndFc(this->conv3_wb, 64, 48, 2, 1, 0);
|
||||
initpRelu(this->prelu_gmma3, 64);
|
||||
long fc4 = initConvAndFc(this->fc4_wb, 128, 576, 1, 1, 0);
|
||||
initpRelu(this->prelu_gmma4, 128);
|
||||
long score = initConvAndFc(this->score_wb, 2, 128, 1, 1, 0);
|
||||
long location = initConvAndFc(this->location_wb, 4, 128, 1, 1, 0);
|
||||
long dataNumber[16] = {conv1, 28, 28, conv2, 48, 48, conv3, 64, 64, fc4, 128, 128, score, 2, location, 4};
|
||||
mydataFmt *pointTeam[16] = {this->conv1_wb->pdata, this->conv1_wb->pbias, this->prelu_gmma1->pdata, \
|
||||
this->conv2_wb->pdata, this->conv2_wb->pbias, this->prelu_gmma2->pdata, \
|
||||
this->conv3_wb->pdata, this->conv3_wb->pbias, this->prelu_gmma3->pdata, \
|
||||
this->fc4_wb->pdata, this->fc4_wb->pbias, this->prelu_gmma4->pdata, \
|
||||
this->score_wb->pdata, this->score_wb->pbias, \
|
||||
this->location_wb->pdata, this->location_wb->pbias};
|
||||
string filename = "../Rnet.txt";
|
||||
readData(filename, dataNumber, pointTeam, 16);
|
||||
|
||||
//Init the network
|
||||
RnetImage2MatrixInit(rgb);
|
||||
convolutionInit(this->conv1_wb, this->rgb, this->conv1_out);
|
||||
maxPoolingInit(this->conv1_out, this->pooling1_out, 3, 2);
|
||||
convolutionInit(this->conv2_wb, this->pooling1_out, this->conv2_out);
|
||||
maxPoolingInit(this->conv2_out, this->pooling2_out, 3, 2);
|
||||
convolutionInit(this->conv3_wb, this->pooling2_out, this->conv3_out);
|
||||
fullconnectInit(this->fc4_wb, this->fc4_out);
|
||||
fullconnectInit(this->score_wb, this->score_);
|
||||
fullconnectInit(this->location_wb, this->location_);
|
||||
}
|
||||
|
||||
Rnet::~Rnet() {
|
||||
freepBox(this->rgb);
|
||||
freepBox(this->conv1_out);
|
||||
freepBox(this->pooling1_out);
|
||||
freepBox(this->conv2_out);
|
||||
freepBox(this->pooling2_out);
|
||||
freepBox(this->conv3_out);
|
||||
freepBox(this->fc4_out);
|
||||
freepBox(this->score_);
|
||||
freepBox(this->location_);
|
||||
|
||||
freeWeight(this->conv1_wb);
|
||||
freepRelu(this->prelu_gmma1);
|
||||
freeWeight(this->conv2_wb);
|
||||
freepRelu(this->prelu_gmma2);
|
||||
freeWeight(this->conv3_wb);
|
||||
freepRelu(this->prelu_gmma3);
|
||||
freeWeight(this->fc4_wb);
|
||||
freepRelu(this->prelu_gmma4);
|
||||
freeWeight(this->score_wb);
|
||||
freeWeight(this->location_wb);
|
||||
}
|
||||
|
||||
void Rnet::RnetImage2MatrixInit(struct pBox *pbox) {
|
||||
pbox->channel = 3;
|
||||
pbox->height = 24;
|
||||
pbox->width = 24;
|
||||
|
||||
pbox->pdata = (mydataFmt *) malloc(pbox->channel * pbox->height * pbox->width * sizeof(mydataFmt));
|
||||
if (pbox->pdata == NULL)cout << "the image2MatrixInit is failed!!" << endl;
|
||||
memset(pbox->pdata, 0, pbox->channel * pbox->height * pbox->width * sizeof(mydataFmt));
|
||||
}
|
||||
|
||||
void Rnet::run(Mat &image) {
|
||||
image2Matrix(image, this->rgb);
|
||||
|
||||
convolution(this->conv1_wb, this->rgb, this->conv1_out);
|
||||
prelu(this->conv1_out, this->conv1_wb->pbias, this->prelu_gmma1->pdata);
|
||||
|
||||
maxPooling(this->conv1_out, this->pooling1_out, 3, 2);
|
||||
|
||||
convolution(this->conv2_wb, this->pooling1_out, this->conv2_out);
|
||||
prelu(this->conv2_out, this->conv2_wb->pbias, this->prelu_gmma2->pdata);
|
||||
maxPooling(this->conv2_out, this->pooling2_out, 3, 2);
|
||||
|
||||
//conv3
|
||||
convolution(this->conv3_wb, this->pooling2_out, this->conv3_out);
|
||||
prelu(this->conv3_out, this->conv3_wb->pbias, this->prelu_gmma3->pdata);
|
||||
|
||||
//flatten
|
||||
fullconnect(this->fc4_wb, this->conv3_out, this->fc4_out);
|
||||
prelu(this->fc4_out, this->fc4_wb->pbias, this->prelu_gmma4->pdata);
|
||||
|
||||
//conv51 score
|
||||
fullconnect(this->score_wb, this->fc4_out, this->score_);
|
||||
addbias(this->score_, this->score_wb->pbias);
|
||||
softmax(this->score_);
|
||||
|
||||
//conv5_2 location
|
||||
fullconnect(this->location_wb, this->fc4_out, this->location_);
|
||||
addbias(this->location_, this->location_wb->pbias);
|
||||
// pBoxShow(location_);
|
||||
}
|
||||
|
||||
Onet::Onet() {
|
||||
Othreshold = 0.7f;
|
||||
this->rgb = new pBox;
|
||||
|
||||
this->conv1_out = new pBox;
|
||||
this->pooling1_out = new pBox;
|
||||
|
||||
this->conv2_out = new pBox;
|
||||
this->pooling2_out = new pBox;
|
||||
|
||||
this->conv3_out = new pBox;
|
||||
this->pooling3_out = new pBox;
|
||||
|
||||
this->conv4_out = new pBox;
|
||||
|
||||
this->fc5_out = new pBox;
|
||||
|
||||
this->score_ = new pBox;
|
||||
this->location_ = new pBox;
|
||||
this->keyPoint_ = new pBox;
|
||||
|
||||
this->conv1_wb = new Weight;
|
||||
this->prelu_gmma1 = new pRelu;
|
||||
this->conv2_wb = new Weight;
|
||||
this->prelu_gmma2 = new pRelu;
|
||||
this->conv3_wb = new Weight;
|
||||
this->prelu_gmma3 = new pRelu;
|
||||
this->conv4_wb = new Weight;
|
||||
this->prelu_gmma4 = new pRelu;
|
||||
this->fc5_wb = new Weight;
|
||||
this->prelu_gmma5 = new pRelu;
|
||||
this->score_wb = new Weight;
|
||||
this->location_wb = new Weight;
|
||||
this->keyPoint_wb = new Weight;
|
||||
|
||||
// // w sc lc ks s p
|
||||
long conv1 = initConvAndFc(this->conv1_wb, 32, 3, 3, 1, 0);
|
||||
initpRelu(this->prelu_gmma1, 32);
|
||||
long conv2 = initConvAndFc(this->conv2_wb, 64, 32, 3, 1, 0);
|
||||
initpRelu(this->prelu_gmma2, 64);
|
||||
long conv3 = initConvAndFc(this->conv3_wb, 64, 64, 3, 1, 0);
|
||||
initpRelu(this->prelu_gmma3, 64);
|
||||
long conv4 = initConvAndFc(this->conv4_wb, 128, 64, 2, 1, 0);
|
||||
initpRelu(this->prelu_gmma4, 128);
|
||||
long fc5 = initConvAndFc(this->fc5_wb, 256, 1152, 1, 1, 0);
|
||||
initpRelu(this->prelu_gmma5, 256);
|
||||
long score = initConvAndFc(this->score_wb, 2, 256, 1, 1, 0);
|
||||
long location = initConvAndFc(this->location_wb, 4, 256, 1, 1, 0);
|
||||
long keyPoint = initConvAndFc(this->keyPoint_wb, 10, 256, 1, 1, 0);
|
||||
long dataNumber[21] = {conv1, 32, 32, conv2, 64, 64, conv3, 64, 64, conv4, 128, 128, fc5, 256, 256, score, 2,
|
||||
location, 4, keyPoint, 10};
|
||||
mydataFmt *pointTeam[21] = {this->conv1_wb->pdata, this->conv1_wb->pbias, this->prelu_gmma1->pdata, \
|
||||
this->conv2_wb->pdata, this->conv2_wb->pbias, this->prelu_gmma2->pdata, \
|
||||
this->conv3_wb->pdata, this->conv3_wb->pbias, this->prelu_gmma3->pdata, \
|
||||
this->conv4_wb->pdata, this->conv4_wb->pbias, this->prelu_gmma4->pdata, \
|
||||
this->fc5_wb->pdata, this->fc5_wb->pbias, this->prelu_gmma5->pdata, \
|
||||
this->score_wb->pdata, this->score_wb->pbias, \
|
||||
this->location_wb->pdata, this->location_wb->pbias, \
|
||||
this->keyPoint_wb->pdata, this->keyPoint_wb->pbias};
|
||||
string filename = "../Onet.txt";
|
||||
readData(filename, dataNumber, pointTeam, 21);
|
||||
|
||||
//Init the network
|
||||
OnetImage2MatrixInit(rgb);
|
||||
|
||||
convolutionInit(this->conv1_wb, this->rgb, this->conv1_out);
|
||||
maxPoolingInit(this->conv1_out, this->pooling1_out, 3, 2);
|
||||
|
||||
convolutionInit(this->conv2_wb, this->pooling1_out, this->conv2_out);
|
||||
maxPoolingInit(this->conv2_out, this->pooling2_out, 3, 2);
|
||||
|
||||
convolutionInit(this->conv3_wb, this->pooling2_out, this->conv3_out);
|
||||
maxPoolingInit(this->conv3_out, this->pooling3_out, 2, 2);
|
||||
|
||||
convolutionInit(this->conv4_wb, this->pooling3_out, this->conv4_out);
|
||||
|
||||
fullconnectInit(this->fc5_wb, this->fc5_out);
|
||||
fullconnectInit(this->score_wb, this->score_);
|
||||
fullconnectInit(this->location_wb, this->location_);
|
||||
fullconnectInit(this->keyPoint_wb, this->keyPoint_);
|
||||
}
|
||||
|
||||
Onet::~Onet() {
|
||||
freepBox(this->rgb);
|
||||
freepBox(this->conv1_out);
|
||||
freepBox(this->pooling1_out);
|
||||
freepBox(this->conv2_out);
|
||||
freepBox(this->pooling2_out);
|
||||
freepBox(this->conv3_out);
|
||||
freepBox(this->pooling3_out);
|
||||
freepBox(this->conv4_out);
|
||||
freepBox(this->fc5_out);
|
||||
freepBox(this->score_);
|
||||
freepBox(this->location_);
|
||||
freepBox(this->keyPoint_);
|
||||
|
||||
freeWeight(this->conv1_wb);
|
||||
freepRelu(this->prelu_gmma1);
|
||||
freeWeight(this->conv2_wb);
|
||||
freepRelu(this->prelu_gmma2);
|
||||
freeWeight(this->conv3_wb);
|
||||
freepRelu(this->prelu_gmma3);
|
||||
freeWeight(this->conv4_wb);
|
||||
freepRelu(this->prelu_gmma4);
|
||||
freeWeight(this->fc5_wb);
|
||||
freepRelu(this->prelu_gmma5);
|
||||
freeWeight(this->score_wb);
|
||||
freeWeight(this->location_wb);
|
||||
freeWeight(this->keyPoint_wb);
|
||||
}
|
||||
|
||||
void Onet::OnetImage2MatrixInit(struct pBox *pbox) {
|
||||
pbox->channel = 3;
|
||||
pbox->height = 48;
|
||||
pbox->width = 48;
|
||||
|
||||
pbox->pdata = (mydataFmt *) malloc(pbox->channel * pbox->height * pbox->width * sizeof(mydataFmt));
|
||||
if (pbox->pdata == NULL)cout << "the image2MatrixInit is failed!!" << endl;
|
||||
memset(pbox->pdata, 0, pbox->channel * pbox->height * pbox->width * sizeof(mydataFmt));
|
||||
}
|
||||
|
||||
void Onet::run(Mat &image) {
|
||||
image2Matrix(image, this->rgb);
|
||||
|
||||
convolution(this->conv1_wb, this->rgb, this->conv1_out);
|
||||
prelu(this->conv1_out, this->conv1_wb->pbias, this->prelu_gmma1->pdata);
|
||||
|
||||
//Pooling layer
|
||||
maxPooling(this->conv1_out, this->pooling1_out, 3, 2);
|
||||
|
||||
|
||||
convolution(this->conv2_wb, this->pooling1_out, this->conv2_out);
|
||||
prelu(this->conv2_out, this->conv2_wb->pbias, this->prelu_gmma2->pdata);
|
||||
maxPooling(this->conv2_out, this->pooling2_out, 3, 2);
|
||||
|
||||
//conv3
|
||||
convolution(this->conv3_wb, this->pooling2_out, this->conv3_out);
|
||||
prelu(this->conv3_out, this->conv3_wb->pbias, this->prelu_gmma3->pdata);
|
||||
maxPooling(this->conv3_out, this->pooling3_out, 2, 2);
|
||||
|
||||
//conv4
|
||||
convolution(this->conv4_wb, this->pooling3_out, this->conv4_out);
|
||||
// convolution(this->conv4_wb, this->pooling3_out, this->conv4_out, this->conv4_matrix);
|
||||
prelu(this->conv4_out, this->conv4_wb->pbias, this->prelu_gmma4->pdata);
|
||||
|
||||
fullconnect(this->fc5_wb, this->conv4_out, this->fc5_out);
|
||||
prelu(this->fc5_out, this->fc5_wb->pbias, this->prelu_gmma5->pdata);
|
||||
|
||||
//conv6_1 score
|
||||
fullconnect(this->score_wb, this->fc5_out, this->score_);
|
||||
addbias(this->score_, this->score_wb->pbias);
|
||||
softmax(this->score_);
|
||||
// pBoxShow(this->score_);
|
||||
|
||||
//conv6_2 location
|
||||
fullconnect(this->location_wb, this->fc5_out, this->location_);
|
||||
addbias(this->location_, this->location_wb->pbias);
|
||||
// pBoxShow(location_);
|
||||
|
||||
//conv6_2 location
|
||||
fullconnect(this->keyPoint_wb, this->fc5_out, this->keyPoint_);
|
||||
addbias(this->keyPoint_, this->keyPoint_wb->pbias);
|
||||
// pBoxShow(keyPoint_);
|
||||
}
|
||||
|
||||
|
||||
mtcnn::mtcnn(int row, int col) {
|
||||
nms_threshold[0] = 0.7f;
|
||||
nms_threshold[1] = 0.7f;
|
||||
nms_threshold[2] = 0.7f;
|
||||
|
||||
//float minl = row>col?row:col;
|
||||
float minl = float(row > col ? col : row);
|
||||
int MIN_DET_SIZE = 12;
|
||||
int minsize = 20;
|
||||
float m = (float) MIN_DET_SIZE / minsize;
|
||||
minl *= m;
|
||||
float factor = 0.709f;
|
||||
int factor_count = 0;
|
||||
|
||||
while (minl > MIN_DET_SIZE) {
|
||||
if (factor_count > 0)m = m * factor;
|
||||
scales_.push_back(m);
|
||||
minl *= factor;
|
||||
factor_count++;
|
||||
}
|
||||
float minside = float(row < col ? row : col);
|
||||
int count = 0;
|
||||
for (vector<mydataFmt>::iterator it = scales_.begin(); it != scales_.end(); it++) {
|
||||
if (*it > 1) {
|
||||
cout << "the minsize is too small" << endl;
|
||||
while (1);
|
||||
}
|
||||
if (*it < (MIN_DET_SIZE / minside)) {
|
||||
scales_.resize(count);
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
simpleFace_ = new Pnet[scales_.size()];
|
||||
}
|
||||
|
||||
mtcnn::~mtcnn() {
|
||||
delete[]simpleFace_;
|
||||
}
|
||||
|
||||
void mtcnn::findFace(Mat &image) {
|
||||
struct orderScore order;
|
||||
int count = 0;
|
||||
if (image.empty())
|
||||
return;
|
||||
for (size_t i = 0; i < scales_.size(); i++) {
|
||||
int changedH = (int) ceil(image.rows * scales_.at(i));
|
||||
int changedW = (int) ceil(image.cols * scales_.at(i));
|
||||
resize(image, reImage, Size(changedW, changedH), 0, 0, cv::INTER_LINEAR);
|
||||
simpleFace_[i].run(reImage, scales_.at(i));
|
||||
nms(simpleFace_[i].boundingBox_, simpleFace_[i].bboxScore_, simpleFace_[i].nms_threshold, "Union");
|
||||
|
||||
for (vector<struct Bbox>::iterator it = simpleFace_[i].boundingBox_.begin();
|
||||
it != simpleFace_[i].boundingBox_.end(); it++) {
|
||||
if ((*it).exist) {
|
||||
firstBbox_.push_back(*it);
|
||||
order.score = (*it).score;
|
||||
order.oriOrder = count;
|
||||
firstOrderScore_.push_back(order);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
simpleFace_[i].bboxScore_.clear();
|
||||
simpleFace_[i].boundingBox_.clear();
|
||||
}
|
||||
//the first stage's nms
|
||||
printf("count1:%d\n", count);
|
||||
if (count < 1)return;
|
||||
nms(firstBbox_, firstOrderScore_, nms_threshold[0], "Union");
|
||||
refineAndSquareBbox(firstBbox_, image.rows, image.cols);
|
||||
|
||||
//second stage
|
||||
count = 0;
|
||||
for (vector<struct Bbox>::iterator it = firstBbox_.begin(); it != firstBbox_.end(); it++) {
|
||||
if ((*it).exist && ((*it).y1 < (*it).y2) && ((*it).x1 < (*it).x2)) {
|
||||
Rect temp((*it).y1, (*it).x1, (*it).y2 - (*it).y1, (*it).x2 - (*it).x1);
|
||||
Mat secImage;
|
||||
resize(image(temp), secImage, Size(24, 24), 0, 0, cv::INTER_LINEAR);
|
||||
refineNet.run(secImage);
|
||||
if (*(refineNet.score_->pdata + 1) > refineNet.Rthreshold) {
|
||||
memcpy(it->regreCoord, refineNet.location_->pdata, 4 * sizeof(mydataFmt));
|
||||
it->area = float((it->x2 - it->x1) * (it->y2 - it->y1));
|
||||
it->score = *(refineNet.score_->pdata + 1);
|
||||
secondBbox_.push_back(*it);
|
||||
order.score = it->score;
|
||||
order.oriOrder = count++;
|
||||
secondBboxScore_.push_back(order);
|
||||
} else {
|
||||
(*it).exist = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("count2:%d\n", count);
|
||||
if (count < 1)return;
|
||||
nms(secondBbox_, secondBboxScore_, nms_threshold[1], "Union");
|
||||
refineAndSquareBbox(secondBbox_, image.rows, image.cols);
|
||||
|
||||
//third stage
|
||||
count = 0;
|
||||
for (vector<struct Bbox>::iterator it = secondBbox_.begin(); it != secondBbox_.end(); it++) {
|
||||
//if ((*it).exist) {
|
||||
if ((*it).exist && ((*it).y1 < (*it).y2) && ((*it).x1 < (*it).x2)) {
|
||||
Rect temp((*it).y1, (*it).x1, (*it).y2 - (*it).y1, (*it).x2 - (*it).x1);
|
||||
Mat thirdImage;
|
||||
resize(image(temp), thirdImage, Size(48, 48), 0, 0, cv::INTER_LINEAR);
|
||||
outNet.run(thirdImage);
|
||||
mydataFmt *pp = NULL;
|
||||
//printf("%f\n", *(outNet.score_->pdata + 1));
|
||||
if (*(outNet.score_->pdata + 1) > outNet.Othreshold) {
|
||||
//if(true){
|
||||
memcpy(it->regreCoord, outNet.location_->pdata, 4 * sizeof(mydataFmt));
|
||||
it->area = float((it->x2 - it->x1) * (it->y2 - it->y1));
|
||||
it->score = *(outNet.score_->pdata + 1);
|
||||
pp = outNet.keyPoint_->pdata;
|
||||
for (int num = 0; num < 5; num++) {
|
||||
(it->ppoint)[num] = it->y1 + (it->y2 - it->y1) * (*(pp + num));
|
||||
(it->ppoint)[num + 5] = it->x1 + (it->x2 - it->x1) * (*(pp + num + 5));
|
||||
}
|
||||
thirdBbox_.push_back(*it);
|
||||
order.score = it->score;
|
||||
order.oriOrder = count++;
|
||||
thirdBboxScore_.push_back(order);
|
||||
} else {
|
||||
it->exist = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("count3:%d\n", count);
|
||||
if (count < 1)return;
|
||||
refineAndSquareBbox(thirdBbox_, image.rows, image.cols);
|
||||
nms(thirdBbox_, thirdBboxScore_, nms_threshold[2], "Min");
|
||||
int num = 0;
|
||||
int saveflag = 2;//0 预处理 1 预测识别 2 单独运行
|
||||
for (vector<struct Bbox>::iterator it = thirdBbox_.begin(); it != thirdBbox_.end(); it++) {
|
||||
if ((*it).exist && ((*it).y1 < (*it).y2) && ((*it).x1 < (*it).x2)) {
|
||||
if (saveflag == 0) {
|
||||
Rect temp((*it).y1, (*it).x1, (*it).y2 - (*it).y1, (*it).x2 - (*it).x1);
|
||||
Mat fourthImage;
|
||||
resize(image(temp), fourthImage, Size(299, 299), 0, 0, cv::INTER_LINEAR);
|
||||
facenet ggg;
|
||||
mydataFmt *o = new mydataFmt[Num];
|
||||
ggg.run(fourthImage, o, num);
|
||||
imshow("result", fourthImage);
|
||||
imwrite("../emb_img/" + to_string(num) + ".jpg", fourthImage);
|
||||
waitKey(3000);
|
||||
|
||||
destroyWindow("result");
|
||||
fourthImage.release();
|
||||
|
||||
ofstream outFile;
|
||||
outFile.open("../emb_csv/" + to_string(num) + ".csv", ios::out); // 打开模式可省略
|
||||
for (int l = 0; l < Num; ++l) {
|
||||
// cout << o[l] << endl;
|
||||
if (l == Num - 1) {
|
||||
outFile << o[l];
|
||||
} else {
|
||||
outFile << o[l] << ',';
|
||||
}
|
||||
}
|
||||
outFile << endl;
|
||||
outFile.close();
|
||||
delete o;
|
||||
} else if (saveflag == 1) {
|
||||
Rect temp((*it).y1, (*it).x1, (*it).y2 - (*it).y1, (*it).x2 - (*it).x1);
|
||||
Mat fourthImage;
|
||||
resize(image(temp), fourthImage, Size(299, 299), 0, 0, cv::INTER_LINEAR);
|
||||
facenet ggg;
|
||||
mydataFmt *o = new mydataFmt[Num];
|
||||
ggg.run(fourthImage, o, num);
|
||||
imshow("result", fourthImage);
|
||||
waitKey(3000);
|
||||
destroyWindow("result");
|
||||
|
||||
ifstream inFile("../emb_csv/" + to_string(num) + ".csv", ios::in);
|
||||
string lineStr;
|
||||
// vector<vector<mydataFmt>> strArray;
|
||||
vector<mydataFmt> lineArray;
|
||||
while (getline(inFile, lineStr)) {
|
||||
// 打印整行字符串
|
||||
// cout << lineStr << endl;
|
||||
// 存成二维表结构
|
||||
stringstream ss(lineStr);
|
||||
string str;
|
||||
// vector<mydataFmt> lineArray;
|
||||
// 按照逗号分隔
|
||||
// mydataFmt nnn = 0;
|
||||
while (getline(ss, str, ',')) {
|
||||
lineArray.push_back(atof(str.c_str()));
|
||||
// cout << str << endl;
|
||||
}
|
||||
// strArray.push_back(lineArray);
|
||||
}
|
||||
mydataFmt sum = 0;
|
||||
for (int i = 0; i < Num; ++i) {
|
||||
cout << o[i] << "===" << lineArray[i] << endl;
|
||||
mydataFmt sub = o[i] - lineArray[i];
|
||||
mydataFmt square = pow(sub, 2);
|
||||
sum += square;
|
||||
}
|
||||
mydataFmt result = sqrt(sum);
|
||||
cout << result << endl;
|
||||
if (result < 0.85)
|
||||
cout << "it's me" << endl;
|
||||
else
|
||||
cout << "unknow" << endl;
|
||||
delete o;
|
||||
}
|
||||
num++;
|
||||
// }
|
||||
// if ((*it).exist) {
|
||||
rectangle(image, Point((*it).y1, (*it).x1), Point((*it).y2, (*it).x2), Scalar(0, 0, 255), 2, 8, 0);
|
||||
for (int num = 0; num < 5; num++)
|
||||
circle(image, Point((int) *(it->ppoint + num), (int) *(it->ppoint + num + 5)), 2, Scalar(0, 255, 255),
|
||||
-1);
|
||||
}
|
||||
}
|
||||
|
||||
firstBbox_.clear();
|
||||
firstOrderScore_.clear();
|
||||
secondBbox_.clear();
|
||||
secondBboxScore_.clear();
|
||||
thirdBbox_.clear();
|
||||
thirdBboxScore_.clear();
|
||||
}
|
||||
156
src/mtcnn.h
Executable file
156
src/mtcnn.h
Executable file
@@ -0,0 +1,156 @@
|
||||
#ifndef MTCNN_H
|
||||
#define MTCNN_H
|
||||
|
||||
#include "network.h"
|
||||
#include "facenet.h"
|
||||
|
||||
class Pnet {
|
||||
public:
|
||||
Pnet();
|
||||
|
||||
~Pnet();
|
||||
|
||||
void run(Mat &image, mydataFmt scale);
|
||||
|
||||
float nms_threshold;
|
||||
mydataFmt Pthreshold;
|
||||
bool firstFlag;
|
||||
vector<struct Bbox> boundingBox_;
|
||||
vector<orderScore> bboxScore_;
|
||||
private:
|
||||
//the image for mxnet conv
|
||||
struct pBox *rgb;
|
||||
//the 1th layer's out conv
|
||||
struct pBox *conv1;
|
||||
struct pBox *maxPooling1;
|
||||
//the 3th layer's out
|
||||
struct pBox *conv2;
|
||||
//the 4th layer's out out
|
||||
struct pBox *conv3;
|
||||
//the 4th layer's out out
|
||||
struct pBox *score_;
|
||||
//the 4th layer's out out
|
||||
struct pBox *location_;
|
||||
|
||||
//Weight
|
||||
struct Weight *conv1_wb;
|
||||
struct pRelu *prelu_gmma1;
|
||||
struct Weight *conv2_wb;
|
||||
struct pRelu *prelu_gmma2;
|
||||
struct Weight *conv3_wb;
|
||||
struct pRelu *prelu_gmma3;
|
||||
struct Weight *conv4c1_wb;
|
||||
struct Weight *conv4c2_wb;
|
||||
|
||||
void generateBbox(const struct pBox *score, const struct pBox *location, mydataFmt scale);
|
||||
};
|
||||
|
||||
class Rnet {
|
||||
public:
|
||||
Rnet();
|
||||
|
||||
~Rnet();
|
||||
|
||||
float Rthreshold;
|
||||
|
||||
void run(Mat &image);
|
||||
|
||||
struct pBox *score_;
|
||||
struct pBox *location_;
|
||||
private:
|
||||
struct pBox *rgb;
|
||||
|
||||
struct pBox *conv1_out;
|
||||
struct pBox *pooling1_out;
|
||||
|
||||
struct pBox *conv2_out;
|
||||
struct pBox *pooling2_out;
|
||||
|
||||
struct pBox *conv3_out;
|
||||
|
||||
struct pBox *fc4_out;
|
||||
|
||||
//Weight
|
||||
struct Weight *conv1_wb;
|
||||
struct pRelu *prelu_gmma1;
|
||||
struct Weight *conv2_wb;
|
||||
struct pRelu *prelu_gmma2;
|
||||
struct Weight *conv3_wb;
|
||||
struct pRelu *prelu_gmma3;
|
||||
struct Weight *fc4_wb;
|
||||
struct pRelu *prelu_gmma4;
|
||||
struct Weight *score_wb;
|
||||
struct Weight *location_wb;
|
||||
|
||||
void RnetImage2MatrixInit(struct pBox *pbox);
|
||||
};
|
||||
|
||||
class Onet {
|
||||
public:
|
||||
Onet();
|
||||
|
||||
~Onet();
|
||||
|
||||
void run(Mat &image);
|
||||
|
||||
float Othreshold;
|
||||
struct pBox *score_;
|
||||
struct pBox *location_;
|
||||
struct pBox *keyPoint_;
|
||||
private:
|
||||
struct pBox *rgb;
|
||||
struct pBox *conv1_out;
|
||||
struct pBox *pooling1_out;
|
||||
|
||||
struct pBox *conv2_out;
|
||||
struct pBox *pooling2_out;
|
||||
|
||||
struct pBox *conv3_out;
|
||||
struct pBox *pooling3_out;
|
||||
|
||||
struct pBox *conv4_out;
|
||||
|
||||
struct pBox *fc5_out;
|
||||
|
||||
//Weight
|
||||
struct Weight *conv1_wb;
|
||||
struct pRelu *prelu_gmma1;
|
||||
struct Weight *conv2_wb;
|
||||
struct pRelu *prelu_gmma2;
|
||||
struct Weight *conv3_wb;
|
||||
struct pRelu *prelu_gmma3;
|
||||
struct Weight *conv4_wb;
|
||||
struct pRelu *prelu_gmma4;
|
||||
struct Weight *fc5_wb;
|
||||
struct pRelu *prelu_gmma5;
|
||||
struct Weight *score_wb;
|
||||
struct Weight *location_wb;
|
||||
struct Weight *keyPoint_wb;
|
||||
|
||||
void OnetImage2MatrixInit(struct pBox *pbox);
|
||||
};
|
||||
|
||||
class mtcnn {
|
||||
public:
|
||||
mtcnn(int row, int col);
|
||||
|
||||
~mtcnn();
|
||||
|
||||
void findFace(Mat &image);
|
||||
|
||||
private:
|
||||
Mat reImage;
|
||||
mydataFmt nms_threshold[3];
|
||||
vector<mydataFmt> scales_;
|
||||
Pnet *simpleFace_;
|
||||
vector<struct Bbox> firstBbox_;
|
||||
vector<struct orderScore> firstOrderScore_;
|
||||
Rnet refineNet;
|
||||
vector<struct Bbox> secondBbox_;
|
||||
vector<struct orderScore> secondBboxScore_;
|
||||
Onet outNet;
|
||||
vector<struct Bbox> thirdBbox_;
|
||||
vector<struct orderScore> thirdBboxScore_;
|
||||
};
|
||||
|
||||
#endif
|
||||
704
src/network.cpp
Executable file
704
src/network.cpp
Executable file
@@ -0,0 +1,704 @@
|
||||
#include "network.h"
|
||||
|
||||
void addbias(struct pBox *pbox, mydataFmt *pbias) {
|
||||
if (pbox->pdata == NULL) {
|
||||
cout << "Relu feature is NULL!!" << endl;
|
||||
return;
|
||||
}
|
||||
if (pbias == NULL) {
|
||||
cout << "the Relu bias is NULL!!" << endl;
|
||||
return;
|
||||
}
|
||||
mydataFmt *op = pbox->pdata;
|
||||
mydataFmt *pb = pbias;
|
||||
|
||||
long dis = pbox->width * pbox->height;
|
||||
for (int channel = 0; channel < pbox->channel; channel++) {
|
||||
for (int col = 0; col < dis; col++) {
|
||||
*op = *op + *pb;
|
||||
op++;
|
||||
}
|
||||
pb++;
|
||||
}
|
||||
}
|
||||
|
||||
void image2MatrixInit(Mat &image, struct pBox *pbox) {
|
||||
if ((image.data == NULL) || (image.type() != CV_8UC3)) {
|
||||
cout << "image's type is wrong!!Please set CV_8UC3" << endl;
|
||||
return;
|
||||
}
|
||||
pbox->channel = image.channels();
|
||||
pbox->height = image.rows;
|
||||
pbox->width = image.cols;
|
||||
|
||||
pbox->pdata = (mydataFmt *) malloc(pbox->channel * pbox->height * pbox->width * sizeof(mydataFmt));
|
||||
if (pbox->pdata == NULL)cout << "the image2MatrixInit failed!!" << endl;
|
||||
memset(pbox->pdata, 0, pbox->channel * pbox->height * pbox->width * sizeof(mydataFmt));
|
||||
}
|
||||
|
||||
void image2Matrix(const Mat &image, const struct pBox *pbox, int num) {
|
||||
if ((image.data == NULL) || (image.type() != CV_8UC3)) {
|
||||
cout << "image's type is wrong!!Please set CV_8UC3" << endl;
|
||||
return;
|
||||
}
|
||||
if (pbox->pdata == NULL) {
|
||||
return;
|
||||
}
|
||||
mydataFmt *p = pbox->pdata;
|
||||
double sqr, stddev_adj;
|
||||
int size;
|
||||
mydataFmt mymean, mystddev;
|
||||
// prewhiten
|
||||
if (num != 0) {
|
||||
meanAndDev(image, &mymean, &mystddev);
|
||||
cout << mymean << "----" << mystddev << endl;
|
||||
size = image.cols * image.rows * image.channels();
|
||||
sqr = sqrt(double(size));
|
||||
if (mystddev >= 1.0 / sqr) {
|
||||
stddev_adj = mystddev;
|
||||
} else {
|
||||
stddev_adj = 1.0 / sqr;
|
||||
}
|
||||
}
|
||||
for (int rowI = 0; rowI < image.rows; rowI++) {
|
||||
for (int colK = 0; colK < image.cols; colK++) {
|
||||
if (num == 0) {
|
||||
*p = (image.at<Vec3b>(rowI, colK)[2] - 127.5) * 0.0078125;
|
||||
*(p + image.rows * image.cols) = (image.at<Vec3b>(rowI, colK)[1] - 127.5) * 0.0078125;
|
||||
*(p + 2 * image.rows * image.cols) = (image.at<Vec3b>(rowI, colK)[0] - 127.5) * 0.0078125;
|
||||
p++;
|
||||
} else {
|
||||
// brg2rgb
|
||||
*(p + 0 * image.rows * image.cols) = (image.at<Vec3b>(rowI, colK)[2] - mymean) / stddev_adj;
|
||||
*(p + 1 * image.rows * image.cols) = (image.at<Vec3b>(rowI, colK)[1] - mymean) / stddev_adj;
|
||||
*(p + 2 * image.rows * image.cols) = (image.at<Vec3b>(rowI, colK)[0] - mymean) / stddev_adj;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void meanAndDev(const Mat &image, mydataFmt *p, mydataFmt *q) {
|
||||
mydataFmt meansum = 0, stdsum = 0;
|
||||
for (int rowI = 0; rowI < image.rows; rowI++) {
|
||||
for (int colK = 0; colK < image.cols; colK++) {
|
||||
meansum += image.at<Vec3b>(rowI, colK)[0] + image.at<Vec3b>(rowI, colK)[1] + image.at<Vec3b>(rowI, colK)[2];
|
||||
// cout << int(image.at<Vec3b>(rowI, colK)[0]) << endl;
|
||||
// cout << int(image.at<Vec3b>(rowI, colK)[1]) << endl;
|
||||
// cout << int(image.at<Vec3b>(rowI, colK)[2]) << endl;
|
||||
}
|
||||
}
|
||||
*p = meansum / (image.cols * image.rows * image.channels());
|
||||
for (int rowI = 0; rowI < image.rows; rowI++) {
|
||||
for (int colK = 0; colK < image.cols; colK++) {
|
||||
stdsum += pow((image.at<Vec3b>(rowI, colK)[0] - *p), 2) +
|
||||
pow((image.at<Vec3b>(rowI, colK)[1] - *p), 2) +
|
||||
pow((image.at<Vec3b>(rowI, colK)[2] - *p), 2);
|
||||
}
|
||||
}
|
||||
*q = sqrt(stdsum / (image.cols * image.rows * image.channels()));
|
||||
}
|
||||
|
||||
void featurePadInit(const pBox *pbox, pBox *outpBox, const int pad, const int padw, const int padh) {
|
||||
if (pad < -1) {
|
||||
cout << "the data needn't to pad,please check you network!" << endl;
|
||||
return;
|
||||
}
|
||||
outpBox->channel = pbox->channel;
|
||||
if (pad == -1) {
|
||||
outpBox->height = pbox->height + 2 * padh;
|
||||
outpBox->width = pbox->width + 2 * padw;
|
||||
} else {
|
||||
outpBox->height = pbox->height + 2 * pad;
|
||||
outpBox->width = pbox->width + 2 * pad;
|
||||
}
|
||||
long RowByteNum = outpBox->width * sizeof(mydataFmt);
|
||||
outpBox->pdata = (mydataFmt *) malloc(outpBox->channel * outpBox->height * RowByteNum);
|
||||
if (outpBox->pdata == NULL)cout << "the featurePadInit is failed!!" << endl;
|
||||
memset(outpBox->pdata, 0, outpBox->channel * outpBox->height * RowByteNum);
|
||||
}
|
||||
|
||||
void featurePad(const pBox *pbox, pBox *outpBox, const int pad, const int padw, const int padh) {
|
||||
mydataFmt *p = outpBox->pdata;
|
||||
mydataFmt *pIn = pbox->pdata;
|
||||
if (pad == -1) {
|
||||
for (int row = 0; row < outpBox->channel * outpBox->height; row++) {
|
||||
if ((row % outpBox->height) < padh || (row % outpBox->height > (outpBox->height - padh - 1))) {
|
||||
p += outpBox->width;
|
||||
continue;
|
||||
}
|
||||
p += padw;
|
||||
memcpy(p, pIn, pbox->width * sizeof(mydataFmt));
|
||||
p += pbox->width + padw;
|
||||
pIn += pbox->width;
|
||||
}
|
||||
} else {
|
||||
for (int row = 0; row < outpBox->channel * outpBox->height; row++) {
|
||||
if ((row % outpBox->height) < pad || (row % outpBox->height > (outpBox->height - pad - 1))) {
|
||||
p += outpBox->width;
|
||||
continue;
|
||||
}
|
||||
p += pad;
|
||||
memcpy(p, pIn, pbox->width * sizeof(mydataFmt));
|
||||
p += pbox->width + pad;
|
||||
pIn += pbox->width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void convolutionInit(const Weight *weight, pBox *pbox, pBox *outpBox) {
|
||||
outpBox->channel = weight->selfChannel;
|
||||
// ((imginputh - ckh + 2 * ckpad) / stride) + 1;
|
||||
if (weight->kernelSize == 0) {
|
||||
outpBox->width = ((pbox->width - weight->w + 2 * weight->padw) / weight->stride) + 1;
|
||||
// outpBox->width = (pbox->width - weight->w) / weight->stride + 1;
|
||||
// outpBox->height = (pbox->height - weight->h) / weight->stride + 1;
|
||||
outpBox->height = (pbox->height - weight->h + 2 * weight->padh) / weight->stride + 1;
|
||||
} else {
|
||||
outpBox->width = ((pbox->width - weight->kernelSize + 2 * weight->pad) / weight->stride) + 1;
|
||||
outpBox->height = ((pbox->height - weight->kernelSize + 2 * weight->pad) / weight->stride) + 1;
|
||||
}
|
||||
// cout << outpBox->pdata << endl;
|
||||
outpBox->pdata = (mydataFmt *) malloc(outpBox->width * outpBox->height * outpBox->channel * sizeof(mydataFmt));
|
||||
// cout << outpBox->pdata << endl;
|
||||
if (outpBox->pdata == NULL)cout << "the convolutionInit is failed!!" << endl;
|
||||
memset(outpBox->pdata, 0, outpBox->width * outpBox->height * outpBox->channel * sizeof(mydataFmt));
|
||||
if (weight->pad != 0) {
|
||||
pBox *padpbox = new pBox;
|
||||
featurePadInit(pbox, padpbox, weight->pad, weight->padw, weight->padh);
|
||||
featurePad(pbox, padpbox, weight->pad, weight->padw, weight->padh);
|
||||
*pbox = *padpbox;
|
||||
}
|
||||
}
|
||||
|
||||
void convolution(const Weight *weight, const pBox *pbox, pBox *outpBox) {
|
||||
// if (weight->pad != 0) {
|
||||
// pBox *padpbox = new pBox;
|
||||
// featurePadInit(outpBox, padpbox, weight->pad, weight->padw, weight->padh);
|
||||
// featurePad(outpBox, padpbox, weight->pad, weight->padw, weight->padh);
|
||||
// *outpBox = *padpbox;
|
||||
// }
|
||||
int ckh, ckw, ckd, stride, cknum, ckpad, imginputh, imginputw, imginputd, Nh, Nw;
|
||||
mydataFmt *ck, *imginput;
|
||||
// float *output = outpBox->pdata;
|
||||
float temp;
|
||||
ck = weight->pdata;
|
||||
if (weight->kernelSize == 0) {
|
||||
ckh = weight->h;
|
||||
ckw = weight->w;
|
||||
} else {
|
||||
ckh = weight->kernelSize;
|
||||
ckw = weight->kernelSize;
|
||||
}
|
||||
ckd = weight->lastChannel;
|
||||
cknum = weight->selfChannel;
|
||||
ckpad = weight->pad;
|
||||
stride = weight->stride;
|
||||
imginput = pbox->pdata;
|
||||
imginputh = pbox->height;
|
||||
imginputw = pbox->width;
|
||||
imginputd = pbox->channel;
|
||||
Nh = outpBox->height;
|
||||
Nw = outpBox->width;
|
||||
// Nh = ((imginputh - ckh + 2 * ckpad) / stride) + 1;
|
||||
// Nw = ((imginputw - ckw + 2 * ckpad) / stride) + 1;
|
||||
for (int i = 0; i < cknum; ++i) {
|
||||
for (int j = 0; j < Nh; j++) {
|
||||
for (int k = 0; k < Nw; k++) {
|
||||
temp = 0;
|
||||
|
||||
for (int m = 0; m < ckd; ++m) {
|
||||
for (int n = 0; n < ckh; ++n) {
|
||||
for (int i1 = 0; i1 < ckw; ++i1) {
|
||||
temp += imginput[(j * stride + n) * imginputw
|
||||
+ (k * stride + i1)
|
||||
+ m * imginputh * imginputw]
|
||||
* ck[i * ckh * ckw * ckd + m * ckh * ckw + n * ckw + i1];
|
||||
// cout << "(" << imginput[(j * stride + n) * imginputw
|
||||
// + (k * stride + i1)
|
||||
// + m * imginputh * imginputw] << ")x("
|
||||
// << ck[i * ckh * ckw * ckd + m * ckh * ckw + n * ckw + i1] << ")="
|
||||
// << imginput[(j * stride + n) * imginputw
|
||||
// + (k * stride + i1)
|
||||
// + m * imginputh * imginputw]
|
||||
// * ck[i * ckh * ckw * ckd + m * ckh * ckw + n * ckw + i1] << endl;
|
||||
// cout << temp << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
//按照顺序存储
|
||||
outpBox->pdata[i * outpBox->height * outpBox->width + j * outpBox->width + k] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
// cout << "output->pdata:" << (outpBox->pdata[10]) << endl;
|
||||
}
|
||||
|
||||
void maxPoolingInit(const pBox *pbox, pBox *Matrix, int kernelSize, int stride, int flag) {
|
||||
if (flag == 1) {
|
||||
Matrix->width = floor((float) (pbox->width - kernelSize) / stride + 1);
|
||||
Matrix->height = floor((float) (pbox->height - kernelSize) / stride + 1);
|
||||
} else {
|
||||
Matrix->width = ceil((float) (pbox->width - kernelSize) / stride + 1);
|
||||
Matrix->height = ceil((float) (pbox->height - kernelSize) / stride + 1);
|
||||
}
|
||||
Matrix->channel = pbox->channel;
|
||||
Matrix->pdata = (mydataFmt *) malloc(Matrix->channel * Matrix->width * Matrix->height * sizeof(mydataFmt));
|
||||
if (Matrix->pdata == NULL)cout << "the maxPoolingI nit is failed!!" << endl;
|
||||
memset(Matrix->pdata, 0, Matrix->channel * Matrix->width * Matrix->height * sizeof(mydataFmt));
|
||||
}
|
||||
|
||||
void maxPooling(const pBox *pbox, pBox *Matrix, int kernelSize, int stride) {
|
||||
if (pbox->pdata == NULL) {
|
||||
cout << "the feature2Matrix pbox is NULL!!" << endl;
|
||||
return;
|
||||
}
|
||||
mydataFmt *p = Matrix->pdata;
|
||||
mydataFmt *pIn;
|
||||
mydataFmt *ptemp;
|
||||
mydataFmt maxNum = 0;
|
||||
if ((pbox->width - kernelSize) % stride == 0 && (pbox->height - kernelSize) % stride == 0) {
|
||||
for (int row = 0; row < Matrix->height; row++) {
|
||||
for (int col = 0; col < Matrix->width; col++) {
|
||||
pIn = pbox->pdata + row * stride * pbox->width + col * stride;
|
||||
for (int channel = 0; channel < pbox->channel; channel++) {
|
||||
ptemp = pIn + channel * pbox->height * pbox->width;
|
||||
maxNum = *ptemp;
|
||||
for (int kernelRow = 0; kernelRow < kernelSize; kernelRow++) {
|
||||
for (int i = 0; i < kernelSize; i++) {
|
||||
if (maxNum < *(ptemp + i + kernelRow * pbox->width))
|
||||
maxNum = *(ptemp + i + kernelRow * pbox->width);
|
||||
}
|
||||
}
|
||||
*(p + channel * Matrix->height * Matrix->width) = maxNum;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int diffh = 0, diffw = 0;
|
||||
for (int channel = 0; channel < pbox->channel; channel++) {
|
||||
pIn = pbox->pdata + channel * pbox->height * pbox->width;
|
||||
for (int row = 0; row < Matrix->height; row++) {
|
||||
for (int col = 0; col < Matrix->width; col++) {
|
||||
ptemp = pIn + row * stride * pbox->width + col * stride;
|
||||
maxNum = *ptemp;
|
||||
diffh = row * stride - pbox->height + 1;
|
||||
diffw = col * stride - pbox->width + 1;
|
||||
for (int kernelRow = 0; kernelRow < kernelSize; kernelRow++) {
|
||||
if ((kernelRow + diffh) > 0)break;
|
||||
for (int i = 0; i < kernelSize; i++) {
|
||||
if ((i + diffw) > 0)break;
|
||||
if (maxNum < *(ptemp + i + kernelRow * pbox->width))
|
||||
maxNum = *(ptemp + i + kernelRow * pbox->width);
|
||||
}
|
||||
}
|
||||
*p++ = maxNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void avePoolingInit(const pBox *pbox, pBox *Matrix, int kernelSize, int stride) {
|
||||
Matrix->width = ceil((float) (pbox->width - kernelSize) / stride + 1);
|
||||
Matrix->height = ceil((float) (pbox->height - kernelSize) / stride + 1);
|
||||
Matrix->channel = pbox->channel;
|
||||
Matrix->pdata = (mydataFmt *) malloc(Matrix->channel * Matrix->width * Matrix->height * sizeof(mydataFmt));
|
||||
if (Matrix->pdata == NULL)cout << "the maxPoolingInit is failed!!" << endl;
|
||||
memset(Matrix->pdata, 0, Matrix->channel * Matrix->width * Matrix->height * sizeof(mydataFmt));
|
||||
}
|
||||
|
||||
void avePooling(const pBox *pbox, pBox *Matrix, int kernelSize, int stride) {
|
||||
if (pbox->pdata == NULL) {
|
||||
cout << "the feature2Matrix pbox is NULL!!" << endl;
|
||||
return;
|
||||
}
|
||||
mydataFmt *p = Matrix->pdata;
|
||||
mydataFmt *pIn;
|
||||
mydataFmt *ptemp;
|
||||
mydataFmt sumNum = 0;
|
||||
if ((pbox->width - kernelSize) % stride == 0 && (pbox->height - kernelSize) % stride == 0) {
|
||||
for (int row = 0; row < Matrix->height; row++) {
|
||||
for (int col = 0; col < Matrix->width; col++) {
|
||||
pIn = pbox->pdata + row * stride * pbox->width + col * stride;
|
||||
|
||||
for (int channel = 0; channel < pbox->channel; channel++) {
|
||||
|
||||
ptemp = pIn + channel * pbox->height * pbox->width;
|
||||
sumNum = 0;
|
||||
for (int kernelRow = 0; kernelRow < kernelSize; kernelRow++) {
|
||||
for (int i = 0; i < kernelSize; i++) {
|
||||
sumNum += *(ptemp + i + kernelRow * pbox->width);
|
||||
}
|
||||
}
|
||||
*(p + channel * Matrix->height * Matrix->width) = sumNum / (kernelSize * kernelSize);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void prelu(struct pBox *pbox, mydataFmt *pbias, mydataFmt *prelu_gmma) {
|
||||
if (pbox->pdata == NULL) {
|
||||
cout << "the pRelu feature is NULL!!" << endl;
|
||||
return;
|
||||
}
|
||||
if (pbias == NULL) {
|
||||
cout << "the pRelu bias is NULL!!" << endl;
|
||||
return;
|
||||
}
|
||||
mydataFmt *op = pbox->pdata;
|
||||
mydataFmt *pb = pbias;
|
||||
mydataFmt *pg = prelu_gmma;
|
||||
|
||||
long dis = pbox->width * pbox->height;
|
||||
for (int channel = 0; channel < pbox->channel; channel++) {
|
||||
for (int col = 0; col < dis; col++) {
|
||||
*op = *op + *pb;
|
||||
*op = (*op > 0) ? (*op) : ((*op) * (*pg));
|
||||
op++;
|
||||
}
|
||||
pb++;
|
||||
pg++;
|
||||
}
|
||||
}
|
||||
|
||||
void relu(struct pBox *pbox, mydataFmt *pbias) {
|
||||
if (pbox->pdata == NULL) {
|
||||
cout << "the Relu feature is NULL!!" << endl;
|
||||
return;
|
||||
}
|
||||
if (pbias == NULL) {
|
||||
cout << "the Relu bias is NULL!!" << endl;
|
||||
return;
|
||||
}
|
||||
mydataFmt *op = pbox->pdata;
|
||||
mydataFmt *pb = pbias;
|
||||
|
||||
long dis = pbox->width * pbox->height;
|
||||
for (int channel = 0; channel < pbox->channel; channel++) {
|
||||
for (int col = 0; col < dis; col++) {
|
||||
*op = *op + *pb;
|
||||
*op = (*op > 0) ? (*op) : ((*op) * 0);
|
||||
op++;
|
||||
}
|
||||
pb++;
|
||||
}
|
||||
}
|
||||
|
||||
void fullconnectInit(const Weight *weight, pBox *outpBox) {
|
||||
outpBox->channel = weight->selfChannel;
|
||||
outpBox->width = 1;
|
||||
outpBox->height = 1;
|
||||
outpBox->pdata = (mydataFmt *) malloc(weight->selfChannel * sizeof(mydataFmt));
|
||||
if (outpBox->pdata == NULL)cout << "the fullconnectInit is failed!!" << endl;
|
||||
memset(outpBox->pdata, 0, weight->selfChannel * sizeof(mydataFmt));
|
||||
}
|
||||
|
||||
void fullconnect(const Weight *weight, const pBox *pbox, pBox *outpBox) {
|
||||
if (pbox->pdata == NULL) {
|
||||
cout << "the fc feature is NULL!!" << endl;
|
||||
return;
|
||||
}
|
||||
if (weight->pdata == NULL) {
|
||||
cout << "the fc weight is NULL!!" << endl;
|
||||
return;
|
||||
}
|
||||
memset(outpBox->pdata, 0, weight->selfChannel * sizeof(mydataFmt));
|
||||
//Y←αAX + βY β must be 0(zero)
|
||||
// row no trans A's row A'col
|
||||
//cblas_sgemv(CblasRowMajor, CblasNoTrans, weight->selfChannel, weight->lastChannel, 1, weight->pdata, weight->lastChannel, pbox->pdata, 1, 0, outpBox->pdata, 1);
|
||||
vectorXmatrix(pbox->pdata, weight->pdata,
|
||||
pbox->width * pbox->height * pbox->channel,
|
||||
weight->lastChannel, weight->selfChannel,
|
||||
outpBox->pdata);
|
||||
}
|
||||
|
||||
void vectorXmatrix(mydataFmt *matrix, mydataFmt *v, int size, int v_w, int v_h, mydataFmt *p) {
|
||||
for (int i = 0; i < v_h; i++) {
|
||||
p[i] = 0;
|
||||
for (int j = 0; j < v_w; j++) {
|
||||
p[i] += matrix[j] * v[i * v_w + j];
|
||||
// cout << p[i] << endl;
|
||||
}
|
||||
// cout << p[i] << endl;
|
||||
// p[i] = -0.0735729;
|
||||
// cout << "...." << endl;
|
||||
// break;
|
||||
}
|
||||
// cout << "...." << endl;
|
||||
}
|
||||
|
||||
void readData(string filename, long dataNumber[], mydataFmt *pTeam[], int length) {
|
||||
ifstream in(filename.data());
|
||||
string line;
|
||||
long temp = dataNumber[0];
|
||||
if (in) {
|
||||
int i = 0;
|
||||
int count = 0;
|
||||
int pos = 0;
|
||||
while (getline(in, line)) {
|
||||
try {
|
||||
if (i < temp) {
|
||||
line.erase(0, 1);
|
||||
pos = line.find(']');
|
||||
line.erase(pos, 1);
|
||||
pos = line.find('\r');
|
||||
if (pos != -1) {
|
||||
line.erase(pos, 1);
|
||||
}
|
||||
if (dataNumber[count] != 0) {
|
||||
*(pTeam[count])++ = atof(line.data());
|
||||
}
|
||||
} else {
|
||||
count++;
|
||||
if ((length != 0) && (count == length))
|
||||
break;
|
||||
temp += dataNumber[count];
|
||||
line.erase(0, 1);
|
||||
pos = line.find(']');
|
||||
line.erase(pos, 1);
|
||||
pos = line.find('\r');
|
||||
if (pos != -1) {
|
||||
line.erase(pos, 1);
|
||||
}
|
||||
if (dataNumber[count] != 0) {
|
||||
*(pTeam[count])++ = atof(line.data());
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
catch (exception &e) {
|
||||
cout << " error " << i << endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cout << "no such file" << filename << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// w sc lc ks s p kw kh
|
||||
long initConvAndFc(struct Weight *weight, int schannel, int lchannel, int kersize,
|
||||
int stride, int pad, int w, int h, int padw, int padh) {
|
||||
weight->selfChannel = schannel;
|
||||
weight->lastChannel = lchannel;
|
||||
weight->kernelSize = kersize;
|
||||
// if (kersize == 0) {
|
||||
weight->h = h;
|
||||
weight->w = w;
|
||||
// }
|
||||
// if (pad == -1) {
|
||||
weight->padh = padh;
|
||||
weight->padw = padw;
|
||||
// }
|
||||
weight->stride = stride;
|
||||
weight->pad = pad;
|
||||
weight->pbias = (mydataFmt *) malloc(schannel * sizeof(mydataFmt));
|
||||
if (weight->pbias == NULL)cout << "Memory request not successful!!!";
|
||||
memset(weight->pbias, 0, schannel * sizeof(mydataFmt));
|
||||
long byteLenght;
|
||||
if (kersize == 0) {
|
||||
byteLenght = weight->selfChannel * weight->lastChannel * weight->h * weight->w;
|
||||
} else {
|
||||
byteLenght = weight->selfChannel * weight->lastChannel * weight->kernelSize * weight->kernelSize;
|
||||
}
|
||||
weight->pdata = (mydataFmt *) malloc(byteLenght * sizeof(mydataFmt));
|
||||
if (weight->pdata == NULL)cout << "Memory request not successful!!!";
|
||||
memset(weight->pdata, 0, byteLenght * sizeof(mydataFmt));
|
||||
return byteLenght;
|
||||
}
|
||||
|
||||
void initpRelu(struct pRelu *prelu, int width) {
|
||||
prelu->width = width;
|
||||
prelu->pdata = (mydataFmt *) malloc(width * sizeof(mydataFmt));
|
||||
if (prelu->pdata == NULL)cout << "prelu apply for memory failed!!!!";
|
||||
memset(prelu->pdata, 0, width * sizeof(mydataFmt));
|
||||
}
|
||||
|
||||
void softmax(const struct pBox *pbox) {
|
||||
if (pbox->pdata == NULL) {
|
||||
cout << "the softmax's pdata is NULL , Please check !" << endl;
|
||||
return;
|
||||
}
|
||||
mydataFmt *p2D = pbox->pdata;
|
||||
mydataFmt *p3D = NULL;
|
||||
long mapSize = pbox->width * pbox->height;
|
||||
mydataFmt eleSum = 0;
|
||||
for (int row = 0; row < pbox->height; row++) {
|
||||
for (int col = 0; col < pbox->width; col++) {
|
||||
eleSum = 0;
|
||||
for (int channel = 0; channel < pbox->channel; channel++) {
|
||||
p3D = p2D + channel * mapSize;
|
||||
*p3D = exp(*p3D);
|
||||
eleSum += *p3D;
|
||||
}
|
||||
for (int channel = 0; channel < pbox->channel; channel++) {
|
||||
p3D = p2D + channel * mapSize;
|
||||
*p3D = (*p3D) / eleSum;
|
||||
}
|
||||
p2D++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool cmpScore(struct orderScore lsh, struct orderScore rsh) {
|
||||
if (lsh.score < rsh.score)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void nms(vector<struct Bbox> &boundingBox_, vector<struct orderScore> &bboxScore_, const mydataFmt overlap_threshold,
|
||||
string modelname) {
|
||||
if (boundingBox_.empty()) {
|
||||
return;
|
||||
}
|
||||
std::vector<int> heros;
|
||||
//sort the score
|
||||
sort(bboxScore_.begin(), bboxScore_.end(), cmpScore);
|
||||
|
||||
int order = 0;
|
||||
float IOU = 0;
|
||||
float maxX = 0;
|
||||
float maxY = 0;
|
||||
float minX = 0;
|
||||
float minY = 0;
|
||||
while (bboxScore_.size() > 0) {
|
||||
order = bboxScore_.back().oriOrder;
|
||||
bboxScore_.pop_back();
|
||||
if (order < 0)continue;
|
||||
heros.push_back(order);
|
||||
boundingBox_.at(order).exist = false;//delete it
|
||||
|
||||
for (int num = 0; num < boundingBox_.size(); num++) {
|
||||
if (boundingBox_.at(num).exist) {
|
||||
//the iou
|
||||
maxX = (boundingBox_.at(num).x1 > boundingBox_.at(order).x1) ? boundingBox_.at(num).x1
|
||||
: boundingBox_.at(order).x1;
|
||||
maxY = (boundingBox_.at(num).y1 > boundingBox_.at(order).y1) ? boundingBox_.at(num).y1
|
||||
: boundingBox_.at(order).y1;
|
||||
minX = (boundingBox_.at(num).x2 < boundingBox_.at(order).x2) ? boundingBox_.at(num).x2
|
||||
: boundingBox_.at(order).x2;
|
||||
minY = (boundingBox_.at(num).y2 < boundingBox_.at(order).y2) ? boundingBox_.at(num).y2
|
||||
: boundingBox_.at(order).y2;
|
||||
//maxX1 and maxY1 reuse
|
||||
maxX = ((minX - maxX + 1) > 0) ? (minX - maxX + 1) : 0;
|
||||
maxY = ((minY - maxY + 1) > 0) ? (minY - maxY + 1) : 0;
|
||||
//IOU reuse for the area of two bbox
|
||||
IOU = maxX * maxY;
|
||||
if (!modelname.compare("Union"))
|
||||
IOU = IOU / (boundingBox_.at(num).area + boundingBox_.at(order).area - IOU);
|
||||
else if (!modelname.compare("Min")) {
|
||||
IOU = IOU /
|
||||
((boundingBox_.at(num).area < boundingBox_.at(order).area) ? boundingBox_.at(num).area
|
||||
: boundingBox_.at(
|
||||
order).area);
|
||||
}
|
||||
if (IOU > overlap_threshold) {
|
||||
boundingBox_.at(num).exist = false;
|
||||
for (vector<orderScore>::iterator it = bboxScore_.begin(); it != bboxScore_.end(); it++) {
|
||||
if ((*it).oriOrder == num) {
|
||||
(*it).oriOrder = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < heros.size(); i++)
|
||||
boundingBox_.at(heros.at(i)).exist = true;
|
||||
}
|
||||
|
||||
void refineAndSquareBbox(vector<struct Bbox> &vecBbox, const int &height, const int &width) {
|
||||
if (vecBbox.empty()) {
|
||||
cout << "Bbox is empty!!" << endl;
|
||||
return;
|
||||
}
|
||||
float bbw = 0, bbh = 0, maxSide = 0;
|
||||
float h = 0, w = 0;
|
||||
float x1 = 0, y1 = 0, x2 = 0, y2 = 0;
|
||||
for (vector<struct Bbox>::iterator it = vecBbox.begin(); it != vecBbox.end(); it++) {
|
||||
if ((*it).exist) {
|
||||
bbh = (*it).x2 - (*it).x1 + 1;
|
||||
bbw = (*it).y2 - (*it).y1 + 1;
|
||||
x1 = (*it).x1 + (*it).regreCoord[1] * bbh;
|
||||
y1 = (*it).y1 + (*it).regreCoord[0] * bbw;
|
||||
x2 = (*it).x2 + (*it).regreCoord[3] * bbh;
|
||||
y2 = (*it).y2 + (*it).regreCoord[2] * bbw;
|
||||
|
||||
h = x2 - x1 + 1;
|
||||
w = y2 - y1 + 1;
|
||||
|
||||
maxSide = (h > w) ? h : w;
|
||||
x1 = x1 + h * 0.5 - maxSide * 0.5;
|
||||
y1 = y1 + w * 0.5 - maxSide * 0.5;
|
||||
(*it).x2 = round(x1 + maxSide - 1);
|
||||
(*it).y2 = round(y1 + maxSide - 1);
|
||||
(*it).x1 = round(x1);
|
||||
(*it).y1 = round(y1);
|
||||
|
||||
//boundary check
|
||||
if ((*it).x1 < 0)(*it).x1 = 0;
|
||||
if ((*it).y1 < 0)(*it).y1 = 0;
|
||||
if ((*it).x2 > height)(*it).x2 = height - 1;
|
||||
if ((*it).y2 > width)(*it).y2 = width - 1;
|
||||
|
||||
it->area = (it->x2 - it->x1) * (it->y2 - it->y1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void initBN(struct BN *var, struct BN *mean, struct BN *beta, int width) {
|
||||
var->width = width;
|
||||
var->pdata = (mydataFmt *) malloc(width * sizeof(mydataFmt));
|
||||
if (var->pdata == NULL)cout << "prelu apply for memory failed!!!!";
|
||||
memset(var->pdata, 0, width * sizeof(mydataFmt));
|
||||
|
||||
mean->width = width;
|
||||
mean->pdata = (mydataFmt *) malloc(width * sizeof(mydataFmt));
|
||||
if (mean->pdata == NULL)cout << "prelu apply for memory failed!!!!";
|
||||
memset(mean->pdata, 0, width * sizeof(mydataFmt));
|
||||
|
||||
beta->width = width;
|
||||
beta->pdata = (mydataFmt *) malloc(width * sizeof(mydataFmt));
|
||||
if (beta->pdata == NULL)cout << "prelu apply for memory failed!!!!";
|
||||
memset(beta->pdata, 0, width * sizeof(mydataFmt));
|
||||
}
|
||||
|
||||
void BatchNorm(struct pBox *pbox, struct BN *var, struct BN *mean, struct BN *beta) {
|
||||
if (pbox->pdata == NULL) {
|
||||
cout << "Relu feature is NULL!!" << endl;
|
||||
return;
|
||||
}
|
||||
if ((var->pdata == NULL) || (mean->pdata == NULL) || (beta->pdata == NULL)) {
|
||||
cout << "the BatchNorm bias is NULL!!" << endl;
|
||||
return;
|
||||
}
|
||||
mydataFmt *pp = pbox->pdata;
|
||||
mydataFmt *vp = var->pdata;
|
||||
mydataFmt *mp = mean->pdata;
|
||||
mydataFmt *bp = beta->pdata;
|
||||
double scale = 0.995;
|
||||
double bias = 0.0010000000474974513;
|
||||
long dis = pbox->width * pbox->height;
|
||||
for (int channel = 0; channel < pbox->channel; channel++) {
|
||||
for (int col = 0; col < dis; col++) {
|
||||
// *pp = *pp + *vp;
|
||||
// cout << ((*pp) / (sqrt(*vp + bias))) << endl;
|
||||
// cout << ((*pp) * (*mp) / (sqrt(*vp + bias))) << endl;
|
||||
// if (*pp == 0) {
|
||||
// cout << *vp << "===" << *mp << "===" << *bp << endl;
|
||||
// }
|
||||
*pp = ((*pp) * (scale) / (sqrt(*vp + bias))) + ((*bp) - (((*pp) * (*mp) * (scale)) / (sqrt(*vp + bias))));
|
||||
// cout << *pp << endl;
|
||||
pp++;
|
||||
}
|
||||
vp++;
|
||||
mp++;
|
||||
bp++;
|
||||
}
|
||||
}
|
||||
72
src/network.h
Executable file
72
src/network.h
Executable file
@@ -0,0 +1,72 @@
|
||||
#ifndef NETWORK_H
|
||||
#define NETWORK_H
|
||||
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/highgui/highgui.hpp"
|
||||
#include <algorithm>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <math.h>
|
||||
#include "pBox.h"
|
||||
//#include <cblas.h>
|
||||
|
||||
using namespace cv;
|
||||
|
||||
void addbias(struct pBox *pbox, mydataFmt *pbias);
|
||||
|
||||
void image2Matrix(const Mat &image, const struct pBox *pbox, int num = 0);
|
||||
|
||||
void maxPooling(const pBox *pbox, pBox *Matrix, int kernelSize, int stride);
|
||||
|
||||
void avePooling(const pBox *pbox, pBox *Matrix, int kernelSize, int stride);
|
||||
|
||||
void featurePad(const pBox *pbox, pBox *outpBox, const int pad, const int padw = 0, const int padh = 0);
|
||||
|
||||
void prelu(struct pBox *pbox, mydataFmt *pbias, mydataFmt *prelu_gmma);
|
||||
|
||||
void relu(struct pBox *pbox, mydataFmt *pbias);
|
||||
|
||||
void fullconnect(const Weight *weight, const pBox *pbox, pBox *outpBox);
|
||||
|
||||
void readData(string filename, long dataNumber[], mydataFmt *pTeam[], int length = 0);
|
||||
|
||||
long initConvAndFc(struct Weight *weight, int schannel, int lchannel, int kersize, int stride, int pad,
|
||||
int w = 0, int h = 0, int padw = 0, int padh = 0);
|
||||
|
||||
void initpRelu(struct pRelu *prelu, int width);
|
||||
|
||||
void softmax(const struct pBox *pbox);
|
||||
|
||||
void image2MatrixInit(Mat &image, struct pBox *pbox);
|
||||
|
||||
void featurePadInit(const pBox *pbox, pBox *outpBox, const int pad, const int padw = 0, const int padh = 0);
|
||||
|
||||
void maxPoolingInit(const pBox *pbox, pBox *Matrix, int kernelSize, int stride, int flag = 0);
|
||||
|
||||
void avePoolingInit(const pBox *pbox, pBox *Matrix, int kernelSize, int stride);
|
||||
|
||||
void convolutionInit(const Weight *weight, pBox *pbox, pBox *outpBox);
|
||||
|
||||
void fullconnectInit(const Weight *weight, pBox *outpBox);
|
||||
|
||||
bool cmpScore(struct orderScore lsh, struct orderScore rsh);
|
||||
|
||||
void nms(vector<struct Bbox> &boundingBox_, vector<struct orderScore> &bboxScore_, const mydataFmt overlap_threshold,
|
||||
string modelname = "Union");
|
||||
|
||||
void refineAndSquareBbox(vector<struct Bbox> &vecBbox, const int &height, const int &width);
|
||||
|
||||
void vectorXmatrix(mydataFmt *matrix, mydataFmt *v, int size, int v_w, int v_h, mydataFmt *p);
|
||||
|
||||
void convolution(const Weight *weight, const pBox *pbox, pBox *outpBox);
|
||||
|
||||
void meanAndDev(const Mat &image, mydataFmt *p, mydataFmt *q);
|
||||
|
||||
void initBN(struct BN *var, struct BN *mean, struct BN *beta, int width);
|
||||
|
||||
void BatchNorm(struct pBox *pbox, struct BN *var, struct BN *mean, struct BN *beta);
|
||||
|
||||
#endif
|
||||
33
src/pBox.cpp
Executable file
33
src/pBox.cpp
Executable file
@@ -0,0 +1,33 @@
|
||||
#include"pBox.h"
|
||||
|
||||
void freepBox(struct pBox *pbox) {
|
||||
if (pbox->pdata == NULL)cout << "pbox is NULL!" << endl;
|
||||
else
|
||||
free(pbox->pdata);
|
||||
pbox->pdata = NULL;
|
||||
delete pbox;
|
||||
}
|
||||
|
||||
void freepRelu(struct pRelu *prelu) {
|
||||
if (prelu->pdata == NULL)cout << "prelu is NULL!" << endl;
|
||||
else
|
||||
free(prelu->pdata);
|
||||
prelu->pdata = NULL;
|
||||
delete prelu;
|
||||
}
|
||||
|
||||
void freeWeight(struct Weight *weight) {
|
||||
if (weight->pdata == NULL)cout << "weight is NULL!" << endl;
|
||||
else
|
||||
free(weight->pdata);
|
||||
weight->pdata = NULL;
|
||||
delete weight;
|
||||
}
|
||||
|
||||
void freeBN(struct BN *bn) {
|
||||
if (bn->pdata == NULL)cout << "weight is NULL!" << endl;
|
||||
else
|
||||
free(bn->pdata);
|
||||
bn->pdata = NULL;
|
||||
delete bn;
|
||||
}
|
||||
92
src/pBox.h
Executable file
92
src/pBox.h
Executable file
@@ -0,0 +1,92 @@
|
||||
#ifndef PBOX_H
|
||||
#define PBOX_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <opencv2/core/cvstd.hpp>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
//#define mydataFmt double
|
||||
#define Num 128
|
||||
typedef double mydataFmt;
|
||||
|
||||
|
||||
struct pBox : public cv::String {
|
||||
mydataFmt *pdata;
|
||||
int width;
|
||||
int height;
|
||||
int channel;
|
||||
};
|
||||
|
||||
|
||||
struct pRelu {
|
||||
mydataFmt *pdata;
|
||||
int width;
|
||||
};
|
||||
|
||||
struct BN {
|
||||
mydataFmt *pdata;
|
||||
int width;
|
||||
};
|
||||
|
||||
|
||||
struct Weight {
|
||||
mydataFmt *pdata;
|
||||
mydataFmt *pbias;
|
||||
int lastChannel;
|
||||
int selfChannel;
|
||||
int kernelSize;
|
||||
int stride;
|
||||
int pad;
|
||||
int w;
|
||||
int h;
|
||||
int padw;
|
||||
int padh;
|
||||
};
|
||||
|
||||
class pBox1 {
|
||||
public:
|
||||
vector<vector<vector<mydataFmt>>> pdata;
|
||||
};
|
||||
|
||||
class pRelu1 {
|
||||
public:
|
||||
vector<mydataFmt> pdata;
|
||||
};
|
||||
|
||||
class Weight1 {
|
||||
public:
|
||||
vector<vector<vector<vector<mydataFmt>>>> pdata;
|
||||
vector<mydataFmt> pbias;
|
||||
int stride;
|
||||
int padw;
|
||||
int padh;
|
||||
};
|
||||
|
||||
struct Bbox {
|
||||
float score;
|
||||
int x1;
|
||||
int y1;
|
||||
int x2;
|
||||
int y2;
|
||||
float area;
|
||||
bool exist;
|
||||
mydataFmt ppoint[10];
|
||||
mydataFmt regreCoord[4];
|
||||
};
|
||||
|
||||
struct orderScore {
|
||||
mydataFmt score;
|
||||
int oriOrder;
|
||||
};
|
||||
|
||||
void freepBox(struct pBox *pbox);
|
||||
|
||||
void freeWeight(struct Weight *weight);
|
||||
|
||||
void freepRelu(struct pRelu *prelu);
|
||||
|
||||
void freeBN(struct BN *bn);
|
||||
|
||||
#endif
|
||||
77
src/pikaqiu.cpp
Executable file
77
src/pikaqiu.cpp
Executable file
@@ -0,0 +1,77 @@
|
||||
#include "network.h"
|
||||
#include "mtcnn.h"
|
||||
#include "facenet.h"
|
||||
#include <time.h>
|
||||
|
||||
void run() {
|
||||
int b = 0;
|
||||
if (b == 0) {
|
||||
Mat image = imread("../40.jpg");
|
||||
// Mat image = imread("../1.jpeg");
|
||||
// Mat image = imread("../Kong_Weiye.jpg");
|
||||
// Mat image = imread("../Kong_Weiye1.jpg");
|
||||
// Mat image = imread("../20.png");
|
||||
// Mat image = imread("../emb_img/0.jpg");
|
||||
mtcnn find(image.rows, image.cols);
|
||||
clock_t start;
|
||||
start = clock();
|
||||
find.findFace(image);
|
||||
imshow("result", image);
|
||||
imwrite("../result.jpg", image);
|
||||
start = clock() - start;
|
||||
// cout<<"time is "<<start/10e3<<endl;
|
||||
cout << "time is " << (double) start / CLOCKS_PER_SEC * 1000 << "ms" << endl;
|
||||
waitKey(0);
|
||||
image.release();
|
||||
} else if (b == 1) {
|
||||
Mat image = imread("../10.jpg");
|
||||
// Mat image = imread("../emb_img/0.jpg");
|
||||
// Mat image = imread("../20.png");
|
||||
Mat Image;
|
||||
resize(image, Image, Size(160, 160), 0, 0, cv::INTER_LINEAR);
|
||||
facenet ggg;
|
||||
mydataFmt *o = new mydataFmt[Num];
|
||||
ggg.run(Image, o, 0);
|
||||
// imshow("result", Image);
|
||||
imwrite("../result.jpg", Image);
|
||||
|
||||
for (int i = 0; i < Num; ++i) {
|
||||
cout << o[i] << endl;
|
||||
}
|
||||
|
||||
waitKey(0);
|
||||
image.release();
|
||||
} else {
|
||||
Mat image;
|
||||
VideoCapture cap(0);
|
||||
if (!cap.isOpened())
|
||||
cout << "fail to open!" << endl;
|
||||
cap >> image;
|
||||
if (!image.data) {
|
||||
cout << "读取视频失败" << endl;
|
||||
}
|
||||
|
||||
mtcnn find(image.rows, image.cols);
|
||||
clock_t start;
|
||||
int stop = 1200;
|
||||
//while (stop--) {
|
||||
while (true) {
|
||||
start = clock();
|
||||
cap >> image;
|
||||
find.findFace(image);
|
||||
imshow("result", image);
|
||||
if (waitKey(1) >= 0) break;
|
||||
start = clock() - start;
|
||||
cout << "time is " << (double) start / CLOCKS_PER_SEC * 1000 << "ms" << endl;
|
||||
}
|
||||
waitKey(0);
|
||||
image.release();
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
for (int i = 0; i < 1; ++i) {
|
||||
run();
|
||||
cout << "==============================" << endl;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user