0

我正在尝试使用存储在匹配功能函数内的 JSON 文件中的数据,使用 opencv4nodejs。存储的数据是来自先前计算的图像的描述符。当数据被计算然后在代码中使用时一切正常,但从 JSON 文件中获取时却不行。数据类型为cv.Mat,然后使用方法存储在 JSON 文件中fs.writeFileSync()。问题是下一个使用这些描述符的函数需要一个 type 的变量cv.Mat,而 JSON 数据不被认为是这样的。如何使用存储在 JSON 文件中的这些数据?

这个过程在 c++ 中完美地工作,使用cv::FileStorage方法。JSON 文件如下所示:

{
    "first": {
        "type_id": "opencv-matrix",
        "rows": 69,
        "cols": 128,
        "dt": "f",
        "data": [ 2.76096805e-04, 7.95492728e-04, 4.21693228e-04, (...)
},
    "second": {
        "type_id": "opencv-matrix",
        "rows": 45,
        "cols": 128,
        "dt": "f",
        "data": [ 3.94702045e-04, 1.63780281e-03, -2.23156996e-03, (...)
    }
}

JSON 文件显示存储的数据,可用于存储cv::Mat带有运算符的变量>>

我无法使用 opencv4nodejs 5.5.0 版在 node.js 中重现此过程。JSON.stringify()我使用变量上的方法保存了JSON文件cv.Mat,然后fs.writeFileSync()从包中保存了方法来存储描述符(不幸的是,在opencv4nodejs中fs似乎没有等价物)。cv::FileStorage首先,我无法在创建的 JSON 文件中看到任何数据:

{"first":{"step":512,"elemSize":4,"sizes":[69,128],"empty":0,"depth":5,"dims":2,"channels":1,"type":5,"cols":128,"rows":69},
"second":{"step":512,"elemSize":4,"sizes":[45,128],"empty":0,"depth":5,"dims":2,"channels":1,"type":5,"cols":128,"rows":45}}

我尝试sizes通过方法访问元素first.sizes,但它只返回数组的大小,而不是里面的数据。我徒劳地搜索了一种访问 JSON 文件中不可见数据的方法。对此有所了解会很棒。更重要的是,我不能在下一个函数中使用这些描述符,因为它需要一个cv.Mat类型。

MSERDetector::MatchKnn - Error: expected argument 0 to be of type Mat

我探索了两种解决方案,到目前为止没有成功:

  • 格式化 JSON 文件。我试图创建一个 JSON 数组,但它没有效果:
["first":{"step":512,"elemSize":4,"sizes":[69,128],"empty":0,"depth":5,"dims":2,"channels":1,"type":5,"cols":128,"rows":69},
"second":{"step":512,"elemSize":4,"sizes":[45,128],"empty":0,"depth":5,"dims":2,"channels":1,"type":5,"cols":128,"rows":45}]

我还尝试添加一个名为的密钥mat(我知道这是一个愚蠢的密钥,不知道如何格式化我的 JSON 文件,因为我在网上找不到任何文档):

{"mat":{"first":{"step":512,"elemSize":4,"sizes":[69,128],"empty":0,"depth":5,"dims":2,"channels":1,"type":5,"cols":128,"rows":69}},
"second":{"step":512,"elemSize":4,"sizes":[45,128],"empty":0,"depth":5,"dims":2,"channels":1,"type":5,"cols":128,"rows":45}}
  • 将 JSON 数据转换为cv.Mat. 我首先使用 读取文件fs.readFileSync(),然后使用方法解析文件JSON.parse()。当试图用 转换这个变量时new cv.Mat(),它返回一个空矩阵。我还尝试手动填充它:
const descriptors_first = new cv.Mat(descriptors.first.rows, descriptors.first.cols, descriptors.first.type, descriptors.first.channels, descriptors.first.depth, descriptors.first.dims, descriptors.first.empty, descriptors.first.step, descriptors.first.elemSize, descriptors.first.sizes);

这一次,它返回一个cv.Mat变量,显示与刚刚计算的 {keys:values} 完全相同的变量,但给出了错误的结果。它就像里面根本没有存储任何数据一样。

也许我的问题可以更准确:有没有办法表明 JSON 文件是 type cv.Mat,如果是,如何在 opencv4nodejs 中这样做?我们看到cv::FileStorage在创建文件时指定了一个类型,"type_id": "opencv-matrix". 但我找不到任何有关 opencv4nodejs 的文档或示例。第二个,如何将 JSON 数据转换为cv.Mat,以一种实际使用假定存储在 JSON 文件中的数据填充几乎创建的变量的方式?问题可能是文件不包含数据,因为我没有发现任何查看它们的可能性。奇怪的是,我什至看不到console.log(). 在描述符cv.Mat变量上,它显示:

Mat {
  step: 512,
  elemSize: 4,
  sizes: [ 69, 128 ],
  empty: 0,
  depth: 5,
  dims: 2,
  channels: 1,
  type: 5,
  cols: 128,
  rows: 69
}

在解析的 JSON 文件上:

{
  first: {
    step: 512,
    elemSize: 4,
    sizes: [ 69, 128 ],
    empty: 0,
    depth: 5,
    dims: 2,
    channels: 1,
    type: 5,
    cols: 128,
    rows: 69
  }
}

欢迎任何帮助,无论如何感谢您阅读我的问题。

4

1 回答 1

0

好吧,我写这个作为答案,因为评论太长了。这就是您打开YAML文件并将其数据存储在 OpenCV 矩阵中的方式。YAML 文件中的数据根据​​“标签”存储。我们可以在一个文件中定义多个矩阵的多个标签。

因此,例如,包含矩阵数据的文件可能如下所示:

myInputFile.yml:

myMatrix: !!opencv-matrix
   rows: 2
   cols: 2
   dt: f
   data: [ 5.8485,  12.6626,
           6.6515,  11.0982 ]

该文件定义了一个 2 x 2 矩阵。数据类型由dt标签定义,在本例中为float。检索此数据的方式是请求myMatrix标签,并使用空矩阵作为接收器。我不知道 OpenCV java 的语法;在 C++ 中,这就是你的做法:

//let's read the external YAML file:
std::string fileStoragePath = "myInputFile.yml";

//use OpenCv's file system to open the file:
cv::FileStorage inputFile( fileStoragePath, cv::FileStorage::READ );

//let's check if the file can be actually opened…
if ( !inputFile.isOpened() ){
   std::cout << "Encountered an error while opening the file!" <<std::endl;
}

//parse the data in the input file to a matrix:
cv::Mat dataMatrix;

//Now, give me a label, and I will give you the data of that label:
std::string fieldName = "myMatrix";
inputFile [ fieldName ] >> dataMatrix;

您的浮动数据应该在dataMatrix并且您可以正常处理它。

于 2020-02-04T06:15:01.453 回答