按照官网下载的
https://github.com/Tencent/ncnn
源码,并且按照链接https://github.com/Tencent/ncnn/wiki/how-to-build#pass-for-linux
中的方式来进行编译,编译之后就可以运行一下。
此时有一个新的需求,我们想要自己编译一个项目,但是我尝试抽取ncnn中的编译库来编译,但是无法成功抽取,太垃圾了,然后转头一想加上分析,发现可以不用抽取ncnn源码,只用在他相同的文件夹中来编译自己的源码就好了。
-
1,
ncnn
源码中有一个examples
文件夹,他里边放着很多自带的待编译demo,编译之后生成的可执行文件就在build/examples
文件夹中(顺着ncnn官网的squeezenet编译与使用来了解整个项目); -
2,然后仿照上边的处理思路,我们可以在
examples
所在的文件夹下建立自己的待编译源码文件夹my_src
,然后里边的CMakeLists.txt
以及cpp
源码都可以仿照examples里边的代码来处理。- CMakeLists.txt:修改的地方主要有添加
ncnn_add_my_src(srcnn)
- cpp: 文件中就是把squeezenet中的代码复制过来修改为自己的就好了
- CMakeLists.txt:修改的地方主要有添加
-
值得一提的是,尽量把数据预处理的代码都写到model中,这样减少在c++中做数据预处理,因为c++数据预处理比较麻烦。
自己的cpp代码如下,仅供参考:
#include "net.h"
#include
#if defined(USE_NCNN_SIMPLEOCV)
#include "simpleocv.h"
#else
#include
#include // image文件读取与写入
#include // 高等级gui
#include // 图像处理
#endif
#include
#include
#include
using namespace std;
static int srcnn_process(const cv::Mat& bgr_image1)
{
// 显示一下输入的image
cout<< bgr_image1.size() << endl;
cv::imshow("bgr_image1", bgr_image1);
cv::waitKey(0);
// 网络加载
ncnn::Net srcnn;
srcnn.opt.use_vulkan_compute = true;
// 看看能否加载成功
if (srcnn.load_param("srcnn.param"))
exit(-1);
if (srcnn.load_model("srcnn.bin"))
exit(-1);
/** 数据预处理 */
// resize小一点
int row = bgr_image1.rows; // 行高
int col = bgr_image1.cols; // 列宽
cv::Mat bgr_image;
cv::resize(bgr_image1, bgr_image, cv::Size(col/2, row/2), 0, 0, CV_INTER_LINEAR);
cout<< bgr_image.size() << endl;
// bgr_image.convertTo(bgr_image, CV_32F); // 首先将数据转为32位浮点数(因为python推理里边有这个操作)
// cvMat转为ncnnMat
ncnn::Mat in = ncnn::Mat::from_pixels(bgr_image.data, ncnn::Mat::PIXEL_BGR2RGB, bgr_image.cols, bgr_image.rows);
// 可视化一下转为ncnn的数据是否还是正常的图片
cv::Mat cv_img_temp(in.h, in.w, CV_8UC3);
in.to_pixels(cv_img_temp.data, ncnn::Mat::PIXEL_RGB2BGR); // 先把ncnnMat转为cvMat的image格式
cv::imshow("cv_img_temp", cv_img_temp);
cv::waitKey(0);
// 归一化
// float mean[1] = { 128.f }; // 均值
// float norm[1] = { 1/128.f }; // 方差
// in.substract_mean_normalize(mean, norm);
// cout<< "111" << endl;
/** 推理 */
// 得到特征提取器
ncnn::Extractor ex = srcnn.create_extractor();
// 送入输入
ex.input("input", in);
// 得到网络的输出
ncnn::Mat out;
ex.extract("output", out);
// cout<< "222" << endl;
/** 后处理 */
// 得到3通道的无符号8位图像数据
cv::Mat cv_img(out.h, out.w, CV_8UC3);
out.to_pixels(cv_img.data, ncnn::Mat::PIXEL_RGB2BGR); // 数据转为BGR输出到cv_img中
// 显示一下处理后的image
cv::imshow("image", cv_img);
cv::waitKey(0);
return 0;
}
// main函数
int main(int argc, char** argv) {
// argc 输入有多少个参数, argv[] 用来存你输入的参数
// 如果没输入两个参数,就是没图片路径
if (argc != 2)
{
fprintf(stderr, "Usage: %s [imagepath]\n", argv[0]);
return -1;
}
// 取出第一个参数,就是 imagepath
const char* imagepath = argv[1];
// 读取输入图片
cv::Mat m = cv::imread(imagepath, 1);
if (m.empty()) // 图片读取失败
{
fprintf(stderr, "cv::imread %s failed\n", imagepath);
return -1;
}
// 推理
srcnn_process(m);
// cv::imshow("image", m);
// cv::waitKey(0);
return 0;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)