gpt4 book ai didi

c++ - OpenCV InputArray 和 getMat 方法

转载 作者:太空宇宙 更新时间:2023-11-04 13:54:22 48 4
gpt4 key购买 nike

我花了很多时间在它上面,似乎 cv::Mat 发生了一些奇怪的事情, cv::Veccv::InputArray .

cv::EM如果我定义 SampleType,则需要 InputArray 只有 1 个 channel 作为cv::Veccv::MatxSampleContainerType作为cv::Mat_并填充它,一切都是正确的,m_Samples 具有正确的结构和 1 个 channel 。当 sample 以 InputArray 形式到达时给 EM em.cpp#L83它神奇地变成了 2 channel 矩阵。

我想使用 cv::Matxcv::Vec而不是 cv::Mat允许用户轻松定义样本,如 SampleType(1., 2.)

我创建了这个文件 https://gist.github.com/jrdi/9328183测试组合,我不明白前两种方法有什么问题。此外,我不想像上一个示例那样重新创建每个示例。

编辑(按要求添加代码):

#include "opencv2/core/core.hpp"
#include "itkObject.h"
#include "itkObjectFactory.h"

#include "BoostTestTargetConfig.h"

void CheckInputArrayChannels( cv::InputArray samples )
{
cv::Mat matrix = samples.getMat();
if( matrix.channels() != 1 )
{
itkGenericExceptionMacro( << "Channels error." );
}
}

BOOST_AUTO_TEST_CASE( cxInputArrayTest )
{
const unsigned int Dimension = 2;
typedef double CoordinateType;
// FAILS
{
typedef cv::Vec<CoordinateType, Dimension> SampleType;
typedef cv::Mat_<CoordinateType> SampleContainerType;

SampleType sample(2., 1.);
SampleContainerType samples;
samples.push_back( sample.t() );

BOOST_CHECK( samples.channels() == 1 );
BOOST_CHECK_NO_THROW( CheckInputArrayChannels( samples ) );
}
// FAILS
{
typedef cv::Matx<CoordinateType, 1, Dimension> SampleType;
typedef cv::Mat_<CoordinateType> SampleContainerType;

SampleType sample(2., 1.);
SampleContainerType samples;
samples.push_back( sample );

BOOST_CHECK( samples.channels() == 1 );
BOOST_CHECK_NO_THROW( CheckInputArrayChannels( samples ) );
}
// FAILS
{
typedef cv::Matx<CoordinateType, 1, Dimension> SampleType;
typedef std::vector<SampleType> SampleContainerType;

SampleType sample(2., 1.);
SampleContainerType samples;
samples.push_back( sample );

BOOST_CHECK_NO_THROW( CheckInputArrayChannels( samples ) );
}
// PASS
{
cv::Mat sample(1, 2, cv::DataType<CoordinateType>::type);
sample.at<CoordinateType>(0) = 2.;
sample.at<CoordinateType>(1) = 1.;

cv::Mat_<CoordinateType> samples;
samples.push_back( sample );

BOOST_CHECK( samples.channels() == 1 );
BOOST_CHECK_NO_THROW( CheckInputArrayChannels( samples ) );
}
// PASS
{
typedef cv::Matx<CoordinateType, 1, Dimension> SampleType;
typedef cv::Mat_<CoordinateType> SampleContainerType;

SampleType sample(2., 1.);
SampleContainerType samples;
samples.push_back( cv::Mat(sample) );

BOOST_CHECK( samples.channels() == 1 );
BOOST_CHECK_NO_THROW( CheckInputArrayChannels( samples ) );
}
}

最佳答案

来自 OpenCV 引用:-

Vec: Template class for short numerical vectors, a partial case of Matx.
...
The Vec class is commonly used to describe pixel types of multi-channel arrays

因此,当您将 cv::Vec 插入 Mat 时,您正在创建多 channel 行。

您的最后一个示例是创建多维矩阵的正确方法。默认情况下,您使用时会复制数据

cv::Mat(sample)

您可以通过将 false 传递给 Mat 构造函数来创建对 sample 的引用。

cv::Mat(sample, false)

有关如何计算 channel 数(行 * 列)的更多引用:-

template<typename _Tp, int m, int n> class Matx
{
public:
typedef _Tp value_type;
typedef Matx<_Tp, (m < n ? m : n), 1> diag_type;
typedef Matx<_Tp, m, n> mat_type;
enum { depth = DataDepth<_Tp>::value, rows = m, cols = n, channels = rows*cols,
type = CV_MAKETYPE(depth, channels) };
....
};

关于c++ - OpenCV InputArray 和 getMat 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22152866/

48 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com