[Image-SIG] Help with AVI files
Riccardo Trocca
rtrocca@libero.it
Fri, 22 Feb 2002 18:14:28 -0800
Hello,
I'll describe my problem just saying that I'm getting crazy! Some time ago
I wrote a Python extension that could read frames from an AVI file.
Everything worked well until my HD crashed and I lost every bit of my work.
Now I've got to do that again, therefore I'm writing a new extension. This
time I decided to go through SWIG in order to learn it and then build a
bigger package for Image Processing.
The problem that I've got now is that I can't see nothing else than noise
in every image I try to grab with python.
The C program I wrote is simple, and I've already used it in other
applications and it works:
struct _AVIFile {
PAVISTREAM ppavi;
PGETFRAME pgframe;
AVISTREAMINFO avis;
LPBITMAPINFOHEADER bi;
//IplImage* img;
int width;
int height;
int frames;
int bitcount;
int current;
};
typedef struct _AVIFile AVIFile;
LONG AFOpenVideoStream(AVIFile* af,const char* path,bool flip=false);
LPBITMAPINFOHEADER AFGetFrame(AVIFile* af, int index);
void AFCloseVideoStream(AVIFile* af);
LONG AFOpenVideoStream(AVIFile* af,const char* path, bool flip){
LONG hr;
int channels;
int origin;
hr=AVIStreamOpenFromFile(
&(af->ppavi),
path,
streamtypeVIDEO,
0,
OF_SHARE_DENY_WRITE,0L);
if (hr!=0)
return false;
AVIStreamInfo(af->ppavi, &(af->avis), sizeof(af->avis));
af->pgframe=AVIStreamGetFrameOpen(af->ppavi,0L);
if (!af->pgframe)
return false;
af->bi = (LPBITMAPINFOHEADER) AVIStreamGetFrame(af->pgframe,0);
af->frames=af->avis.dwLength;
af->width=af->bi->biWidth;
af->height=af->bi->biHeight;
af->bitcount=af->bi->biBitCount;
af->current=0;
return true;
}
LPBITMAPINFOHEADER AFGetFrame(AVIFile* af, int index){
static int temp;
temp=(index>af->frames-1?af->frames-1:(index<0?0:index));
if (af->current!=temp) {
af->current=temp;
af->bi=(LPBITMAPINFOHEADER) AVIStreamGetFrame(af->pgframe,af->current);
}
return af->bi;
}
Then I wrote a SWIG file like this:
%module _pyAVIFile
%{
#include <windows.h>
#include <vfw.h>
#include <Numeric/arrayobject.h>
#include "AVIFile.h"
#include <stdio.h>
%}
%include "typemaps.i"
typedef struct {
%readonly
int width;
int height;
int frames;
int bitcount;
int current;
} AVIFile;
%addmethods AVIFile{
AVIFile(char* path) {
AVIFile* af=(AVIFile*)malloc(sizeof(AVIFile));
if (!AFOpenVideoStream(af,path,false))
return NULL;
return af;
}
~AVIFile() {
AFCloseVideoStream(self);
free(self);
}
PyObject* getNumeric(int frame) {
int dims[3];
dims[0]=self->width;
dims[1]=self->height;
dims[2]=3;
AFGetFrame(self,frame);
return PyArray_FromDimsAndData(3,dims,PyArray_UBYTE,
(char*)self+(self->bi->biSize));
}
PyObject* getString(int frame) {
int dims[3];
dims[0]=self->width;
dims[1]=self->height;
dims[2]=3;
AFGetFrame(self,frame);
return
PyString_FromStringAndSize((char*)self+(self->bi->biSize),dims[0]*dims[1]*dims[2]);
}
}
void AVIFileInit();
void AVIFileExit();
%init %{
import_array();
%}
Of course all of this will work with just 24bit images, but by now it is
ok. Everything seems to work, and when I open the AVI file I can see the
exact width and size being read. Ok. The problem is with the Numeric and
string representation.
If I try to print the Numeric object, Python crashes. This just printing!
if I use NumTut.view it will not crash, but it will show just noise!
The same result with:
im=Image.new('RGB',(352,288))
im.fromstring(af2.getString(100))
im.show()
the same "noise"
I remember problems with channels ordering, but in that case I should be
able to see a false color image. Well, now I'm really lost. Can somebody
give some help?
Riccardo