我正在尝试编写一个 TCP 客户端/服务器应用程序来传输包含 OpenCv Mat 的对象。我想使用 JSON 序列化这些对象。我发现一些库可以帮助我做到这一点( rapidjson ),但它们当然不会将图像视为对象成员。
您建议如何在 JSON 对象中序列化 cv::Mat 变量?例如,我如何使用 RapidJson 来实现这一目标?
最佳答案
imencode
可用于将可 View 像(具有 CV_8UC1
或 CV_8UC3
像素格式)编码为 std::vector<uchar>
。 Link to documentation 。
vector<uchar>
将包含相同的字节就像 OpenCV 将图像保存为受支持的图像文件格式之一(例如 JPEG 或 PNG),然后将文件字节加载回字节数组中。
imencode
使用OpenCV 2.x时可以在highgui模块中找到,使用OpenCV 3.x时可以在imgcodecs模块中找到。
压缩后的数据在 vector<uchar>
中,您可以使用 Base64 编码将其格式化为字符串,然后可以将其作为 JSON 值添加到 JSON 对象中。
当使用 JSON 传输大量数据时,请非常仔细考虑指示 JSON 库发出的字符编码格式。通常,如果大部分数据将采用 Base64,您将需要确保 JSON 以 UTF8 格式发出。
如果您可以选择以二进制形式发送(这需要在网络服务中进行“带外”设计,这并不总是可行),那么应该认真考虑。
在考虑图像的不同序列化选择时,应考虑以下事项:
- 典型图像尺寸(像素总数)
- 如果图像很小,则尺寸效率就不太重要。
- 像素格式( channel 数和精度)
- 最常见的图像文件格式仅允许 8 位灰度和 24 位 RGB 像素数据。尝试将更高精度的像素数据保存为这些图像格式将导致部分精度损失。
- 可用的传输带宽(如果它稀缺到足以引起关注)。随着可用带宽的减少,压缩变得更加重要。
- 压缩选项。
- 典型(照片或合成)图像具有高度可压缩性,因为人们普遍认为太“密集”的图像在人眼观看时将难以理解。
- 压缩可以是无损压缩,也可以是有损压缩。
- 压缩的选择可能取决于像素值(图像内容)的统计特征。
- 如上所述,如果通过编码为某些图像格式来进行压缩,您必须确保该图像格式能够满足您的应用程序的像素值精度要求。
- 如果现有图像格式无法满足您的要求,并且您仍想执行无损压缩,请考虑使用
zlib
集成到 OpenCV Core 模块中的 API。 - 如果您擅长图像处理和数据压缩理论,您也许能够根据自己的需求设计出适合应用的压缩方法。
- 请记住,降低图像分辨率可能是减少传输文件大小的有效(且 super 有损)方法。仔细考虑您的应用程序实际需要的最低图像分辨率。
- 其他注意事项
- 二进制或文本
- 字节序
highgui
的可用性,imgcodecs
或接收端所选图像格式的图像解码器。
信息来源:几个月前刚这样做过。
关于c++ - 在 C++ 中使用 JSON 序列化 OpenCv Mat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29350993/