概述
MNN 图像处理
MNN中提供了CV模块,可以帮助用户简化图像的处理,还可以免于引入opencv、libyuv等图片处理库。
- 支持目标Tensor为float或 uint8_t 的数据格式
- 支持目标Tensor为NC4HW4、NHWC、NCHW的维度格式
- CV模块支持直接输入Device Tensor,也即由Session中获取的Tensor。
MNN图像处理配置
struct Config
{
Filter filterType = NEAREST;
ImageFormat sourceFormat = RGBA;
ImageFormat destFormat = RGBA;
//Only valid if the dest type is float
float mean[4] = {0.0f,0.0f,0.0f, 0.0f};
float normal[4] = {1.0f, 1.0f, 1.0f, 1.0f};
};
CV::ImageProcess::Config中
- 通过sourceFormat和destFormat指定输入和输出的格式,当前支持RGBA、RGB、BGR、GRAY、BGRA、YUV_NV21、YUV_NV12
- 通过filterType指定插值的类型,当前支持NEAREST、BILINEAR和BICUBIC三种插值方式
- 通过mean和normal指定均值归一化,但数据类型不是浮点类型时,设置会被忽略
测试用例 NV12转BGR
#include <MNN/ImageProcess.hpp>
#include <cmath>
#include <memory>
#include "MNNTestSuite.h"
#define MNN_OPEN_TIME_TRACE
#include <MNN/AutoTime.hpp>
using namespace MNN;
using namespace MNN::CV;
static void BGR2NV12(const cv::Mat &bgr_image,
unsigned char *buffer) {
int bgr_width = bgr_image.cols;
int bgr_height = bgr_image.rows;
cv::Mat yuv_image = cv::Mat(bgr_height, bgr_width, CV_8UC2);
cvtColor(bgr_image, yuv_image, CV_BGRA2YUV_I420);
int len_y = bgr_height * bgr_width;
int len_u = len_y >> 2;
unsigned char *pt_yuv_y = yuv_image.data;
unsigned char *pt_yuv_u = pt_yuv_y + len_y;
unsigned char *pt_yuv_v = pt_yuv_u + len_u;
unsigned char *pt_dst_uv = buffer + len_y;
int i, j;
// copy y;
memcpy(buffer, pt_yuv_y, len_y);
// copy uv;
for (i = 0, j = 0; i < len_u; i++) {
pt_dst_uv[j++] = pt_yuv_u[i];
pt_dst_uv[j++] = pt_yuv_v[i];
}
}
int main(int argc, char *argv[])
{
ImageProcess::Config config;
config.sourceFormat = YUV_NV12;
config.destFormat = BGR;
config.filterType = NEAREST;
config.wrap = CLAMP_TO_EDGE;
std::shared_ptr<ImageProcess> process(ImageProcess::create(config));
int sw = 1280;
int sh = 960;
Matrix tr;
process->setMatrix(tr);
std::shared_ptr<Tensor> tensor(Tensor::create<uint8_t>(std::vector<int>{1, sh, sw, 3}, nullptr, Tensor::TENSORFLOW));
char src_video[256];
int n = sprintf(src_video, "test.avi");
src_video[n] = '