Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read raw png from an array in python opencv?

Tags:

python

opencv

png

I'm streaming a png image from my iPhone to my MacBook over tcp. The MacBook code is from http://docs.python.org/library/socketserver.html#requesthandler-objects. How can the image be converted for use with OpenCV? A png was selected because they are efficient, but other formats could be used.

I wrote a test program that reads the rawImage from a file, but not sure how to convert it:

# Read rawImage from a file, but in reality will have it from TCPServer
f = open('frame.png', "rb")
rawImage = f.read()
f.close()

# Not sure how to convert rawImage
npImage = np.array(rawImage)
matImage = cv2.imdecode(rawImage, 1)

#show it
cv.NamedWindow('display')
cv.MoveWindow('display', 10, 10)
cv.ShowImage('display', matImage)
cv. WaitKey(0)
like image 922
Andy Rosenblum Avatar asked Jul 19 '12 01:07

Andy Rosenblum


People also ask

Can OpenCV read PNG?

So, OpenCV can always read JPEGs, PNGs, and TIFFs.

Does cv2 Imread return an array?

The OpenCV cv2. imread function then returns either of two values: A NumPy array representing the image with the shape (num_rows, num_cols, num_channels) , which we'll discuss later in this tutorial.

What is cv2 Imread ()?

imread() function. cv2. IMREAD_COLOR: It is used to read the image as an RGB image. It ignores the alpha channel present in the image. It is the default value for the flag parameters.

Is cv2 Imread a NumPy array?

The cv2 package provides an imread() function to load the image. It also reads a PIL image in the NumPy array format.


2 Answers

@Andy Rosenblum's works, and it might be the best solution if using the outdated cv python API (vs. cv2).

However, because this question is equally interesting for users of the latest versions, I suggest the following solution. The sample code below may be better than the accepted solution because:

  1. It is compatible with newer OpenCV python API (cv2 vs. cv). This solution is tested under opencv 3.0 and python 3.0. I believe only trivial modifications would be required for opencv 2.x and/or python 2.7x.
  2. Fewer imports. This can all be done with numpy and opencv directly, no need for StringIO and PIL.

Here is how I create an opencv image decoded directly from a file object, or from a byte buffer read from a file object.

import cv2
import numpy as np

#read the data from the file
with open(somefile, 'rb') as infile:
     buf = infile.read()

#use numpy to construct an array from the bytes
x = np.fromstring(buf, dtype='uint8')

#decode the array into an image
img = cv2.imdecode(x, cv2.IMREAD_UNCHANGED)

#show it
cv2.imshow("some window", img)
cv2.waitKey(0)

Note that in opencv 3.0, the naming convention for the various constants/flags changed, so if using opencv 2.x, you will need to change the flag cv2.IMREAD_UNCHANGED. This code sample also assumes you are loading in a standard 8-bit image, but if not, you can play with the dtype='...' flag in np.fromstring.

like image 78
svohara Avatar answered Sep 20 '22 20:09

svohara


another way,

also in the case of a reading an actual file this will work for a unicode path (tested on windows)
with open(image_full_path, 'rb') as img_stream:
    file_bytes = numpy.asarray(bytearray(img_stream.read()), dtype=numpy.uint8)
    img_data_ndarray = cv2.imdecode(file_bytes, cv2.CV_LOAD_IMAGE_UNCHANGED)
    img_data_cvmat = cv.fromarray(img_data_ndarray) #  convert to old cvmat if needed
like image 32
Noam Geffen Avatar answered Sep 19 '22 20:09

Noam Geffen