47

I'm working with PyOpenCV. How to convert cv2 image (numpy) to binary string for writing to MySQL db without a temporary file and imwrite?

I googled it but found nothing...

I'm trying imencode, but it doesn't work.

capture = cv2.VideoCapture(url.path)
capture.set(cv2.cv.CV_CAP_PROP_POS_MSEC, float(url.query))
self.wfile.write(cv2.imencode('png', capture.read()))

Error:

  File "server.py", line 16, in do_GET
  self.wfile.write(cv2.imencode('png', capture.read()))
  TypeError: img is not a numerical tuple

Help somebody!

1
  • question arose due to a TYPO. capture.read() returns a tuple (result, value), not just a numpy array. if OP had debugged this (not a minimal reproducible example...), they would have found this, and fixed it, and everything would have worked fine. Commented Jul 20 at 17:18

6 Answers 6

82

If you have an image img (which is a numpy array) you can convert it into string using:

>>> img_str = cv2.imencode('.jpg', img)[1].tostring()
>>> type(img_str)
 'str'

Now you can easily store the image inside your database, and then recover it by using:

>>> nparr = np.fromstring(STRING_FROM_DATABASE, np.uint8)
>>> img = cv2.imdecode(nparr, cv2.CV_LOAD_IMAGE_COLOR)

where you need to replace STRING_FROM_DATABASE with the variable that contains the result of your query to the database containing the image.

Sign up to request clarification or add additional context in comments.

2 Comments

have to use cv2.imdecode(nparr, cv2.IMREAD_COLOR) for opencv3.0+
isn't tobytes() better than tostring(), just as numpy recommends using frombuffer() instead of fromstring()?
14

It works in 2020 with numpy==1.19.4 and opencv==4.4.0:

import cv2

cam = cv2.VideoCapture(0)

# get image from web camera
ret, frame = cam.read()

# convert to jpeg and save in variable
image_bytes = cv2.imencode('.jpg', frame)[1].tobytes()

Comments

7

Here is an example:

def image_to_bts(frame):
    '''
    :param frame: WxHx3 ndarray
    '''
    _, bts = cv2.imencode('.webp', frame)
    bts = bts.tostring()
    return bts

def bts_to_img(bts):
    '''
    :param bts: results from image_to_bts
    '''
    buff = np.fromstring(bts, np.uint8)
    buff = buff.reshape(1, -1)
    img = cv2.imdecode(buff, cv2.IMREAD_COLOR)
    return img

Comments

6
im = cv2.imread('/tmp/sourcepic.jpeg')
res, im_png = cv2.imencode('.png', im)
with open('/tmp/pic.png', 'wb') as f:
    f.write(im_png.tobytes())

Comments

5

capture.read() returns a tuple, (err,img).

try splitting it up:

_,img = capture.read()
self.wfile.write(cv2.imencode('png', img))

3 Comments

it returns (True, array([[137], [ 80], [ 78], ..., [ 66], [ 96], [130]], dtype=uint8)), but not a byte string
How to convert that to byte string?
my solution is self.wfile.write(numpy.array(cv2.imencode('.png', img)[1]).tostring())
3

My code to use opencv with python cgi :

    im_data = form['image'].file.read()
    im = cv2.imdecode( np.asarray(bytearray(im_data), dtype=np.uint8), 1 )
    ret, im_thresh = cv2.threshold( im, 128, 255, cv2.THRESH_BINARY )
    self.send_response(200)
    self.send_header("Content-type", "image/jpg")
    self.end_headers()      
    ret, buf = cv2.imencode( '.jpg', im_thresh )
    self.wfile.write( np.array(buf).tostring() )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.