[Opencv源码阅读]InputArray和OutputArray

本文详细介绍了OpenCV中的InputArray和OutputArray类,它们作为数据输入和输出的代理类型。InputArray用于接收不可变的输入参数,如Mat和Vector<>,而OutputArray则允许修改参数内容。文章探讨了它们的构造函数,特别是如何通过flags标记数据类型,并提供了数据转换的方法,如getMat(),用于将不同类型的数据转换为Mat。此外,还讲解了类型标记和数据转换的相关枚举常量及其用途。
摘要由CSDN通过智能技术生成

概述

InputArray和OutputArray两个类都是代理数据类型,用来接收Mat和Vector<>作为输入参数,OutputArray继承自InputArray。

InputArray作为输入参数的时候,传入的参数加了const限定符,即它只接收参数作为纯输入参数,无法更改输入参数的内容。而OutputArray则没有加入限定符,可以对参数的内容进行更改。

 

InputArray使用一系列的数据类型作为输入实例化自身,通过设定一系列的构造函数来实现。

_InputArray::_InputArray(constMat&m) : flags(MAT),obj((void*)&m) {}

_InputArray::_InputArray(constvector<Mat>&vec) : flags(STD_VECTOR_MAT),obj((void*)&vec) {}

_InputArray::_InputArray(constdouble&val) : flags(FIXED_TYPE +FIXED_SIZE + MATX +CV_64F), obj((void*)&val),sz(Size(1,1)) {}

.....

 

可以看到在构造的时候,同时指定了flags和obj,flags用于表明当前存储的数据类型,而obj存储的则是数据的内存地址。

 

除了这些基本的构造函数外,还有其他支持泛型的构造函数,如下

/// Input/Output Arrays /

 

template<typename_Tp>inline_InputArray::_InputArray(constvector<_Tp>&vec)

: flags(FIXED_TYPE +STD_VECTOR + DataType<_Tp>::type),obj((void*)&vec) {}

 

template<typename

以下是 OpenCV 中 `cv::filter2D` 函数的简化版源码: ```cpp void cv::filter2D( InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor = Point(-1,-1), double delta = 0, int borderType = BORDER_DEFAULT ) { // 获取输入图像和卷积核 Mat srcMat = src.getMat(); Mat kernelMat = kernel.getMat(); // 创建输出图像 dst.create(srcMat.size(), CV_MAKETYPE(ddepth, srcMat.channels())); Mat dstMat = dst.getMat(); // 根据卷积核的大小和锚点位置进行卷积计算 Point kernelAnchor(-1, -1); if (anchor.x >= 0 && anchor.y >= 0) kernelAnchor = Point(anchor.x * kernelMat.cols, anchor.y * kernelMat.rows); else kernelAnchor = Point((kernelMat.cols - 1) / 2, (kernelMat.rows - 1) / 2); // 对输入图像进行卷积计算 for (int i = 0; i < srcMat.channels(); ++i) { // 获取当前通道的输入图像和输出图像 Mat srcChannel = srcMat.channel(i); Mat dstChannel = dstMat.channel(i); // 对每个像素进行卷积操作 for (int y = 0; y < srcMat.rows; ++y) { for (int x = 0; x < srcMat.cols; ++x) { // 计算当前像素的卷积结果 float sum = 0; for (int ky = 0; ky < kernelMat.rows; ++ky) { for (int kx = 0; kx < kernelMat.cols; ++kx) { int srcX = x + kx - kernelAnchor.x; int srcY = y + ky - kernelAnchor.y; if (srcX >= 0 && srcX < srcMat.cols && srcY >= 0 && srcY < srcMat.rows) sum += srcChannel.at<float>(srcY, srcX) * kernelMat.at<float>(ky, kx); } } dstChannel.at<float>(y, x) = static_cast<float>(sum + delta); } } } // 边界处理 if (borderType != BORDER_CONSTANT) copyMakeBorder(dst, dst, kernelAnchor.y, kernelMat.rows - kernelAnchor.y - 1, kernelAnchor.x, kernelMat.cols - kernelAnchor.x - 1, borderType); } ``` 这是一个简化版的源码,省略了一些参数的处理和错误检查等细节。如果你想获得更完整和详细的源码,建议直接查阅 OpenCV 的源代码库中的 `imgproc/src/filter.cpp` 文件。 希望对你有帮助!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值