访问CV_32SC1 nx1的opencv矩阵
Access to CV_32SC1 nx1 opencv matrix
我有一个人工矩阵,我把它传递给OpenCV - 3.0.0版本的EM高斯混合模型算法:
[1.1, 3.2;
1.15, 3.1500001;
3.0999999, 4.1999998;
3.2, 4.3000002;
5, 5]
我调用GMM预测通过:
cv::Ptr<cv::ml::EM> source_model = cv::ml::EM::create();
source_model->setClustersNumber(3);
cv::Mat logs;
cv::Mat labels;
cv::Mat probs;
source_model->trainEM( openCVPointCloud,logs,labels,probs)
文档说明了我感兴趣的矩阵标签:
labels -每个样本的可选输出'class label':Labels_i = {arg max}k(p{i,k}), i=1..N(每个样本最可能混合成分的指数)。它有nsamples x 1大小和'CV_32SC1'类型。
我对'labels'的非工作访问打印(0,0,0,0,0)而不是预期的(0,0,1,1,2),这是通过
绘制的std::cout << labels <<std::endl;
。我需要使用整数索引来处理我想通过点云功能聚类的原始PCL点云:
std::cout << labels.data[0] << std::endl;
std::cout << labels.data[1] << std::endl;
std::cout << labels.data[2] << std::endl;
std::cout << labels.data[3] << std::endl;
std::cout << labels.data[4] << std::endl;
在一个未经测试的最小示例中包装在一起的代码片段(我在不使用框架的情况下使用qmake有问题):
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/ml.hpp>
int main()
{
cv::Mat openCVPointCloud(5, 2, CV_32FC(1));
{
cv::Vec<float,1> & values1 = openCVPointCloud.at<cv::Vec<float,1> >(0,0);
values1.val[0] = 1.1;
cv::Vec<float,1> & values2 = openCVPointCloud.at<cv::Vec<float,1> >(0,1);
values2.val[0] = 3.2;
}
{
cv::Vec<float,1> & values1 = openCVPointCloud.at<cv::Vec<float,1> >(1,0);
values1.val[0] = 1.15;
cv::Vec<float,1> & values2 = openCVPointCloud.at<cv::Vec<float,1> >(1,1);
values2.val[0] = 3.15;
}
{
cv::Vec<float,1> & values1 = openCVPointCloud.at<cv::Vec<float,1> >(2,0);
values1.val[0] = 3.1;
cv::Vec<float,1> & values2 = openCVPointCloud.at<cv::Vec<float,1> >(2,1);
values2.val[0] = 4.2;
}
{
cv::Vec<float,1> & values1 = openCVPointCloud.at<cv::Vec<float,1> >(3,0);
values1.val[0] = 3.2;
cv::Vec<float,1> & values2 = openCVPointCloud.at<cv::Vec<float,1> >(3,1);
values2.val[0] = 4.3;
}
{
cv::Vec<float,1> & values1 = openCVPointCloud.at<cv::Vec<float,1> >(4,0);
values1.val[0] = 5;
cv::Vec<float,1> & values2 = openCVPointCloud.at<cv::Vec<float,1> >(4,1);
values2.val[0] = 5;
}
std::cout << openCVPointCloud << std::endl;
cv::Ptr<cv::ml::EM> source_model = cv::ml::EM::create();
source_model->setClustersNumber(3);
cv::Mat logs;
cv::Mat labels;
cv::Mat probs;
if(source_model->trainEM( openCVPointCloud,logs,labels,probs))
{
std::cout << "true train em";
std::cout << labels.data[0] << std::endl;
std::cout << labels.data[1] << std::endl;
std::cout << labels.data[2] << std::endl;
std::cout << labels.data[3] << std::endl;
std::cout << labels.data[4] << std::endl;
} else {
std::cout <<"false train em" << std::endl;
}
}
我能做些什么来访问存储在标签中的整数?
这个stackexchange主题说明,如果我知道矩阵元素类型,我可以使用模板化的at()函数。api声明标签矩阵的类型为$CV_32SC1$。现在访问:
std::cout << labels.at<CV_32SC1>(2,0) << std::endl;
导致以下错误:
invalid template argument for '_Tp', type expected
在创建这个问题的时候,我也100%确定我测试了
std::cout << labels.at<int>(2,0) << std::endl;
也绘制了0(并且应该是1)。在接受答案后,我面前的代码适应性虽然证明我错了。可能是重复的,因为我几个小时没有看到错字,"错字"可能是QT的qdebug()用法,而不是std::cout。如果仍然认为有价值,可以改进我提供的最小示例中的构造函数,并删除这句话和以下内容。我仍然希望有一个一行的解决方案,但我还没有执行。
正确的打印Mat
值的方法是使用operator<<
。你已经有了。
您的cv::Mat labels
类型为CV_32SC1
。它包含32位有符号整数元素。因此,您可以通过labels.at<int>
方法访问项目。
访问项的更好方法是使用迭代器cv::MatIterator_< _Tp >
:
for(cv::MatIterator_<int> it(labels.begin<int>()); it != labels.end<int>(); it++)
{
std::cout << (*it) << std::endl; // int i = *it
}
- OpenCV矩阵奇怪的加法,乘法与浮点数和8位值
- 在C++中使用OpenCV矩阵中的特征将图像旋转90度
- 从 16UC3 到 8UC3 的高性能 OpenCV 矩阵转换
- 将元素从opencv矩阵复制到特征矩阵
- 在 openCV 矩阵中查找列最大值的索引和值
- 如何从OpenCV矩阵转换为k4a_image_t(Azure Kinect SDK)
- 如何将 Openh264 解码帧无延迟输出格式转换为 OpenCV 矩阵
- 如何在 CUDA 中的内核函数中乘以两个 openCV 矩阵?
- 将 OpenCV 矩阵分配给数据结构
- 从3通道矩阵中减去OPENCV矩阵
- 我可以将矢量投入到OpenCV矩阵中吗?
- OPENCV矩阵伪逆失败
- 将Kinect数据转换为OpenCV矩阵
- OpenCV 矩阵和 FileNodeIterator:选择第一次迭代
- 在 GPU 的 opencv 矩阵缩减中可能存在的错误
- 为什么此OpenCV矩阵的大小和值不正确
- OpenCV 矩阵乘法断言
- 访问 opencv 矩阵CV_32S元素
- C++类和OpenCV矩阵操作之间的转换
- 如何根据C++中的数据类型打印 OpenCv 矩阵