Group Abstract Group Abstract

Message Boards Message Boards

0
|
12.6K Views
|
6 Replies
|
3 Total Likes
View groups...
Share
Share this post:

[?] Access an image in a System.Windows.Media.Imaging.CachedBitmap ?

Posted 8 years ago

I am trying to use a camera with a .NET interface. The code below seems like it may be capturing an image into a System.Windows.Media.Imaging.CachedBitmap object.

Any ideas how to access this from within Mathematica? Eventually, I will need a solution that runs quickly. Saving to disk using .NET and then reading the file into Mathematica would functionally give me what I need, but will be too slow.

Needs["NETLink`"];
InstallNET[];
LoadNETAssembly["C:\\XIMEA\\API\\x64"];
LoadNETType["xiApi.NET.xiCam"];
myCam = NETNew["xiApi.NET.xiCam"];
myCam@OpenDevice[0];

(*Start acquisition *)
myCam@StartAcquisition[];

timeouts = 1000;
myCam@GetImage[myImage, timeouts]

myCam@StopAcquisition[];

myImage

Output of last statement is: « NETObject[System.Windows.Media.Imaging.CachedBitmap]»

POSTED BY: Jeff Burns
6 Replies
Posted 8 years ago
POSTED BY: Jeff Burns
Posted 8 years ago
NETObjectToExpression[myImage] 

returns « NETObject[System.Windows.Media.Imaging.CachedBitmap]»

Clearly I have to do something to convert the CachedBitmap.

MATLAB automatically converts arrays to .NET types as described hear. Does Mathematica do something similar?

This is some code that does not work but outlines what I think is needed.

In[]=  bytesPerPixel = myImage@Format@BitsPerPixel/8
Out[] =  4

In[] = netArray = NET@CreatArray["system.byte", myImage@Height myImage@Width  bytesPerPixel]
Out[] = NET[CreatArray["system.byte", 1.27473*10^7]]

In[] = myImage@CopyPixels[netArray, bytesPerPixel myImage@Width, 0]
NET: Improper arguments supplied for method named CopyPixels. 
Out[] = $Failed

Seems the key is setting up an array to accept the image.

POSTED BY: Jeff Burns
Posted 8 years ago

Thanks for the input. I think .NET calls can be made in Mathematica to copy the array. How is a .NET array accessed in Mathematica?

POSTED BY: Jeff Burns

If the array has a meaningful value, you might try NETObjectToExpression[obj] to convert the NETObject (array) into nested lists of real numbers in Mathematica.

POSTED BY: Kevin Daily

I'm not sure at which point you are stuck.

Are you not able to get the image data to Mathematica? It seems the manufacturer has a method to return an image (GetImage function). I suggest writing a simple C# class that would load the manufacturer's class. When you initialize that class, connect to your camera. Have a public function that does the GetImage call, which should return a CachedBitmap. It seems you could use the C# Bitmap method 'CopyPixels' to put the image data inside a .NET array. Have the function return this array. Back in Mathematica, load your new C# class. Then, run your function that gets the [next] image from the camera and return its pixel values as an array.

Once the pixel data is available in Mathematica, you just need to reshape it as is done in the Matlab code (there should be 3 channels, and you already know the image width and height). To create the Image in Mathematica, wrap Image around the data, specifying the ImageType as "Byte",

Image[reshape[-netArrayData-], "Byte"]
POSTED BY: Chad Knutson
Posted 8 years ago

The camera manufacturer supplied this MATLAB code that does what I need to do in Mathematica.

disp('Color image format')
        myCam.SetParam(xiApi.NET.PRM.BUFFER_POLICY , xiApi.NET.BUFF_POLICY.UNSAFE);
        bmap=GetImage(myCam,1000);
        BytesPerPixel=bmap.Format.BitsPerPixel/8;
        NetArray=NET.createArray('System.Byte',W*H*BytesPerPixel);
        img_data=zeros(H,W,3,'uint8');
        for id=1:numOfFrames
                bmap=GetImage(myCam,1000);    
                bmap.CopyPixels(NetArray,BytesPerPixel*W,0);  
                img=uint8(NetArray);
                img_data(:,:,1)=transpose(reshape(img(3:BytesPerPixel:end),W,H));
                img_data(:,:,2)=transpose(reshape(img(2:BytesPerPixel:end),W,H));
                img_data(:,:,3)=transpose(reshape(img(1:BytesPerPixel:end),W,H));
                imshow(img_data);
                drawnow;
        end

I can get the image height, width, and bytes per pixel with the code below.

bytesPerPixel = myImage@Format@BitsPerPixel/8;
myCam@GetParam["height", imageHeight];
myCam@GetParam["width", imageWidth];

Still looking for how to read the image from memory.

POSTED BY: Jeff Burns
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard