OpenCV creating an iplImage from memoryblock

I’m having some fun with OpenCV now that I have it working! :slight_smile:

I have a memoryblock that is an RGB Image, the pixels are in RGB order
I has a width and a height.

I want to convert the memory block into a picture using OpenCV.

It seems that OpenCV is based on top of Intel’s Image Processing Libraries.
They use a stucture of fixed size in front of the actual image data

memoryblock = [[IplImage-Structure][raw pixel data described in structure]]

    dim myImg as new MyImageClass(x)
    dim imgStruct as IplImage
    
    imgStruct.nChannels = 3
    imgStruct.alphaChannel = 0
    imgStruct.depth = 8
    imgStruct.colorModel = "RGB"
    imgStruct.channelSeq = "BGR"
    imgStruct.dataOrder = 0
    imgStruct.origin = 0
    imgStruct.align = 3
    imgStruct.width = myImg.mColumns
    imgStruct.widthStep = myImg.mColumns
    imgStruct.height = myImg.mRows
    imgStruct.roi = nil
    imgStruct.maskRoi = nil
    imgStruct.tileInfo = nil
    imgStruct.imageSize = myImg.getPixelMemoryBlock.Size
    imgStruct.imageDataOrigin = myImg.getPixelMemoryBlock
    imgStruct.imageData = myImg.getPixelMemoryBlock
    
    // I think this is where I need help....
    dim img as new MemoryBlock(imgStruct.size  + imgStruct.imageSize)

   // So this is where I am wondering how I copy the structure into the memory 
   // block and then copy the memoryblock from the other image class's memory block.
   // I think the rest is ok. 

    dim img4 as ptr
    dim size as CvSize
    dim sc as CvScalar
    dim wimg, himg, nchannels, simg, depth, sizeimg as integer
    
    wimg= imgStruct.width
    himg = imgStruct.height
    nchannels =imgStruct.nChannels
    simg = imgStruct.widthStep
    sizeimg = imgStruct.Size
    depth=imgStruct.depth
    
    // we need a 4 Channels image to be converted in Xojo BitMap Format
    size.Height=himg
    size.width=wimg
    img4=cvCreateImage(size,depth,4)
    
    if nChannels <=2 then
      dim img3 as ptr=cvCreateImage(size,depth,3)
      cvCvtColor(img,img3,CV_GRAY2BGR)
      cvCvtColor(img3,img4,CV_RGB2RGBA)
    else
      cvCvtColor(img,img4,CV_RGB2RGBA)
    end if
    
    // to reverse BGRA order for bitMap
    cvFlip(img4,img4, 0)
    // convert to Xojo
    // must be improved for 16 bits
    if depth>=16 then
      picture =convert2Picture(img)
    else
      picture=convert2BMP(img4)
    end if
  end if

/*
Struct IplImageHdr stIpl;
stIpl.Width = 512;
stIpl.Height = 512;

unsigned char img = malloc(5125123) // My RGB Image
unsigned char iplImg = malloc(sizeof(Struct IplImageHdr) + 512512
3);
memcpy(&stIpl, iplImg, sizeof(IplImageHdr));
memcpy(iplImg+sizeof(iplImageHdr), img, 5125123);

*/

How do you create a memoryblock given a structure and a memory block?

Function memblk(imgStruct as IplImage, raw as MemoryBlock) As MemoryBlock //concatenate imgStruct + raw and return a memory block End Function

Function memblk(imgStruct as IplImage, raw as MemoryBlock) As MemoryBlock
  dim mb as MemoryBlock
  
  mb = new MemoryBlock(imgStruct.size + raw.size)
  mb.StringValue(0, imgStruct.size) = imgStruct.StringValue(false)
  mb.StringValue(imgStruct.size, raw.size) = raw.StringValue(0, raw.size)
  
  return mb
  
End Function

Thanks Tim.

Getting a bit further but this is crashing in xTools.convert2BMP
bmp=bmp.FromData(RGBBitmap)

width is not necessarily even… could be odd…

    dim img4 as ptr
    dim size as CvSize
    dim depth as integer
    dim nchannels as integer
    dim matsize as integer

    dim hdrsize as integer
    dim img as MemoryBlock
    dim imgStruct as IplImage
    
    size.Height = dcmImg.mRows
    size.width = dcmImg.mColumns
    
    depth = dcmImg.mBitsStored
    nchannels = dcmImg.mSamplesPerPixel
    matsize = dcmImg.getPixelMemoryBlock.Size
    hdrsize = imgStruct.Size
    
    img = cvCreateImage(size,depth,nchannels)
    img.Ptr(108) = dcmImg.getPixelMemoryBlock
    img.ptr(68) = dcmImg.getPixelMemoryBlock
    
    // we need a 4 Channels image to be converted in Xojo BitMap Format
    img4=cvCreateImage(size,depth,4)
    
    if nChannels <=2 then
      dim img3 as ptr=cvCreateImage(size,depth,3)
      cvCvtColor(img,img3,CV_GRAY2BGR)
      cvCvtColor(img3,img4,CV_RGB2RGBA)
    else
      cvCvtColor(img,img4,CV_RGB2RGBA)
    end if
    
    // to reverse BGRA order for bitMap
    cvFlip(img4,img4, 0)
    // convert to Xojo
    // must be improved for 16 bits
    if depth>=16 then
      picture =convert2Picture(img)
    else
      picture=convert2BMP(img4)   // Dies here saying that the source image format is not correct.
    end if

Getting a bit further but this is crashing in xTools.convert2BMP

bmp=bmp.FromData(RGBBitmap)
This is crashing with an unsupported format exception.

    dim img4 as ptr
    dim size as CvSize
    dim depth as integer
    dim nchannels as integer

    dim img as MemoryBlock
    
    size.Height = dcmImg.mRows
    size.width = dcmImg.mColumns
    
    depth = dcmImg.mBitsStored   //8
    nchannels = dcmImg.mSamplesPerPixel  //3
    matsize = dcmImg.getPixelMemoryBlock.Size
    
    img = cvCreateImage(size,depth,nchannels)
    img.Ptr(108) = dcmImg.getPixelMemoryBlock
    img.ptr(68) = dcmImg.getPixelMemoryBlock
    
    // we need a 4 Channels image to be converted in Xojo BitMap Format
    img4=cvCreateImage(size,depth,4)
    
    if nChannels <=2 then
      dim img3 as ptr=cvCreateImage(size,depth,3)
      cvCvtColor(img,img3,CV_GRAY2BGR)
      cvCvtColor(img3,img4,CV_RGB2RGBA)
    else
      cvCvtColor(img,img4,CV_RGB2RGBA)
    end if
    
    // mirror about centre horizontal axis
    cvFlip(img4,img4, 0)
    // convert to Xojo
    // must be improved for 16 bits
    if depth>=16 then
      picture =convert2Picture(img)
    else
      picture=convert2BMP(img4)   // Dies here saying that the source image format is not correct.
    end if

Width is not necessarily even… could be odd…

You probably could use the TypeLib plugins RawBitmapConverter and RawBitmap to convert to MemoryBlock (TypeLib plugin is free for everyone).

From the RawBitmap class you can get the MemoryBlock as zero cost operation.

I’m still stuck here. Anyone?
I’ve used these MMX intel image processing libraries a long time ago in VB60…
Anyone know why my code is crashing?
Also… Anyone know how these binding were made?

[quote=378378:@Brian O’Brien]I’m still stuck here. Anyone?
I’ve used these MMX intel image processing libraries a long time ago in VB60…
Anyone know why my code is crashing?
Also… Anyone know how these binding were made?[/quote]
UnsupportedFormatException means that Picture.FromData can’t figure out what kind of picture data it is. Typically you’d pass in a Memoryblock that contains PNG or JPEG data.