1. WebCam with wxEuphoria

I've just started on a project to do image acquisition with OpenCV, EU4, and wxEuphoria. OpenCV allows me to grab images from my webcam, and it returns a pointer to the memory location of the RGB values for each pixel. I would like to be able to display these images with wxEuphoria using something like wxImage or wxBitmap, but I'm not sure how to organize the pixel data. Do I need to make a 2D sequence where each entry is a sequence of 3 characters representing the RGB values? Something like this:

image = {{{R,G,B},{R,G,B},{R,G,B},{R,G,B}}, 
         {{R,G,B},{R,G,B},{R,G,B},{R,G,B}}, 
         {{R,G,B},{R,G,B},{R,G,B},{R,G,B}}} 

If so, then what is the appropriate function to pass this info to display these images?

Thanks in advance,
Ira

new topic     » topic index » view message » categorize

2. Re: WebCam with wxEuphoria

Jerome said...

I've just started on a project to do image acquisition with OpenCV, EU4, and wxEuphoria. OpenCV allows me to grab images from my webcam, and it returns a pointer to the memory location of the RGB values for each pixel. I would like to be able to display these images with wxEuphoria using something like wxImage or wxBitmap, but I'm not sure how to organize the pixel data. Do I need to make a 2D sequence where each entry is a sequence of 3 characters representing the RGB values? Something like this:

image = {{{R,G,B},{R,G,B},{R,G,B},{R,G,B}}, 
         {{R,G,B},{R,G,B},{R,G,B},{R,G,B}}, 
         {{R,G,B},{R,G,B},{R,G,B},{R,G,B}}} 

If so, then what is the appropriate function to pass this info to display these images?

I suppose there are a few ways to go here. It's hard to say which will be best, since I'm not sure what all you need to do.

  1. Looking at the OpenCV docs, you could use cvSaveImage(), and then load it from your code. This is probably the easiest, but also likely the slowest.
  2. You could encode it on the fly as an XPM, and pass that to the constructor.
  3. You could create a bitmap in memory, use a wxMemoryDC, and use draw_point.

I suspect that #2 may be the fastest, but it's hard to say.

Matt

new topic     » goto parent     » topic index » view message » categorize

3. Re: WebCam with wxEuphoria

Matt,

Thanks for the options! I agree that number 1 is probably the easiest and slowest. I'll try using wxMemoryDC and draw_point first since I have a decent idea of how that should work. I'm not familiar with XPM, but I noticed some examples in the wxEuphoria demos that I can play with.

Thanks,
Ira

new topic     » goto parent     » topic index » view message » categorize

4. Re: WebCam with wxEuphoria

I have been able to successfully map from an SDL image buffer
to a wxWidgets buffer and display images.

See below for code snippets.

wxWidgets requires images to be in BGR format, where
the list of bytes is a single sequence buffer.

so, an image buffer of

image = {{{R,G,B},{R,G,B},{R,G,B},{R,G,B}},  
         {{R,G,B},{R,G,B},{R,G,B},{R,G,B}},  
         {{R,G,B},{R,G,B},{R,G,B},{R,G,B}}} 

would need to be 'flattened'. I think eu4 standard library
has a flatten() function

if your opencv image is RGB it will
need to be converted.

 
--// Convert SDL surface from RGB to BGR 
public enum 
		ofsRED   = 1, 
		ofsGREEN, 
		ofsBLUE, 
		ofsALPHA 
 
public function RGBtoBGR(sequence rgbbuf, integer bytesPerPixel=3) 
	--// swap B with R 
	sequence bgrbuf = {} 
	sequence rgb    = {} 
	integer  l = length(rgbbuf) 
	for i = 1 to l by bytesPerPixel do 
		rgb = rgbbuf[i..(i + (bytesPerPixel - 1))] 
		bgrbuf &= { rgb[ofsBLUE], rgb[ofsGREEN], rgb[ofsRED] } 
	end for 
	--// return buffer 
	atom bgr = allocate(length( rgbbuf )) 
	poke(bgr, bgrbuf) 
	return bgr 
end function 
 


something similar to the following will display
a BGR buffer to a wxWidgets DC.

--// convert sdl surface into wx compatible buffer 
-- atom bgr = RGBtoBGR(sdlcanvas, 3) 
 
/* 

    you would probably need to flatten your image  
    here and create your bgr surface 
*/ 
 
atom bgr = RGBtoBGR( flatten(openCVImage), 3)     
 
--// create image from converted bgr surface 
atom img = wx:create(wxImage, { openCVImageWidth, openCVImageHeight, bgr }) 
--// free converted bgr surface 
free(bgr) 
 
--// create bitmap from image 
atom bmp = wx:create(wxBitmap,{ BM_FROM_IMAGE, img, -1 }) 
 
--// update client DC 
atom clientDC = wx:create(wxClientDC, this) 
wx:begin_drawing(clientDC) 
wx:draw_bitmap(clientDC, bmp, 0, 0, true) 
wx:end_drawing(clientDC) 
 
--// clean up 
wx:delete_instance(clientDC) 
wx:delete_instance(bmp) 
wx:delete_instance(img) 
 

HTH

new topic     » goto parent     » topic index » view message » categorize

5. Re: WebCam with wxEuphoria

Thanks for the help so far! I've tried the following:

1) Saving the image to disk from OpenCV and opening the image in my EU code to display on screen
2) Drawing the individual pixel values of the image using draw_point
3) The method suggested by raseunew that creates wxImage from the pixels in memory

Method 1 is the slowest with lots of jitter in the picture. Method 2 works better but also has a noticeable lag from drawing the individual pixels. I like what raseunew suggested but I'm getting strange results. I'm working with 320 by 240 images from my webcam and using the code below, the picture shrinks and is tiled when displayed in my EU program. I thought there might be a problem with how I'm interfacing with my C++ code, but Method 2 would not work if there was a problem there. I can make things slightly better by playing with set_user_scale but this does not seem like the appropriate solution. Any help is appreciated!

- Ira

raseunew said...
--// create image from converted bgr surface 
atom img = wx:create(wxImage, { openCVImageWidth, openCVImageHeight, bgr }) 
--// free converted bgr surface 
free(bgr) 
 
--// create bitmap from image 
atom bmp = wx:create(wxBitmap,{ BM_FROM_IMAGE, img, -1 }) 
 
--// update client DC 
atom clientDC = wx:create(wxClientDC, this) 
wx:begin_drawing(clientDC) 
wx:draw_bitmap(clientDC, bmp, 0, 0, true) 
wx:end_drawing(clientDC) 
 
--// clean up 
wx:delete_instance(clientDC) 
wx:delete_instance(bmp) 
wx:delete_instance(img) 
 
new topic     » goto parent     » topic index » view message » categorize

6. Re: WebCam with wxEuphoria

Jerome said...

Thanks for the help so far! I've tried the following:

1) Saving the image to disk from OpenCV and opening the image in my EU code to display on screen
2) Drawing the individual pixel values of the image using draw_point
3) The method suggested by raseunew that creates wxImage from the pixels in memory

Method 2 works better but also has a noticeable lag from drawing the individual pixels.

There might be some ways to speed it up. For instance, since you're capturing video, many of the pixels may not be changing in each frame. You could possibly skip updating those. You might also detect if you have the same color pixel multiple times, and use draw_line() to reduce the number of calls. There might also be some micro optimizations possible in your euphoria code. Finally, you might compare the difference interpreted vs translated.

Jerome said...

I like what raseunew suggested but I'm getting strange results. I'm working with 320 by 240 images from my webcam and using the code below, the picture shrinks and is tiled when displayed in my EU program. I thought there might be a problem with how I'm interfacing with my C++ code, but Method 2 would not work if there was a problem there. I can make things slightly better by playing with set_user_scale but this does not seem like the appropriate solution. Any help is appreciated!

- Ira

raseunew said...
--// create image from converted bgr surface 
atom img = wx:create(wxImage, { openCVImageWidth, openCVImageHeight, bgr }) 
--// free converted bgr surface 
free(bgr) 
 
--// create bitmap from image 
atom bmp = wx:create(wxBitmap,{ BM_FROM_IMAGE, img, -1 }) 

I'm really surprised that works at all. The "data" parameter is supposed to be XPM data. If you're not familiar with XPM, there are several used in the demos. When they're created, the wxEuphoria library converts the euphoria sequences into "raw" xpm char data. It's basically an array of pointers to C strings.

You can pass the euphoria sequence versions to the wxBitmap constructor, and the library converts it, or you can convert it yourself and pass it to the wxImage constructor.

Matt

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu