【问题标题】:Python OpenCV load image from byte stringPython OpenCV从字节字符串加载图像
【发布时间】:2021-08-06 13:00:33
【问题描述】:

我正在尝试从字符串中加载图像,例如 PHP 函数 imagecreatefromstring

我该怎么做?

我有 MySQL blob 字段图像。我正在使用 MySQLdb 并且不想创建临时文件来处理 PyOpenCV 中的图像。

注意:需要 cv(不是 cv2)包装函数

【问题讨论】:

    标签: python image opencv byte


    【解决方案1】:

    这是我通常用来将存储在数据库中的图像转换为 Python 中的 OpenCV 图像的方法。

    import numpy as np
    import cv2
    from cv2 import cv
    
    # Load image as string from file/database
    fd = open('foo.jpg')
    img_str = fd.read()
    fd.close()
    
    # CV2
    nparr = np.fromstring(img_str, np.uint8)
    img_np = cv2.imdecode(nparr, cv2.CV_LOAD_IMAGE_COLOR) # cv2.IMREAD_COLOR in OpenCV 3.1
    
    # CV
    img_ipl = cv.CreateImageHeader((img_np.shape[1], img_np.shape[0]), cv.IPL_DEPTH_8U, 3)
    cv.SetData(img_ipl, img_np.tostring(), img_np.dtype.itemsize * 3 * img_np.shape[1])
    
    # check types
    print type(img_str)
    print type(img_np)
    print type(img_ipl)
    

    我已经添加了从numpy.ndarraycv2.cv.iplimage 的转换,所以上面的脚本会打印出来:

    <type 'str'>
    <type 'numpy.ndarray'>
    <type 'cv2.cv.iplimage'>
    

    编辑: 从最新的 numpy 1.18.5 + 开始,np.fromstring 会发出警告,因此应在该位置使用 np.frombuffer

    【讨论】:

    • 使用 cv2 和 cv(导入 cv2,从 cv2 导入 cv)。但返回的不是 lplimage 和 cvMat。函数 GetSize 不起作用
    • src=image_create_from_string(str) cv.GetSize(src)
    • 我建议您只使用 cv2,只要它使用在 Python 中比 cvMat 和 lplimage 更有效的 numpy 数组。函数 GetSize 在 cv2 中不起作用,因为 cv2 使用 numpy 并且您使用 np.shape(image) 来获取图像的大小。无论如何,如果您想将表单 cv2 ndarray 转换为 cv lplimage,请查看以下答案:stackoverflow.com/questions/11528009/…
    • 对于 OpenCV 3+ 使用 cv2.IMREAD_COLOR 而不是 cv2.CV_LOAD_IMAGE_COLOR
    • np.fromstring 现在已弃用,我们应该使用 np.frombuffer。其次,如果我们在 np.frombuffer 中使用原始字符串,它不会提供适当的 numpy 数组。因此,最好使用 base64 库来更好地读取字符串 something 链接base64.b64decode(string)。最后,我认为这里的答案 (stackoverflow.com/a/58406222/1522905) 更适合这个问题。
    【解决方案2】:

    我认为thisstackoverflow 问题上提供的this 答案是这个问题的更好答案。

    引用细节(从上面链接的答案中借用@lamhoangtung)

    import base64
    import json
    import cv2
    import numpy as np
    
    response = json.loads(open('./0.json', 'r').read())
    string = response['img']
    jpg_original = base64.b64decode(string)
    jpg_as_np = np.frombuffer(jpg_original, dtype=np.uint8)
    img = cv2.imdecode(jpg_as_np, flags=1)
    cv2.imwrite('./0.jpg', img)
    

    【讨论】:

    • 为了更详细:img = cv2.imdecode(jpg_as_np, cv2.IMREAD_COLOR)
    【解决方案3】:

    我尝试使用此代码从包含原始缓冲区(普通像素数据)的字符串创建一个 opencv,但在这种特殊情况下它不起作用。

    以下是对此类数据执行此操作的方法:

    image = np.fromstring(im_str, np.uint8).reshape( h, w, nb_planes )
    

    (但是你需要知道你的图像属性)

    如果您的 B 和 G 频道被置换,以下是修复方法:

    image = cv2.cvtColor(image, cv2.cv.CV_BGR2RGB)
    

    【讨论】:

    • 我也有这个问题 - 为什么会出现?是否有 any 方法可以像其他答案一样规避 (h,w) 问题?谢谢!
    • 你能更准确地定义你的问题吗?
    • 在这种情况下,没有标题,因此您无法猜测图像属性。 (除非您决定始终接收 4/3 或 16/9 比例的图像)
    猜你喜欢
    • 1970-01-01
    • 2013-07-31
    • 2017-04-17
    • 2017-08-16
    • 2011-02-27
    • 1970-01-01
    • 2012-11-05
    • 2021-09-13
    相关资源
    最近更新 更多