【问题标题】:OpenCV 3.0 - How can I create a cv::Mat from CSV string?OpenCV 3.0 - 如何从 CSV 字符串创建 cv::Mat?
【发布时间】:2016-02-28 06:11:29
【问题描述】:

我正在尝试从一个 CSV 字符串创建一个 cv::Mat,该字符串是我从 python 脚本管道传输的。我目前正在使用 python 2.7、C++ 和 OpenCV 3.0,我能找到的只是如何在 OpenCV 2.4 中执行此操作,但问题是它与使用 ml::TrainData 的 3.0 有很大不同。我不明白它是如何工作的,也没有示例代码! :-(

我的 python 脚本所做的是将 np.array 作为 CSV 进行管道传输,它看起来像这样:

import sys
import numpy as np
import csv


csvToSend = csv.writer(sys.stdout, delimiter=',')

data = np.array([ [3, 7, 9],
               [1, 7, 0],
               [4, 12, 8]])

csvToSend.writerows(data)

python-script目前正在模拟相机发送bgr RAW格式的图片。

管道数据由我的 C++ 代码接收,这就是代码目前的样子:

#include <iostream>
#include <string>
#include <opencv2/core/core.hpp>

using namespace std;
using namespace cv;

string values = "", csvPart;
Mat img;
int i;

int main()
{
    for (i = 0; i < 3; i++)
    {

        cin >> csvPart; //here I get my CSV lines from python-script

        if (values == "") values = values + csvPart;

        else values = values + "\n" + csvPart;  //makes the CVS lines look like a 3x3 matrix again
    }

    cout << values << endl; //prints the CVS to see that it looks like it did before piping it over to the C++ code

    /* how the printed string looks like
    3,7,9 
    1,7,0
    4,12,8    */

/*      Here I want to load the "values" into the Mat img
        so I can do my mojo with openCV in C++          */
}

如果有人能帮我解决这个问题并给我一个简单的代码示例,我将不胜感激。 如果有更好的方法将 np.array 传递到 C++ 代码并将其加载到 cv::Mat 中,我会为你敞开怀抱! ;-)

【问题讨论】:

  • 更好的方法是使用 FileStorage(xml 或 yml)来传递矩阵(但我忽略它是否也可以在 Python 中使用)。
  • 如果我理解正确,那么使用 xml 或 yml 会花费更多的时间/过程,除非它加快了过程,否则不需要保存数据。可能会提到我使用 Raspberry Pi 2 来运行我的代码。 @三木
  • ...看起来我在上面的代码 cmets 中写了 /*如何打印字符串...@Miki
  • 你知道行、列和通道吗?或者你应该从数据中推断出它们?可能至少必须先验地知道通道的数量。
  • 另外,你不能只发送base64编码的图像数据,而不是通过csv吗?

标签: c++ csv opencv opencv3.0 opencv-mat


【解决方案1】:

csv 文件的每一行代表一行。如果您的图像是 1 个通道,则每个值都是像素的灰度值:

1,2,3 
4,5,6 
7,8,9 

生成的 3x3 1 通道图像为:

如果您的图像是 3 通道,则每行中的 3 个连续值代表一个 bgr 三元组。比如这个:

1,2,3,200,100,200
4,5,6,47,205,103
7,8,9,95,23,209

生成 3x2 3 通道图像:

loadFromCSV函数接受csv内容的字符串,以及OpenCV图像类型,并返回图像:

Mat loadFromCSV(const string& values, int opencv_type);

查看完整代码:

#include <opencv2\opencv.hpp>
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
using namespace cv;

Mat loadFromCSV(const string& values, int opencv_type)
{
    Mat m;

    stringstream ss(values);
    string line;
    while (getline(ss, line))
    {
        vector<double> dvals;

        stringstream ssline(line);
        string val;
        while (getline(ssline, val, ','))
        {
            dvals.push_back(stod(val));
        }

        Mat mline(dvals, true);
        transpose(mline, mline);

        m.push_back(mline);
    }

    int ch = CV_MAT_CN(opencv_type);

    m = m.reshape(ch);
    m.convertTo(m, opencv_type);
    return m;
}

int main()
{
    string values = "1,2,3\n4,5,6\n7,8,9";
    Mat img = loadFromCSV(values, CV_8UC1);
    //Mat img = loadFromCSV(values, CV_8UC3);

    //string values = "1,2,3,200,100,200\n4,5,6,47,205,103\n7,8,9,95,23,209";
    //Mat img = loadFromCSV(values, CV_8UC3);

    cout << "Img:" << endl;
    cout << img << endl;

    imshow("Img", img);
    waitKey();

    return 0;
}

【讨论】:

  • 看起来好像误解了 BGR 矩阵的样子,np.array 只是在那里,所以我可以将一些东西传递给 C++ 代码。正如您在上面显示的那样,我会将我的 np.array 更改为外观正确的 BGR,感谢您的回答,我会在尝试您的示例后回复您;-) @Miki
  • 工作就像一个魅力! :-)
猜你喜欢
  • 2017-03-01
  • 1970-01-01
  • 2013-10-21
  • 2013-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多