Converting a Memory Address to a MemoryBlock

Thanks Will
I’ll test with BMP format. I also use a RGBSurface.pixel technique which works fine but is rather slow when processing large images. I was just wondering for a quicker rendering such as the way I used with other language like Rebol

cvtoRebolByPtr: func [img dest /local src] [
"Transforms OpenCV image to REBOL image"
    src: getIPLImage img 							; get values of IplImage
	data: src/imageData								; address of image data
	rgb: reverse get-memory data src/imageSize		;get the data in rgb order
	; now makes a REBOL image
    dest/image: make image! reduce [as-pair (src/width) (src/height) rgb]
	show dest
] 

What are you doing with the Xojo Pictures? I mean, is this just a video stream you’re drawing to screen? Then I think you’ll get better performance using OpenGL. Or possibly declares to your OSes native picture and drawing routines. What OS are you targeting?

But for making Xojo Pictures there might be MBS or other plugins too.

Thanks Will,
It’s really easy to make the header for a bmp format :), but you’re right, the pixel format is not appropriate (BGR and not BGRA). I’ll test with OpenGL ASAP.
To answer to tour question about Xojo pictures: in fact, I’m preparing a teaching about OpenCV image processing for non computer scientist students and I’ve decided to use Xojo for an introduction to development of nice applications for this public. This is why I want to convert the result of OpenCV image processing onto a Xojo Picture. Work on progress and once again, thanks for your help. Best regards

Done!
you can find an image here https://drive.google.com/file/d/0BzN_niDInGT4UEhPeW1TR3NUTGs/view?usp=sharing
OpenCV is able to convert A RBG image to a RGBA image : cvCvtColor(img,img4,CV_RGB2RGBA). Very easy after that.

Find enclosed the fonction convertToBMP(imgOCV as Ptr) which returns a Xojo Picture

  Dim imgSize as integer=imgOCV.Int32(64)
  Dim w as integer = imgOCV.int32(40)
  Dim h as integer = imgOCV.int32(44)
  Dim nChannels as integer= imgOCV.Int32(8)
  Dim depth as integer=imgOCV.int32(16)
  Dim imageData As MemoryBlock
  // create a MemoryBlock for the header and image values
  Dim RGBBitmap as MemoryBlock =  new MemoryBlock(h * w * 4 +54)        
  //  the 54 bytes header with required information
  RGBBitmap.UShort(0)=&h4D42
  RGBBitmap.UInt32Value(2)=imgSize
  RGBBitmap.UInt16Value(6)=0
  RGBBitmap.UInt16Value(8)=0
  RGBBitmap.UInt32Value(10)=54
  RGBBitmap.UInt32Value(14)=40
  RGBBitmap.UInt32Value(18)=w
  RGBBitmap.UInt32Value(22)=h
  RGBBitmap.UInt16Value(26)=1
  RGBBitmap.UInt16Value(28)=32
  RGBBitmap.UInt32Value(30)=0
  RGBBitmap.UInt32Value(34)=imgSize
  RGBBitmap.UInt32Value(38)=72
  RGBBitmap.UInt32Value(42)=72
  RGBBitmap.UInt32Value(46)=0
  RGBBitmap.UInt32Value(50)=0
  // update bitmap image values from opencv data address
  imageData= imgOCV.ptr(68)                                      
  RGBBitmap.StringValue(54,imgSize)= imageData.StringValue(0,imgSize)
  //make a Picture from Data
  Dim bmp as picture=new picture (w,h,32)
  bmp=bmp.FromData(RGBBitmap)
  return bmp

Very quick in comparison to the RGBSurface.pixel technique.
Thanks for helping

Oups
seems better

I’d got curious and did a test to see how RGBSurface compares to OpenGL. Results from a compiled app on an old mac…

process 30 MemoryBlocks containing 720x404 RGB data
                              seconds
scan RGB to pic time:            0.733314   41 per sec
move RGB to OpenGL time:         0.011278   2600 per sec **

scan RGB to pic time (+draw):    1.487114   20 fps
move RGB to OpenGL time (+draw): 0.483332   60 fps

‘Scan RGB’ is the RGBSurface.Pixel technique (all pragmas on) and ‘Move RGB’ is a single OpenGL call. The first two are just times to process, no drawing. The last two measure actual drawing rate. **2600 is too high, I’m guessing the data isn’t processed until drawn.

Letting the memoryblocks loop for awhile Activity Monitor plateaus around…

scan to pic and draw: 75% cpu
load OpenGL and draw: 9% cpu
Playing the source movie in quicktime player is 6% cpu

To test bmp I prebuilt the 30 Memoryblocks with a header and BGRA data, ie a bmp file :slight_smile: so it’s basically timing Picture.FromData and Graphics.DrawPicture.

bmp fromData time:         0.420370    71 per sec
bmp fromData time (+draw): 1.001263    30 fps

bmp fromData and draw: 75% cpu

Here’s the testing app if you want to compare on your system. Very very messy. Only the enabled buttons on MainWindow are expected to work.

https://drive.google.com/file/d/0B97iUmOCTUYdQnk3WjF0LVNoT1k/view?usp=sharing 40.6Mb

First put the folders ‘memfiles’ and ‘bmpfiles’ on your desktop. Run and click ‘load all mems’ and ‘load bmp mem’ which load the files to a Memoryblock array. Also click ‘test texture’ which initializes the OpenGL texture for receiving data.

Now it’s primed to run timing tests by clicking on ‘pic play’ for RGBSurface, ‘bmp play’ for FromData and ‘tex play’ for OpenGL. There’s a Checkbox slapped on there labeled ‘+draw’. Toggle that to include drawing in the test or not.

To do a cpu % test requires going through the testing buttons (pic play, bmp play, tex play) and uncommenting the “for pass = 1 to 20” loops. Then it’ll run long enough to level out a cpu load.

So that’s just messy tests, what you might be more interested in is an OpenGLSurface subclass for displaying RGB memoryblocks. RawRGBView wraps up the little bit of the ezgl framework used in testing into a single stand alone control. Simply drop a RawRGBView on your window and initialize the image size

RawRGBView1.texSetSize(720, 404)

as memoryblocks come in pass them to the view

RawRGBView1.texLoadData(rgbDataMemoryBlock)

It’s at proof-of-concept right now, some little things still need tweaking. To run the demo the ‘memfiles’ folder needs to be on the desktop.

https://drive.google.com/file/d/0B97iUmOCTUYdTXN1a1V5QmhUQnM/view?usp=sharing 8k

Hopefully I’ll get to compiling OpenCV in a few days. I played with it once in processing/openFrameworks and had a bewildering time.

Hi Will
Really interesting app :slight_smile:

Hi everybody,
Some tests for loading and displaying a 8-bit RVB image (740X1000)
classical RGBSurface (pixel by pixel): 0.292 sec
convert2BMP function: 0.054 sec

for a 512x512 image
classical RGBSurface: 0.12 vs 0.02
convert2BMP function: 0.025 sec
Regards