I’m trying to load image from string like as PHP function imagecreatefromstring
How can I do that?
I have MySQL blob field image. I’m using MySQLdb and don’t want create temporary file for working with images in PyOpenCV.
NOTE: need cv (not cv2) wrapper function
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
This is what I normally use to convert images stored in database to OpenCV images in Python.
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)
I have added the conversion from numpy.ndarray to cv2.cv.iplimage, so the script above will print:
<type 'str'> <type 'numpy.ndarray'> <type 'cv2.cv.iplimage'>
EDIT:
As of latest numpy 1.18.5 +, the np.fromstring raise a warning, hence np.frombuffer shall be used in that place.
Method 2
I think this answer provided on this stackoverflow question is a better answer for this question.
Quoting details (borrowed from @lamhoangtung from above linked answer)
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)
Method 3
I’ve try to use this code to create an opencv from a string containing a raw buffer (plain pixel data) and it doesn’t work in that peculiar case.
So here’s how to do that for this kind of data:
image = np.fromstring(im_str, np.uint8).reshape( h, w, nb_planes )
(but yes you need to know your image properties)
if your B and G channel is permuted, here’s how to fix it:
image = cv2.cvtColor(image, cv2.cv.CV_BGR2RGB)
Method 4
I was following the solution from @jabaldonedo but it seems it’s a bit old and need some adjustments.
I am using OpenCV 3.4.8.29 by the way.
im_path = 'path/to/foo.jpg'
with open(im_path, 'rb') as fp:
im_b = fp.read()
image_np = np.frombuffer(im_b, np.uint8)
img_np = cv2.imdecode(image_np, cv2.IMREAD_COLOR)
im_cv = cv2.imread(im_path)
print('Same image: {}'.format(np.all(im_cv == img_np)))
Same image: True
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0