I'm working with OpenCV in Python. I want to get input from Asus Xtion .
I'm able to successfully run samples from PyOpenNI .
I want to use the image obtained (str format) by igen.get_synced_image_map_bgr() in opencv.
igen-ImageGenerator
I want to convert it to IplImage.
How can I do it,or How can I otherwise use the input from the depth sensor in Opencv python code.
I recently used the string format depth data from Kinect in PyOpenNI with OpenCV. Use numpy arrays which can be created from strings and which are the default data type in cv2 (OpenCV) for Python.
Code example here: http://euanfreeman.co.uk/pyopenni-and-opencv/
Not sure how Kinect differs from your depth sensor but that may be a useful starting point. Good luck!
Edit: added code
from openni import *
import numpy as np
import cv2
# Initialise OpenNI
context = Context()
context.init()
# Create a depth generator to access the depth stream
depth = DepthGenerator()
depth.create(context)
depth.set_resolution_preset(RES_VGA)
depth.fps = 30
# Start Kinect
context.start_generating_all()
context.wait_any_update_all()
# Create array from the raw depth map string
frame = np.fromstring(depth.get_raw_depth_map_8(), "uint8").reshape(480, 640)
# Render in OpenCV
cv2.imshow("image", frame)
Related
I've got a problem. I'm trying create image from binary data which I got from hyperspectral camera. The file which I have is in BSQ uint16 format. From the documentation I found out that images contained in the file (.dat) have a resolution of 1024x1024 and there are 24 images in total. The whole thing is to form a kind of "cube" which I want use in the future to creat multi-layered orthomosaic.
I would also like to add that I am completely new in python but I try to be up to date with everything I need. I hope that everything what I have written is clear and uderstandable.
At first I tried to use Numpy liblary to creating 3D array but ended up with an arrangement of random pixels.
from PIL import Image
import numpy as np
file=open('Sequence 1_000021.dat','rb')
myarray=np.fromfile(file,dtype=np.uint16)
print('Size of new array',":", len(myarray))
con_array=np.reshape(myarray,(24,1024,1024),'C')
naPIL=Image.fromarray(con_array[1,:,:])
naPIL.save('naPIL.tiff')
The result: enter image description here
Example of image which I want to achieve (thumbnail): enter image description here
As suspected it's just byte order, I get a sensible looking image when running the following code in a Jupyter notebook:
import numpy as np
from PIL import Image
# open as big-endian, convert to native order, then reshape as appropriate
raw = np.fromfile(
'./Sequence 1_000021.dat', dtype='>u2'
).astype('uint16').reshape((24, 1024, 1024))
# display inline
Image.fromarray(raw[1,:,:])
I want to compress a GIF image by extracting 15 frames from the GIF that preferably should be distinct.
I'm using Python and Pillow library and I didn't find any way to get the number of frames a GIF has in the Pillow docs. Neither did I find how to extract a specific frame from a GIF, because Pillow restricts that.
Is there any way to extract frames without iterating through each frame consequently?
Is there a more advanced Python library for GIF processing?
Here is an extension of #radarhere's answer that divides the .gif into num_key_frames different parts and saves each part to a new image.
from PIL import Image
num_key_frames = 8
with Image.open('somegif.gif') as im:
for i in range(num_key_frames):
im.seek(im.n_frames // num_key_frames * i)
im.save('{}.png'.format(i))
The result is somegif.gif broken into 8 pieces saved as 0..7.png.
For the number of frames, you are looking for n_frames. Take a look at here.
from PIL import Image
im = Image.open('test.gif')
print("Number of frames: "+str(im.n_frames))
For extracting a single frame -
im.seek(20)
im.save('frame20.jpg')
The real working solution to extract proper frames of any GIF file:
BigglesZX/gifextract.py
If you have tf imported you can:
def load_gif(file_path):
with tf.io.gfile.GFile(file_path, 'rb') as f:
video = tf.io.decode_gif(f.read())
return np.array(video)
I'm using OpenCV 2.4.0 python bindings and I found that when calculating a laplacian of an image I get different results with the cv2 API from the cv2.cv API.
if I use cv2 API:
im_laplacian = cv2.Laplacian(im_gray, cv2.IPL_DEPTH_32F, ksize = 3)
im_laplacian is always uint8 (missing sign), and ddepth has to be IPL_DEPTH_32F or IPL_DEPTH_64F, if I try IPL_DEPTH_16S or IPL_DEPTH_32S I get an error:
"OverflowError: Python int too large to convert to C long"
if I use cv2.cv API:
cvgray = cv.fromarray(im_gray)
im_laplacian2 = cv.CreateImage(cv.GetSize(cvgray), cv.IPL_DEPTH_16S, 1)
cv.Laplace(cvgray, im_laplacian2, 3)
as expected I get a signed laplacian, this is the same result as in the C++ API.
If I do:
im_laplacian2_scaled = cv.CreateImage(cv.GetSize(cvgray), 8, 1)
cv.ConvertScaleAbs(dst, im_laplacian2_scaled, 1, 0)
im_laplacian2_scaled is still different from im_laplacian calculated with cv2 API
In my particular case I think I can get away with the cv2 output,
but I'm puzzeled, shouldn't all APIs produce the same output?
do they use different algorithms?
or maybe the cv2 python bindings don't correspond to individual C++ functions but some combination of them?
New cv2 API uses different depth constants:
cv2.CV_64F instead of cv2.IPL_DEPTH_64F
cv2.CV_32F instead of cv2.IPL_DEPTH_32F
cv2.CV_32S instead of cv2.IPL_DEPTH_32S
cv2.CV_16S instead of cv2.IPL_DEPTH_16S
cv2.CV_16U instead of cv2.IPL_DEPTH_16U
cv2.CV_8S instead of cv2.IPL_DEPTH_8S
cv2.CV_8U instead of cv2.IPL_DEPTH_8U
Is it possible to reduce the depth of an image using PIL? Say like going to 4bpp from a regular 8bpp.
You can easily convert image modes (just call im.convert(newmode) on an image object im, it will give you a new image of the new required mode), but there's no mode for "4bpp"; the modes supported are listed here in the The Python Imaging Library Handbook.
This can be done using the changeColorDepth function in ufp.image module.
this function only can reduce color depth(bpp)
import ufp.image
import PIL
im = PIL.Image.open('test.png')
ufp.image.changeColorDepth(im, 16) # change to 4bpp(this function change original PIL.Image object)
im.save('changed.png')
Here is my current code (language is Python):
newFrameImage = cv.QueryFrame(webcam)
newFrameImageFile = cv.SaveImage("temp.jpg",newFrameImage)
wxImage = wx.Image("temp.jpg", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
wx.StaticBitmap(self, -1, wxImage, (0,0), (wxImage.GetWidth(), wxImage.GetHeight()))
I'm trying to display an iplimage captured from my webcam in a wxPython window. The problem is I don't want to store the image on hard disk first. Is there any way to convert an iplimage into another image format in memory? Any other solution?
I found a few "solutions" to this problem in other languages, but I'm still having trouble with this issue.
Thanks.
What you have to do is:
frame = cv.QueryFrame(self.cam) # Get the frame from the camera
cv.CvtColor(frame, frame, cv.CV_BGR2RGB) # Color correction
# if you don't do this your image will be greenish
wxImage = wx.EmptyImage(frame.width, frame.height) # If your camera doesn't give
# you the stream size, you might have to use (640, 480)
wxImage.SetData(frame.tostring()) # convert from cv.iplimage to wxImage
wx.StaticBitmap(self, -1, wxImage, (0,0),
(wxImage.GetWidth(), wxImage.GetHeight()))
I figured oyt out how to do this by looking at the Python OpenCV cookbook and at the wxPython wiki.
Yes, this question is old but I came here like everybody else searching for the answer. Several versions of wx, numpy, and opencv after the above solutions I figured I'd share a fast solution using cv2 and numpy images.
This is how to convert a NumPy array style image as used in OpenCV2 into a bitmap you can then set to a display element in wxPython (as of today):
import wx, cv2
import numpy as np
# Start with a numpy array style image I'll call "source"
# convert the colorspace to RGB from cv2 standard BGR, ensure input is uint8
img = cv2.cvtColor(np.uint8(source), cv2.cv.CV_BGR2RGB)
# get the height and width of the source image for buffer construction
h, w = img.shape[:2]
# make a wx style bitmap using the buffer converter
wxbmp = wx.BitmapFromBuffer(w, h, img)
# Example of how to use this to set a static bitmap element called "bitmap_1"
self.bitmap_1.SetBitmap(wxbmp)
Tested 10 minutes ago :)
This uses the built in wx function BitmapFromBuffer and takes advantage of the NumPy buffer interface so that all we have to do is swap the colors to get those in the expected order.
You could do with StringIO
stream = cStringIO.StringIO(data)
wxImage = wx.ImageFromStream(stream)
you can check more detail in \wx\lib\embeddedimage.py
just my 2 cents.