【发布时间】:2020-02-03 21:57:07
【问题描述】:
我正在尝试使用存储在匹配功能函数内的 JSON 文件中的数据,使用 opencv4nodejs。存储的数据是来自先前计算的图像的描述符。当数据被计算然后在代码中使用时一切正常,但从 JSON 文件中获取时却不行。
数据类型为cv.Mat,然后使用fs.writeFileSync() 方法存储在JSON 文件中。问题是使用这些描述符的下一个函数需要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 中重现此过程。
我使用cv.Mat 变量上的JSON.stringify() 方法保存了JSON 文件,然后使用fs 包中的fs.writeFileSync() 方法来存储描述符(不幸的是,在opencv4nodejs 中似乎没有与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}}
我尝试通过first.sizes方法访问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 文件的类型为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
}
}
欢迎任何帮助,无论如何感谢您阅读我的问题。
【问题讨论】:
-
将您的输出放入一个变量中并作为字典访问它们。例如,
output = {"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}}你会得到[69, 128]的东西output["first"]["sizes"]。 -
您可以使用 OpenCV 的文件系统在本地以 YAML 格式存储和检索来自 OpenCV 浮点矩阵的浮点数据,完全无需外部 JSON 解析器。如果可能的话,我建议采用前一种方法,因为它更容易、更快捷!
-
谢谢@testuser。实际上,console.log(output["first"]["sizes"]) 返回 [69, 128]。但我仍然无法访问任何数据,也无法使用此输出,因为它未被识别为
cv.Mat类型。 -
谢谢@eldesgraciado。我为 node.js 安装了
js-yaml模块。我用yaml.load(fs.writeFileSync("./uploads/descriptors.yml", descriptors_first));创建了 yml 文件。这次文件只包含[object Mat],由于不是cv.Mat类型,所以还是不能使用。
标签: node.js json opencv opencv4nodejs