【问题标题】:How to store an Image as a 1*n floating point vector?如何将图像存储为 1*n 浮点向量?
【发布时间】:2013-10-04 18:12:16
【问题描述】:

我试图从通过网络摄像头获得的图像中获取一个名为 testdata 的单个浮动向量。一旦将图像转换为单个浮动向量,它就会传递给经过训练的神经网络。为了测试网络,我使用函数 float CvANN_MLP ::predict(const Mat& inputs, Mat& outputs)。这个函数需要一个测试样本,格式如下:-

输入向量的浮点矩阵,每行一个向量。

testdata向量定义如下:-

// define testing data storage matrices
//NumberOfTestingSamples is 1 and AttributesPerSample is number of rows *number of columns

Mat testing_data = Mat(NumberOfTestingSamples, AttributesPerSample, CV_32FC1);

要以 CSV 格式存储图像的每一行,我执行以下操作:-

Formatted row0= format(Image.row(0),"CSV" ); //Get all rows to store in a single vector
Formatted row1= format(Image.row(1),"CSV" ); //Get all rows to store in a single vector
Formatted row2= format(Image.row(2),"CSV" ); //Get all rows to store in a single vector
Formatted row3= format(Image.row(3),"CSV" ); //Get all rows to store in a single vector

然后,我将存储在 row0 到 row3 中的所有格式化行输出到一个文本文件中,如下所示:-

store_in_file<<row0<<", "<<row1<<", "<<row2<<", "<<row3<<endl;

这会将整个 Mat 存储在一行中。

文本文件已关闭。我重新打开相同的文本文件以提取数据以存储到向量 testdata 中

 // if we can't read the input file then return 0

 FILE* Loadpixel = fopen( "txtFileValue.txt", "r" );

 if(!Loadpixel) // file didn't open
{
    cout<<"ERROR: cannot read file \n";
    return 0; // all not OK;
}
for(int attribute = 0; attribute < AttributesPerSample; attribute++)
{
            fscanf(Loadpixel, "%f,",&colour_value);//Reads a single attribute and stores it in colour_value
            testdata.at<float>(0, attribute) = colour_value;
}

这可行,但是一段时间后文件无法打开并显示错误消息:“错误:无法读取文件”。此方法有很多限制,需要花费不必要的时间存储在文本文件中和然后重新打开并提取。将图像(Mat)存储到类似于testdata.at&lt;float&gt;(0, attribute) 的单个浮点向量中的最佳方法是什么?或者有没有一种简单的方法来确保文件总是打开,基本上是正确的问题?

【问题讨论】:

  • 您可能想弄清楚FormattedImage 是什么。
  • 您确实意识到您所写的内容在您的脑海中可能是有道理的,但对其他人来说却完全是晦涩难懂的?为其添加一些上下文,描述这些“向量”是什么,为使用的变量提供声明,描述问题的“大图”。
  • 我刚刚更新了发布的问题,以更详细地解释我实现了什么,希望这会有所帮助。变量“图像”是从网络摄像头获得的垫子。使用 opencv,垫子可以从默认格式为 CSV 格式,使用:- Formatted row0= format(Image.row(0),"CSV" );
  • 知道为什么文件打开超过 1000 次然后无法打开吗?有没有办法纠正这个问题,如果不是最好的选择是什么?
  • 我的水晶球说你缺少 fclose,因此你没有文件描述符。

标签: c++ visual-studio-2010 visual-studio visual-c++


【解决方案1】:

理智的解决方案当然是直接在内存中转换值。正如您所怀疑的,整个中间文件是一个令人难以置信的组合。

如果您要使用标准 C++ 类型,例如 std::vector,我们可以提供实际代码。与您的代码等效的简单算法是一次遍历您的 2D 图像一个像素,并将每个像素的值附加到 1D 向量的后面。

但是,无论如何,这对于网络摄像头图像的神经网络处理来说是个坏主意。如果您的输入向下移动一个像素 - 完全有可能 - 整个 1D 矢量会发生变化。因此,建议首先标准化您的输入。这可能需要先平移、缩放和旋转图像。

[编辑] 标准 C++ 示例:

std::vector<std::vector<int>> Image2D;
std::vector<float> Vector1D;
for (auto const& row : Image2D) {
  for (auto pixel : row) { 
    Vector1D.push_back(pixel);
  }
}

【讨论】:

  • 图像被裁剪为标准尺寸,然后归一化,均衡化并转换为二进制图像。这个过程是正确的并且预测很好,问题是在一定数量的图像之后文件没有打开,我不想使用文本文件来获取图像的浮点向量。请问您可以通过提供示例详细说明您建议的方法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多