【问题标题】:Convert base64 String to an Image that's compatible with OpenCV将 base64 字符串转换为与 OpenCV 兼容的图像
【发布时间】:2017-08-28 16:14:37
【问题描述】:

我正在尝试将 JPEG 的 base64 表示转换为可与 OpenCV 一起使用的图像。问题是我希望能够做到这一点而不必实际保存照片(我希望它保留在内存中)。有没有更新的方法来完成这个?

我正在使用 python 3.6.2 和 OpenCV 3.3

这是我尝试转换的输入类型的部分示例:

/9j/4AAQSkZJRgABAQAASABIAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAA....

我已经尝试过这些问题提供的解决方案,但总是收到相同的“内置操作的参数类型错误”错误:

【问题讨论】:

  • 什么是抛出错误的参数异常?一旦将 base64 转换为 numpy 数组,我认为您应该能够使用 OpenCV 的 imdecode 函数。
  • 将您自己的代码和图像数据添加到问题中,以便我们查看是否可以重新创建您遇到的错误。

标签: python opencv


【解决方案1】:

这是一个使用 imageio 而不是 PIL 的 python 3.6 示例。它首先加载图像并将其转换为 b64_string。然后可以发送此字符串并按如下方式重建图像:

import base64
import io
import cv2
from imageio import imread
import matplotlib.pyplot as plt

filename = "yourfile.jpg"
with open(filename, "rb") as fid:
    data = fid.read()

b64_bytes = base64.b64encode(data)
b64_string = b64_bytes.decode()

# reconstruct image as an numpy array
img = imread(io.BytesIO(base64.b64decode(b64_string)))

# show image
plt.figure()
plt.imshow(img, cmap="gray")

# finally convert RGB image to BGR for opencv
# and save result
cv2_img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
cv2.imwrite("reconstructed.jpg", cv2_img)
plt.show()

【讨论】:

  • 什么是 imageio lib?那是python3.6的默认库吗?
【解决方案2】:

我已经为这个问题苦苦挣扎了一段时间,当然,一旦我发布了一个问题 - 我就明白了。

对于我的特定用例,我需要先将字符串转换为 PIL 图像以在另一个函数中使用,然后再将其转换为 numpy 数组以在 OpenCV 中使用。您可能会想,“为什么要转换为 RGB?”。我添加这个是因为当从 PIL Image -> Numpy 数组转换时,OpenCV 的图像默认为 BGR。

无论如何,这是我的两个帮助函数,它们解决了我自己的问题:

import io
import cv2
import base64 
import numpy as np
from PIL import Image

# Take in base64 string and return PIL image
def stringToImage(base64_string):
    imgdata = base64.b64decode(base64_string)
    return Image.open(io.BytesIO(imgdata))

# convert PIL Image to an RGB image( technically a numpy array ) that's compatible with opencv
def toRGB(image):
    return cv2.cvtColor(np.array(image), cv2.COLOR_BGR2RGB)

【讨论】:

    【解决方案3】:

    你也可以试试这个:

    import numpy as np
    import cv2
    
    def to_image_string(image_filepath):
        return open(image_filepath, 'rb').read().encode('base64')
    
    def from_base64(base64_data):
        nparr = np.fromstring(base64_data.decode('base64'), np.uint8)
        return cv2.imdecode(nparr, cv2.IMREAD_ANYCOLOR)
    

    您现在可以像这样使用它:

    filepath = 'myimage.png'
    encoded_string = to_image_string(filepath)
    

    像这样用打开的简历加载它:

    im = from_base64(encoded_string)
    cv2.imwrite('myloadedfile.png', im)
    

    【讨论】:

      【解决方案4】:

      这里有一些可能有用的命令

      import io
      import cv2
      import base64 
      import numpy as np
      from PIL import Image
      
      #convert image to byte type
      with open("tes-img/example27.png", "rb") as image_file:
          encoded_string1 = base64.b64encode(image_file.read())
      
      #convert byte to string
      encoded_string = encoded_string1.decode("utf-8")
      
      #convert string to byte
      base64_image = str.encode(encoded_string)
      
      #save image locally
      with open("tes-img/example27_2.png", "wb") as fh:
          fh.write(base64.decodebytes(base64_image))
      
      #convert byte to numpy array for cv2 
      img_color = cv2.cvtColor(np.array(Image.open(io.BytesIO(base64.b64decode(base64_image)))), cv2.COLOR_BGR2RGB)
      

      【讨论】:

        【解决方案5】:

        我已经尝试了所有这些方法,但对我不起作用,并且出现了无法识别的编码错误。

        适合我的脚本。使用请求直接下载图像并使用 PIL 显示

        import requests
        from io import BytesIO
        import base64
        from PIL import Image
        def image_show(image_url=None):
            img_response = requests.get(image_url)
            if img_response.ok:
                image_bytes = BytesIO(base64.b64decode(base64.b64encode(img_response.content)))
                img = Image.open(image_bytes)
                return img
            else:
                print("invalid image url response")
        image_show(image_url= 'https://images.unsplash.com/photo-1515628640587-603301d8a4d4?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&dl=shane-stagner-mdS-6oNgRXc-unsplash.jpg')
        

        【讨论】:

        • 该问题不涉及从 URL 获取数据。它特别指定输入数据已经经过 base64 编码。你的答案归结为base64.b64decode(base64.b64encode(...)),它根本不涉及 OpenCV
        猜你喜欢
        • 2018-09-07
        • 2014-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-14
        • 2011-06-17
        • 1970-01-01
        相关资源
        最近更新 更多