Files
micro_servers/lci/src/mainNn.cpp
T
2026-08-02 20:15:07 +08:00

188 lines
6.3 KiB
C++

#include <iostream>
#include <filesystem>
#include <vector>
#include <string>
#include <fstream>
#include <chrono>
#include <iomanip>
//#include <CImg.h>
#include "hd/Camera.h"
#include "nn/ImageLoader.hpp"
#include "nn/ConvLayer.hpp"
#include "nn/PoolingLayer.hpp"
#include "nn/FlattenLayer.hpp"
#include "nn/CNNBuilder.hpp"
#include "nn/NNBuilder.hpp"
#include "nn/NeuralNetwork.hpp"
using namespace qing;
// 定义颜色用于不同的人脸框
const unsigned char colors[][3] = {
{255, 0, 0}, // 红色
{0, 255, 0}, // 绿色
{0, 0, 255}, // 蓝色
{255, 255, 0}, // 黄色
{255, 0, 255} // 紫色
};
void take_a_photo(const char* path);
int run_facerec(const char* in, const char* out);
// 主函数
int main(int argc, char* argv[]) {
ImageLoader image_loader(3, 480, 640, true, false);
ConvLayer conv1(3, 16, 3, 1, 1);
PoolingLayer pool1(2, 2, 2, 0, true);
ConvLayer conv2(16, 32, 3, 1, 1);
PoolingLayer pool2(2, 2, 2, 0, true);
ConvLayer conv3(32, 64, 3, 1, 1);
PoolingLayer pool3(2, 2, 2, 0, true);
ConvLayer conv4(64, 128, 3, 1, 1);
PoolingLayer pool4(2, 2, 2, 0, true);
ConvLayer conv5(128, 256, 3, 1, 1);
PoolingLayer pool5(2, 2, 2, 0, true);
ConvLayer conv6(256, 512, 3, 1, 1);
PoolingLayer pool6(2, 2, 2, 0, true);
FlattenLayer flatten;
CNNBuilder cnn;
int in_channels = 3;
int in_h = 480;
int in_w = 640;
int batch_size = 1;
cnn.add_conv_layer(conv1, in_channels, in_h, in_w);
cnn.add_pool_layer(pool1, 16, in_h, in_w);
cnn.add_conv_layer(conv2, 16, in_h/2, in_w/2);
cnn.add_pool_layer(pool2, 32, in_h/2, in_w/2);
cnn.add_conv_layer(conv3, 32, in_h/4, in_w/4);
cnn.add_pool_layer(pool3, 64, in_h/4, in_w/4);
cnn.add_conv_layer(conv4, 64, in_h/8, in_w/8);
cnn.add_pool_layer(pool4, 128, in_h/8, in_w/8);
cnn.add_conv_layer(conv5, 128, in_h/16, in_w/16);
cnn.add_pool_layer(pool5, 256, in_h/16, in_w/16);
cnn.add_conv_layer(conv6, 256, in_h/32, in_w/32);
cnn.add_pool_layer(pool6, 512, in_h/32, in_w/32);
cnn.add_flatten_layer(flatten, 512, 7, 10);
cnn.print_architecture();
NNBuilder nn;
using nnl = NeuralNetwork;
auto layer0 = nnl::Create_in_Factory(15360, 6500,0.5, nnl::ActivationFunc::Leaky_ReLU);
auto layer1 = nnl::Create_in_Factory(6500, 1500, 0.45, nnl::ActivationFunc::Leaky_ReLU);
auto layer2 = nnl::Create_in_Factory(1500, 300, 0.40, nnl::ActivationFunc::Leaky_ReLU);
auto layer3 = nnl::Create_in_Factory(300, 70, 0.35, nnl::ActivationFunc::Leaky_ReLU);
auto layer4 = nnl::Create_in_Factory(70, 5, 0.30, nnl::ActivationFunc::Sigmoid);
nn.add(layer0);
nn.add(layer1);
nn.add(layer2);
nn.add(layer3);
nn.add(layer4);
nn.print_shape();
//Camera_init(640, 480);
bool flag = true;
while (flag) {
//std::string imgpath = std::string("./dataSet/" + std::to_string(time(NULL)) + ".jpeg");
//std::string txtpath =std::string("./dataSet/" + std::to_string(time(NULL)) + ".txt");
//bool flag;
//auto img = get_frame_from_camera(flag);
//img.save(imgpath.c_str());
//if (run_facerec(imgpath.c_str(), txtpath.c_str()))
// throw std::runtime_error("facerec");
std::string data_root = "./dataSet";
namespace fs = std::filesystem;
for (const auto& entry : fs::recursive_directory_iterator(data_root)) {
if (!fs::is_regular_file(entry.status()))
continue;
std::string basename = entry.path().stem().string();
std::string txtpath = data_root + "/" + basename + ".txt";
std::string imgpath = data_root + "/" + basename+".jpeg";
auto img = cimg_library::CImg<unsigned char>(imgpath.c_str());
auto image_data = image_loader.load_from_cimg(img, true);
if (image_data.empty()) {
std::cerr << "Failed to load image!" << std::endl;
break;
}
/* 前向传播 */
auto output = cnn.forward(image_data, batch_size, true);
if (!output.empty()) {
std::cout << "Forward pass successful!" << std::endl;
std::cout << "Input size: " << image_data.size() << std::endl;
std::cout << "Output size: " << output.size() << std::endl;
// 计算输出统计信息
float sum = 0.0f, max_val = output[0], min_val = output[0];
for (float val : output) {
sum += val;
if (val > max_val) max_val = val;
if (val < min_val) min_val = val;
}
std::cout << "Output statistics:" << std::endl;
std::cout << " Mean: " << sum / output.size() << std::endl;
std::cout << " Min: " << min_val << std::endl;
std::cout << " Max: " << max_val << std::endl;
}
std::vector<float> t(5);
std::ifstream file(txtpath);
if (!file) t[0] = 0;
else {
t[0] = 1;
for (int i=0; i<5; ++i) {
file >> t[i+1];
std::cout << t[i+1] << " ";
}
}
std::cout<< std::endl;
auto r = nn.forward(output);
auto y = nn.cal_err(r, t);
/* 不存在人脸时,位置信息不计入 */
if (t[0] == 0)
for (int i =1; i< 5; i++)
y[i]= 0;
else {
for (auto i: y) {
std::cout << i << " ";
}
std::cout << std::endl;
auto fix_img = img.draw_rectangle(t[4]*640,t[1]*480, t[2]*640,t[3]*480, colors[1], 1, ~0U); /* 抽象为函数 */
fix_img = fix_img.draw_rectangle(r[4]*640,r[1]*480, r[2]*640,r[3]*480, colors[0], 1, ~0U);
std::string respath = "./resSet/" + basename+".jpeg";
fix_img.save(respath.c_str());
}
y = nn.backward(y);
y = cnn.backward(y);
}
}
//Camera_close();
}
int run_facerec(const char* in, const char* out) {
auto cmd = std::string("python tools/facerec.py detect ");
cmd += in;
cmd += " --output ";
cmd += out;
return system(cmd.c_str());
}