【深度学习】MNN ImageProcess处理图像顺序,逻辑,均值,方差

本文主要是介绍【深度学习】MNN ImageProcess处理图像顺序,逻辑,均值,方差,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 介绍
  • Opencv numpy
  • 等效的MNN处理

介绍

MNN ImageProcess处理图像是先reisze还是后resize,均值方差怎么处理,是什么通道顺序?这篇文章告诉你答案。

Opencv numpy

这段代码是一个图像预处理函数,用于对输入的图像进行一系列处理,以便将其用于某些机器学习模型的输入。

  1. cv2.imdecode(np.fromfile(imgpath, dtype=np.uint8), 1):这行代码从文件中读取图像数据,并使用OpenCV库中的imdecode函数将其解码为图像矩阵。参数1表示图像应该按原样解码,即不进行颜色转换或通道重新排序。

  2. cv2.resize(img, (224, 224), interpolation=cv2.INTER_LINEAR):接下来,将图像调整大小为 (224, 224),这是因为一些深度学习模型(如AlexNet、VGG等)需要固定大小的输入图像。

  3. img = img.astype(np.float32):将图像数据类型转换为 32 位浮点数,通常这是深度学习模型期望的输入类型。

  4. img = img[..., ::-1]:颜色通道顺序调整,将图像从 BGR 格式转换为 RGB 格式。

  5. img_norm_cfg:定义了图像的归一化参数,包括均值和标准差。这些参数用于将图像像素值标准化到一个较小的范围,以便模型更好地处理图像数据。

  6. img -= img_norm_cfg['mean']:对图像进行均值归一化。

  7. img *= img_norm_cfg['std']:对图像进行标准差归一化。

  8. img = img.transpose((2, 0, 1)):调整图像的维度顺序,将通道维度置于第一个位置。

  9. img = np.expand_dims(img, axis=0):在图像的第一个维度(批处理维度)上添加一个维度,使其成为形状为 (1, C, H, W) 的批量图像数据,其中 C 是通道数,H 和 W 是图像的高度和宽度。

最终,函数返回预处理后的图像数据,可以直接用于输入深度学习模型进行训练或推断。

    def preprocess(self, imgpath: str):img = cv2.imdecode(np.fromfile(imgpath, dtype=np.uint8), 1)  # img是矩阵if img is None:raise Exception("image is None:" + imgpath)img = cv2.resize(img, (224, 224), interpolation=cv2.INTER_LINEAR)img = img.astype(np.float32)img = img[..., ::-1]img_norm_cfg = dict(mean=[103.53, 116.28, 123.675],std=[0.01712, 0.01750, 0.01742])img -= img_norm_cfg['mean']img *= img_norm_cfg['std']img = img.transpose((2, 0, 1))img = np.expand_dims(img, axis=0)return img

等效的MNN处理

下面是一个等效的MNN处理:

// 获取模型和会话
ModelData GetDetModel(const char* model_file_name) {using namespace MNN;ModelData modelData;// MNNstd::shared_ptr<Interpreter> interpreter(Interpreter::createFromFile(model_file_name));ScheduleConfig config_s;config_s.type = MNN_FORWARD_AUTO;Session* mSession = interpreter->createSession(config_s);Tensor* mInputTensor = interpreter->getSessionInput(mSession, NULL);Tensor* mOutputTensor = interpreter->getSessionOutput(mSession, NULL);// 输入处理,形成一个mnn张量// dst = (img - mean) * normalMNN::CV::ImageProcess::Config config;config.destFormat = MNN::CV::ImageFormat::RGB;config.sourceFormat = MNN::CV::ImageFormat::BGR;float mean_[4] = {103.53f, 116.28f, 123.675f, 0.0f};memcpy(config.mean, mean_, 4 * sizeof(float));float normal_[4] = {0.01712f, 0.01750f, 0.01742f, 0.0f};memcpy(config.normal, normal_, 4 * sizeof(float));config.filterType = MNN::CV::NEAREST;config.wrap = MNN::CV::ZERO;std::shared_ptr<MNN::CV::ImageProcess> image_process(MNN::CV::ImageProcess::create(config));//    MNN::CV::Matrix transform;//    image_process->setMatrix(transform);modelData.interpreter = interpreter;modelData.session = mSession;modelData.mInputTensor = mInputTensor;modelData.mOutputTensor = mOutputTensor;modelData.image_process = image_process;return modelData;
}// 释放资源
void ReleaseDetModel(ModelData& modelData) {using namespace MNN;auto interpreter = modelData.interpreter;auto mSession = modelData.session;auto mInputTensor = modelData.mInputTensor;auto mOutputTensor = modelData.mOutputTensor;auto image_process = modelData.image_process;interpreter->releaseModel();interpreter->releaseSession(mSession);
}std::vector<float> RunDetModel(ModelData& modelData,  // 模型和会话cv::Mat& img_bgr)      // 图片 opencv mat
{using namespace MNN;auto interpreter = modelData.interpreter;auto mSession = modelData.session;auto mInputTensor = modelData.mInputTensor;auto mOutputTensor = modelData.mOutputTensor;auto image_process = modelData.image_process;cv::Mat srcimgx;srcimgx = img_bgr.clone();cv::resize(srcimgx, srcimgx, cv::Size(224, 224), 0, 0, cv::INTER_LINEAR);int img_resize_height = srcimgx.rows;int img_resize_width = srcimgx.cols;// resizeSession//    interpreter->resizeTensor(mInputTensor, {1, 3, img_resize_height, img_resize_width});//    interpreter->resizeSession(mSession);// 输入处理,形成一个mnn张量std::vector<int> shape = {1, 3, img_resize_height, img_resize_width};std::shared_ptr<MNN::Tensor> input_tensor(MNN::Tensor::create<float>(shape, nullptr, MNN::Tensor::CAFFE));image_process->convert(srcimgx.data, img_resize_width, img_resize_height, 0, input_tensor.get());// 给入mInputTensormInputTensor->copyFromHostTensor(input_tensor.get());// Run mSessioninterpreter->runSession(mSession);// Get outputauto nchwTensorOt = new Tensor(mOutputTensor, Tensor::CAFFE);// 拷贝出去mOutputTensor->copyToHostTensor(nchwTensorOt);// 使用auto type = nchwTensorOt->getType();auto size = nchwTensorOt->elementSize();std::vector<int> shape_out = nchwTensorOt->shape();// values 输出形状是 img_fp_height, img_fp_width,直接给到cv::Matauto values = nchwTensorOt->host<float>();// log values sizestd::vector<float> outimg(values, values + size);delete nchwTensorOt;return outimg;
}

这篇关于【深度学习】MNN ImageProcess处理图像顺序,逻辑,均值,方差的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/663914

相关文章

如何使用celery进行异步处理和定时任务(django)

《如何使用celery进行异步处理和定时任务(django)》文章介绍了Celery的基本概念、安装方法、如何使用Celery进行异步任务处理以及如何设置定时任务,通过Celery,可以在Web应用中... 目录一、celery的作用二、安装celery三、使用celery 异步执行任务四、使用celery

SpringBoot操作spark处理hdfs文件的操作方法

《SpringBoot操作spark处理hdfs文件的操作方法》本文介绍了如何使用SpringBoot操作Spark处理HDFS文件,包括导入依赖、配置Spark信息、编写Controller和Ser... 目录SpringBoot操作spark处理hdfs文件1、导入依赖2、配置spark信息3、cont

JAVA利用顺序表实现“杨辉三角”的思路及代码示例

《JAVA利用顺序表实现“杨辉三角”的思路及代码示例》杨辉三角形是中国古代数学的杰出研究成果之一,是我国北宋数学家贾宪于1050年首先发现并使用的,:本文主要介绍JAVA利用顺序表实现杨辉三角的思... 目录一:“杨辉三角”题目链接二:题解代码:三:题解思路:总结一:“杨辉三角”题目链接题目链接:点击这里

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

MyBatis延迟加载的处理方案

《MyBatis延迟加载的处理方案》MyBatis支持延迟加载(LazyLoading),允许在需要数据时才从数据库加载,而不是在查询结果第一次返回时就立即加载所有数据,延迟加载的核心思想是,将关联对... 目录MyBATis如何处理延迟加载?延迟加载的原理1. 开启延迟加载2. 延迟加载的配置2.1 使用

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超

Python中处理NaN值的技巧分享

《Python中处理NaN值的技巧分享》在数据科学和数据分析领域,NaN(NotaNumber)是一个常见的概念,它表示一个缺失或未定义的数值,在Python中,尤其是在使用pandas库处理数据时,... 目录NaN 值的来源和影响使用 pandas 的 isna()和 isnull()函数直接比较 Na

详解Python中通用工具类与异常处理

《详解Python中通用工具类与异常处理》在Python开发中,编写可重用的工具类和通用的异常处理机制是提高代码质量和开发效率的关键,本文将介绍如何将特定的异常类改写为更通用的ValidationEx... 目录1. 通用异常类:ValidationException2. 通用工具类:Utils3. 示例文

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用