首页 > 解决方案 > 在python中导入opencv mat(用c#压缩)

问题描述

我在 python 中解码/解压缩字符串时遇到问题,该字符串最初是使用带有“GZipStream”的 C# 压缩的。

“opencv mat”被转换为json:

public override void WriteJson(JsonWriter writer, Mat value, JsonSerializer serializer)
{
    byte[] matBytes = null;
    Cv2.ImEncode(".png", value, out matBytes);

    // Convert byte[] to Base64 String
    string matBase64 = Convert.ToBase64String(matBytes);

    var resCompressed = Utils.StringCompressor.CompressString(matBase64);
    writer.WriteValue(resCompressed);
}

要解压缩的示例字符串“jsontoken”是:

uAoAAB+LCAAAAAAABADtls3SsrgWhS+IASogOOiB/GgS/gkqMlMUgkFEEGK8+o7v1931DU7VqTqzU9UMfDS1srPY2dmx3pthwmbutnqsxRPgHXF2lfj28xNU1vrniceHr34HPrPGifeJur4q5nqHdocErlnx0YH8eA2fZwhrsz4q2epTEWRSyjESqDjO0VogzpFPK/yDWgD69I5jJLDFKYLOL1ABGyFKLYGfIOa/sf6XWJGbAaDW9kzmUryc6FDcpQMGmbYGaKIGka8J4ZmGYFnC9co1ahpOs+JKpXRhE6O6zQg/qtdIzLuNp9YGmgWgfr8wTcImDzVaBAF3wkTxU5KP2MSRflTPZ1rsbtInBAttu4HRqLPTNX5jW78bfkudHZEWEphoOKYyOtsKTzKk3GU2N9o5z7Xe8OGYeih8L+4c7JEy7hi2NM8gS3DIUELbQv0gv6f9x1ZjHZq7RtKzdakBSCflpG4U+KaNsVTWkrYZ7hMIl24GW7phmpLUmmP0Ys0c9NT7vAogU79OpvDFbmPco4PQ4KdmGo+vBnlCQwpPplaNp3DF5oudzMchWFF5J5bvi3DVhMazF9qoQa6heZal4732OTjmguqfeoBgQG27OcZRnpYuZ2zJ72PSkPecBkXr2XSCeQczcDmJBMVT+GSknjXXS0DsVfcTEOrWXmMHJ13sJl4N/nPoztQ8Xva5pSCLLXW+OeH2vTjQ04xGn2GA8xcq2/Mx6U5YDjG71ayRioaAVYOM15vAy3/gILj6RbQXfEZ22rtYW19Bd4gbHhvhwWi2dDQu884NUGBourU74/P3XdmBTp92QHRAURsd0yDHkRcc0/1fLPNEdiemuPwmJSWR9hQYTUZkweJvUsH5b2xlcNLWrw4YqrJGw0OhQL14dDujKdMzGLxgS9gYd6ckspuCXFl9zVzVejUbY0zY5ux6mt8S9x5nPI/svKiezo0UZMnqqgjm3HrgcMPh2XJNpmYQESg+yQAfwCZFdXeqZQYfLyg0rmd5pLDuvIap/Sqqq1OJ9dsXVMG6Gx6FY3dFfZ3dqq+GsDicc9Tj0GTe2d2aa6G9//KaiD3+eq3FHn+9bjaN/fXqCt3X6+4eBzw1wv13fqS9R9POY9mNvv5A58kiMNAtoE2G8G8usceEx+wFp+97jYxIV8S2Zxdo7mTvhU/6/Mba6NhThTAe4NQ+C3PL6xD3bJZB2CEZYM0MRI6XPzluafbNsTOjylvkdnNKSiC2Uzklcnhl7chqqViRcN5sjU62L73ra/YIlEN85lkRjgZdiPoo9l0wF/Whn61zjz1NOTifBS0/1YDKAcqtecRzUReuzeZPTsMEkOWeQuMeibOAkg6WIDvhBqcRsEVd/07zhLsvy1Pyw8sp6f9h/FPqp1kjXV5kI2rUUD0L/X526OBfh+5G0bGY53aEaqad+Vas9Z4vaLATR30aoPtCWQuOMTilU+iy6sru12JO1pcmMPrenn6dc12xX3k6uUumLVIdi/4RMGWx0zn59gZpRs+ftvDnTWQ8z7aceyu0FXMsJU9ld8H0hWhntsFGR+LJHpbjhrVS7CJvNRvtFbdzVIp+VI7xGfVvZbw13NbMWXiZHcd4giNRhlrsq9YZ0Yq6YigoSTaQBgf6qzBlGtZYVlMz6mnKD0xPNedBJ0n00KW2MfohLKSkRp788p3DmEzQJO8ND3MYheV7Xoh75PZpjTxDG1oZumzv+S53o1BmTdEccKR4ag5QR2+rmWQn/JpD+TJVvlFVNFAs1c9oTLtBVSAzHP8egK24MB493VdiCK42xS0EEY+jREEeYVKacKz1hQ+4G2Il6ElgtDf6+lzVtIRQC4x68HXuh2kp7okFT6DceXYgChwBOVGP7bcd/H/ey//G+q+x5KpcbVeiPaTR+Gbfv6AmSnaa01NUVdUff/wJwhGNxbgKAAA=

加载此数据的相应 C# 代码是:

private static void CreateDataFromJsonZip(ref ThresholdMask mask, JObject jsonObj, string maskName)
{
    // get JSON result objects into a list
    JToken jsonToken = jsonObj["Selection"]; # jsonToken

    var res = Utils.StringCompressor.DecompressString(jsonToken.ToString());
    byte[] data = Convert.FromBase64String(res);
    mask.Selection = Cv2.ImDecode(data, ImreadModes.Unchanged);

我在 python 中读取数据的尝试是:

jsonToken = r'uAoAAB+LCAAAAAAABADtls3SsrgWhS+IASogOOiB/GgS/gkqMlMUgkFEEGK8+o7v1931DU7VqTqzU9UMfDS1srPY2dmx3pthwmbutnqsxRPgHXF2lfj28xNU1vrniceHr34HPrPGifeJur4q5nqHdocErlnx0YH8eA2fZwhrsz4q2epTEWRSyjESqDjO0VogzpFPK/yDWgD69I5jJLDFKYLOL1ABGyFKLYGfIOa/sf6XWJGbAaDW9kzmUryc6FDcpQMGmbYGaKIGka8J4ZmGYFnC9co1ahpOs+JKpXRhE6O6zQg/qtdIzLuNp9YGmgWgfr8wTcImDzVaBAF3wkTxU5KP2MSRflTPZ1rsbtInBAttu4HRqLPTNX5jW78bfkudHZEWEphoOKYyOtsKTzKk3GU2N9o5z7Xe8OGYeih8L+4c7JEy7hi2NM8gS3DIUELbQv0gv6f9x1ZjHZq7RtKzdakBSCflpG4U+KaNsVTWkrYZ7hMIl24GW7phmpLUmmP0Ys0c9NT7vAogU79OpvDFbmPco4PQ4KdmGo+vBnlCQwpPplaNp3DF5oudzMchWFF5J5bvi3DVhMazF9qoQa6heZal4732OTjmguqfeoBgQG27OcZRnpYuZ2zJ72PSkPecBkXr2XSCeQczcDmJBMVT+GSknjXXS0DsVfcTEOrWXmMHJ13sJl4N/nPoztQ8Xva5pSCLLXW+OeH2vTjQ04xGn2GA8xcq2/Mx6U5YDjG71ayRioaAVYOM15vAy3/gILj6RbQXfEZ22rtYW19Bd4gbHhvhwWi2dDQu884NUGBourU74/P3XdmBTp92QHRAURsd0yDHkRcc0/1fLPNEdiemuPwmJSWR9hQYTUZkweJvUsH5b2xlcNLWrw4YqrJGw0OhQL14dDujKdMzGLxgS9gYd6ckspuCXFl9zVzVejUbY0zY5ux6mt8S9x5nPI/svKiezo0UZMnqqgjm3HrgcMPh2XJNpmYQESg+yQAfwCZFdXeqZQYfLyg0rmd5pLDuvIap/Sqqq1OJ9dsXVMG6Gx6FY3dFfZ3dqq+GsDicc9Tj0GTe2d2aa6G9//KaiD3+eq3FHn+9bjaN/fXqCt3X6+4eBzw1wv13fqS9R9POY9mNvv5A58kiMNAtoE2G8G8usceEx+wFp+97jYxIV8S2Zxdo7mTvhU/6/Mba6NhThTAe4NQ+C3PL6xD3bJZB2CEZYM0MRI6XPzluafbNsTOjylvkdnNKSiC2Uzklcnhl7chqqViRcN5sjU62L73ra/YIlEN85lkRjgZdiPoo9l0wF/Whn61zjz1NOTifBS0/1YDKAcqtecRzUReuzeZPTsMEkOWeQuMeibOAkg6WIDvhBqcRsEVd/07zhLsvy1Pyw8sp6f9h/FPqp1kjXV5kI2rUUD0L/X526OBfh+5G0bGY53aEaqad+Vas9Z4vaLATR30aoPtCWQuOMTilU+iy6sru12JO1pcmMPrenn6dc12xX3k6uUumLVIdi/4RMGWx0zn59gZpRs+ftvDnTWQ8z7aceyu0FXMsJU9ld8H0hWhntsFGR+LJHpbjhrVS7CJvNRvtFbdzVIp+VI7xGfVvZbw13NbMWXiZHcd4giNRhlrsq9YZ0Yq6YigoSTaQBgf6qzBlGtZYVlMz6mnKD0xPNedBJ0n00KW2MfohLKSkRp788p3DmEzQJO8ND3MYheV7Xoh75PZpjTxDG1oZumzv+S53o1BmTdEccKR4ag5QR2+rmWQn/JpD+TJVvlFVNFAs1c9oTLtBVSAzHP8egK24MB493VdiCK42xS0EEY+jREEeYVKacKz1hQ+4G2Il6ElgtDf6+lzVtIRQC4x68HXuh2kp7okFT6DceXYgChwBOVGP7bcd/H/ey//G+q+x5KpcbVeiPaTR+Gbfv6AmSnaa01NUVdUff/wJwhGNxbgKAAA='

string = jsonToken
original = base64.b64decode(string)
convert_to_np = np.frombuffer(original, dtype=np.uint8)
print(convert_to_np)
len(convert_to_np)
img = cv2.imdecode(convert_to_np, cv2.IMREAD_UNCHANGED)

不幸的是,最后一步imdecode不起作用,结果是None. 有什么提示吗?

标签: pythonc#opencvcompression

解决方案


这将完全按照您的要求执行,遵循此 SO 答案StringCompressor.DecompressString中的代码(解压缩的长度存储在前 4 个字节中):

original = base64.b64decode(gzip.decompress(base64.b64decode(jsonToken)[4:]))

但是,我建议简化您的 C# 实现。从原始 OpenCV 垫子开始,您:

  1. 将其编码为 PNG 图像
  2. 将该二进制数据转换为base64字符串
  3. 使用 gzip 压缩文本字符串
  4. 再次转换为base64
  5. 将其存储到 json 文件中

第 2 步是完全没有必要的,第 3 步是多余的,因为 PNG 编码过程已经压缩了图像数据。添加另一层压缩不会有太大帮助,甚至可能会使情况变得更糟。

我只需转换为 PNG,使用 base64 编码,然后将其写入 json 文件。然后您的原始 Python 代码将按预期工作。


推荐阅读