views:

246

answers:

2

Hey all,

I am streaming some data down from a webcam. When I get all of the bytes for a full image (in a string called byteString) I want to display the image using OpenCV. Done fast enough, this will "stream" video from the webcam to an OpenCV window.

Here's what I've done to set up the window:

cvNamedWindow('name of window', CV_WINDOW_AUTOSIZE)

And here's what I do when the byte string is complete:

img = cvCreateImage(IMG_SIZE,PIXEL_DEPTH,CHANNELS)
buf = ctypes.create_string_buffer(byteString) img.imageData = ctypes.cast(buf, ctypes.POINTER(ctypes.c_byte)) cvShowImage('name of window', img) cvWaitKey(0)

For some reason this is producing an error:

File "C:\Python26\lib\site-packages\ctypes_opencv\highgui_win32.py", line 226, in execute return func(*args, **kwargs)

WindowsError: exception: access violation reading 0x015399E8

Does anybody know how to do what I'm trying to do / how to fix this crazy violation error?

A: 

Tyler:

I'm not sure what you are trying to do..i have a few guesses.

if you are trying to simply read an image from a webcam connected to your pc then this code should work:

import cv

cv.NamedWindow("camera", 1)

capture = cv.CaptureFromCAM(0)

while True:
    img = cv.QueryFrame(capture)
    cv.ShowImage("camera", img)
    if cv.WaitKey(10) == 27:
        break

are you trying to stream video from an internet cam? if so, you should check this other post: opencv-with-network-cameras

If for some reason you cannot do it in any of these ways then may be you can just somehow savethe image on the hard drive and then load it in your opencv program by doing a simple cvLoadImage ( of course this way is much slower).

another approach would be to set the new image pixels by hand by reading each of the values from the byteString, doing something like this:

for(int x=0;x<640;x++){
                for(int y=0;y<480;y++){
                        uchar * pixelxy=&((uchar*) (img->imageData+img->widthStep*y))[x];
                        *pixelxy=buf[y*img->widthStep + x]; 
                }
        }

this is also slower but faster than using the hard drive. Anyway, hope some of this helps, you should also specify which opencv version are you using.

dnul
A: 

I actually solved this problem and forgot to post the solution. Here's how I did it, though it may not be entirely robust:

I analyzed the headers coming from the MJPEG of the network camera I was doing this to, then I just read from the stream 1 byte at a time, and, when I detected that the header of the next image was also in the bytestring, I cut the last 42 bytes off (since that's the length of the header).

Then I had the bytes of the JPEG, so I simply created a new Cv Image by using the open(...) method and passing it the byte string wrapped in a StringIO class.

tyler