Ask Your Question
0

Open 16 bit video file (proprietary format) with OpenCV

asked 2016-02-15 11:53:48 -0600

androgenus gravatar image

updated 2016-12-15 12:31:03 -0600

I would very much like to import in OpenCV a video file which is in a proprietary format - from a Xenics-Gobi infrared camera - file extension *.xvi.

The file is a 16 bit video format and with the image processing program that came with the camera i can export frames as 16 bit png frames that contain thermal information.

Would it be possible somehow to open the video files in OpenCV and process the frames?

Thank you for your time.

I've just found out how the .xvi file is structured:

The first 1024 bytes of an .XVI file is reserved for header information. After this block of 1kb you have raw frame data in the following format: Pixel(x,y) = block[ x+(y*width) ] Where each pixel is represented by an integer scaled up to the nearest CPU representation. For example, if the bit size is 12, you will get a 16bit integer. For bit sizes larger than 16 you will get a 32 bit integer, followed by a 64 bit representation (and so on ...) Note: All integers used are in Intel byte order.

Maybe with the above information someone could help me import the file in openCV (python code).

Thank you again

edit retag flag offensive close merge delete

Comments

is there any chance, you can access the video from your proprietary api ? once you have a pixel buffer, and image dimensions, it's a breeze to make a cv::Mat from that.

berak gravatar imageberak ( 2016-02-15 12:04:42 -0600 )edit

Hi and thank you for the answer. The SDK/API costs a lot like 1000 eur and have not bought it with the camera (stupid mistake). So looking now for some shortcut maybe someone here has used a xenics infrared camera with opencv?

androgenus gravatar imageandrogenus ( 2016-02-16 06:03:58 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
1

answered 2016-12-15 21:19:25 -0600

Tetragramm gravatar image

That's pretty easy. Read in the header and keep or discard as you like. Then create a buffer and read the data in from the file.

ushort* ptr = new ushort[width*height];
file.read((uchar*)ptr, width*height*sizeof(ushort));

Then use the Mat constructor

Mat(height, width, CV_16U, ptr);

Remember to delete the buffer when you're done with it. The Mat won't automatically take care of it.

edit flag offensive delete link more

Comments

Thank you for your answer. Thats great! Now have to figure out how to do it in Python.

androgenus gravatar imageandrogenus ( 2016-12-17 08:51:24 -0600 )edit

I think you just use numpy.fromfile to read the data, then the numpy array is transparent with OpenCV. I don't use python for very much so I'm not sure about that.

Tetragramm gravatar imageTetragramm ( 2016-12-17 11:47:32 -0600 )edit
0

answered 2017-01-05 12:56:49 -0600

androgenus gravatar image

I've managed to write a code in Python that can extract the frames from the .xvi file (as Tetragramm suggested in C#). It's strange that the first frame seems to be discarded or there's something else in the first 640x480x2 bytes after the videofile header (which is 1024 bytes). It also seems that each frame has a 32 byte header.

import cv2
import numpy as np
import matplotlib.pyplot as plt

#read the data from the file
with open('filename.xvi', 'rb') as infile:
    #choose the frame number to extract
    n=51
    infile.seek(1024+(32+640*480*2)*n)
    #read frame bytes into buffer
    buf = infile.read(640*480*2)

#use numpy to construct an array from the bytes
x = np.frombuffer(buf, dtype='uint16').reshape(480, 640)
#visualize extracted frame
plt.figimage(x, cmap='gray_r', vmin=np.min(x), vmax=np.max(x))
plt.show()

As you can see from the code I've visualized the frame (16bit depth array) with matplotlib. I cannot understand why when trying to visualize with opencv like in the code below it gives me an error (img_data = None). Maybe someone could help? Does opencv have a problem opening 16 bit greyscale images? If someone could help, here is a link to a small .xvi file with 81 frames (32 Mb) https://drive.google.com/file/d/0BzQd...

x = np.frombuffer(buf, dtype='uint16').reshape(480, 640)
img_data = cv2.imdecode(x,2)

Thank you for your help.

edit flag offensive delete link more

Comments

Hello, I am also working with an IR Xenics camera, did you manage to open the video? I am interested in. Kind regards

Corona gravatar imageCorona ( 2017-05-30 06:54:55 -0600 )edit

Hello, I see that this was written some time ago but were you able to successfully extract frames from the xvi? I am trying something similar and tried the code here but am not able to successfully extract the right data

nmthomas28 gravatar imagenmthomas28 ( 2020-04-07 09:46:23 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-02-15 11:53:48 -0600

Seen: 3,289 times

Last updated: Jan 05 '17