我花了很多时间用cv::Mat
,cv::Vec
和cv::InputArray
看起来很奇怪。
cv::EM
定义为SampleType
或cv::Vec
并将cv::Matx
定义为SampleContainerType
,则 cv::Mat_
需要和InputArray只有1个频道并填充它,一切正确,m_Samples具有正确的结构和1个通道。当样本以InputArray
到达EM em.cpp#L83时,它会神奇地变为2个通道矩阵。
我想使用cv::Matx
或cv::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 ) );
}
}
答案 0 :(得分:0)
来自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
时,您正在制作多渠道行。
你的最后一个例子是创建多维矩阵的正确方法。 默认情况下,使用
时将复制数据cv::Mat(sample)
您可以通过将sample
传递给false
构造函数来创建对Mat
的引用。
cv::Mat(sample, false)
有关如何计算通道数的更多参考(行*列): -
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) };
....
};