【问题标题】:Convert cv::Mat to std::vector<double> complications [duplicate]将 cv::Mat 转换为 std::vector<double> 并发症 [重复]
【发布时间】:2018-05-23 10:34:01
【问题描述】:

我必须处理一个 .PNG 文件。 该处理将 std::vector 作为输入,并且 我想将图像显示为灰度。 所以我做了什么:

Mat img = imread("Image.PNG");
cvtColor(img, img, COLOR_RGB2GRAY);
imshow(windowName,img); 

这张图片看起来不错,cout&lt;&lt;img&lt;&lt;endl; 吐出 0 到 255 之间的真实值。 然后我想将此 cv::Mat 转换为 std::vector

std::vector<double> imgvec;
imgvec.assign(img.begin<double>(), img.end<double>());

这些值现在都非常小(大约 1e-180)。为什么会发生这种情况,我该如何解决?

更新:

我按照@Swift-Friday Pie 的建议尝试了以下方法:

std::vector<double> imgvec;
if (img.isContinuous()){
    imgvec.assign((double*)img.datastart, (double*)img.dataend);
}else{
    for (int i = 0; i < img.rows; i++){
        imgvec.insert(imgvec.end(), img.ptr<double>(i) + img.cols);
    }
}

但是,这给了我以下错误:

no matching function for call to 'std::vector<double>::insert(std::vector<double>::iterator, double*)'

【问题讨论】:

  • 如果需要unsigned char,为什么要使用double
  • @zindarod 因为处理部分是一个以std::vector&lt;double&gt;为输入的外部库
  • 您更新中的第一个if 分支肯定是不正确的。 img 不以双精度格式存储数据,因此将数据字节当作双精度来读取会产生垃圾。我怀疑这与img.begin&lt;double&gt;() 存在相同的问题,但我对 OpenCV 迭代器的了解不足以肯定地说。同样的错误发生在第二个分支中,除了你试图将指向数据的指针写入向量(而不是它指向的数据)。

标签: c++ opencv


【解决方案1】:

您没有将正确的参数传递给插入函数,它需要三个参数。 所以更新后的代码将是,

 std::vector<double> imgvec;
if (palette.isContinuous()) {
    imgvec.assign(palette.datastart, palette.dataend);  // No need to typecast to double * 
}
else {
    for (int i = 0; i < palette.rows; i++) {
        imgvec.insert(imgvec.end(), palette.ptr<double>(i),palette.ptr<double>(i) + palette.cols);
    }
}

您的代码中的错误是关于类型转换为 double*

【讨论】:

  • 其实有four overloadsstd::vector&lt;T&gt;::insert 带两个参数(没有一个带四个参数)
  • 哦对不起三个参数
【解决方案2】:

我会这样做,你可以试试吗?

#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>


template <typename T, typename ... Ts>
void insert_all(std::vector<T> &vec, Ts ... ts)
{
   (vec.push_back(ts), ...);
}

int main ()
{
 cv::Mat img = cv::imread("Image.PNG");
 cv::cvtColor(img, img, cv::COLOR_RGB2GRAY);
 std::vector<cv::Mat> imgvec;
 imgvec.reserve(1);
 insert_all(imgvec, img);
} 

g++ -std=c++17 test.cpp -o test `pkg-config --cflags --libs opencv`

【讨论】:

  • 当我按照您编写的代码实现时,出现以下错误:MainConfMap.cpp: In function ‘void insert_all(std::vector&lt;_Tp&gt;&amp;, Ts ...)’: MainConfMap.cpp:19:22: error: expected primary-expression before ‘...’ token MainConfMap.cpp:19:22: error: expected ‘)’ before ‘...’ token MainConfMap.cpp:19:26: error: parameter packs not expanded with ‘...’: MainConfMap.cpp:19:26: note: ‘ts’
  • 我使用了仅在 c++17 中可用的折叠表达式。因此,请确保您使用 std=c++17 进行编译
猜你喜欢
  • 2017-09-29
  • 1970-01-01
  • 2018-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-01
  • 2012-04-19
  • 1970-01-01
相关资源
最近更新 更多