如何从MATLAB中用ActiveX控件控制的设备存储的内存中检索数据

时间:2012-08-15 14:11:04

标签: matlab camera activex

我有一个USB摄像头(DCC1645),我试图通过MATLAB与之交互。我已通过ActiveX成功将其连接到它:

cam = actxcontrol('uc480.uc480Ctrl.1');

我可以在上面运行各种功能等等。我现在想知道如何检索图像数据;相关函数返回指向内存中图像的指针:

GetImageMem() returns the pointer to the internal image memory where the image is stored.

所以如果我跑

loc = cam.GetImageMem();

然后loc是一个代表内存位置的大数字。获取内存量的函数如下:

InquireImageMem(LONG* nWidth, LONG* nHeight, LONG*nBits, LONG* nPitch) 
reads the properties of the allocated image memory. The function returns 
the properties of the actual image buffer, as returned by GetImageMem

nWidth     Receives the width of the allocated image memory.
nHeight    Receives the height of the allocated image memory.
nBits      Receives the bits per pixel of the allocated image memory.
nPitch     Receives the pitch of the allocated image memory. The pitch 
           is the number of bytes from the start of a line to the start 
           of the next line.

所以我的问题有两个:

  1. 如何获得指向内存和大小的指针的实际数据?
  2. 如何传递对函数的引用(例如LONG * nwidth)?有没有像我应该使用的libpointer?
  3. 谢谢!

3 个答案:

答案 0 :(得分:2)

根据IDS,不再支持COM框架,因此您应该考虑切换到.NET框架。我认为lunarquaker的帖子是指旧版本。这是一个代码片段,如果复制并粘贴到Matlab中,则无需修改相机型号#UI-1220SE-M-GL(它适用于我)。您可以更改彩色摄像机的像素格式。

在Matlab 8.3.0.532(R2014a)中测试,uEyeDotNet版本= 1.5.3.0和IDS / uEye v4.40.0.0

注意 - 在尝试再次初始化相同的相机之前,您必须“退出”,否则您会发现自己陷入了困境。

%   Add NET assembly if it does not exist
%   May need to change specific location of library
asm = System.AppDomain.CurrentDomain.GetAssemblies;
if ~any(arrayfun(@(n) strncmpi(char(asm.Get(n-1).FullName), ...
        'uEyeDotNet', length('uEyeDotNet')), 1:asm.Length))
    NET.addAssembly(...
        'C:\Program Files\IDS\uEye\Develop\DotNet\signed\uEyeDotNet.dll');
end

%   Create camera object handle
cam = uEye.Camera;

%   Open 1st available camera
%   Returns if unsuccessful
if ~strcmp(char(cam.Init), 'SUCCESS')
    error('Could not initialize camera');
end

%   Set colormode to 8-bit RAW
if ~strcmp(char(cam.PixelFormat.Set(uEye.Defines.ColorMode.SensorRaw8)), ...
        'SUCCESS')
    error('Could not set pixel format');
end

%   Set trigger mode to software (single image acquisition)
if ~strcmp(char(cam.Trigger.Set(uEye.Defines.TriggerMode.Software)), 'SUCCESS')
    error('Could not set trigger format');
end

%   Allocate image memory
[ErrChk, img.ID] = cam.Memory.Allocate(true);
if ~strcmp(char(ErrChk), 'SUCCESS')
    error('Could not allocate memory');
end

%   Obtain image information
[ErrChk, img.Width, img.Height, img.Bits, img.Pitch] ...
    = cam.Memory.Inquire(img.ID);
if ~strcmp(char(ErrChk), 'SUCCESS')
    error('Could not get image information');
end

%   Acquire image
if ~strcmp(char(cam.Acquisition.Freeze(true)), 'SUCCESS')
    error('Could not acquire image');
end

%   Extract image
[ErrChk, tmp] = cam.Memory.CopyToArray(img.ID); 
if ~strcmp(char(ErrChk), 'SUCCESS')
    error('Could not obtain image data');
end

%   Reshape image
img.Data = reshape(uint8(tmp), [img.Width, img.Height, img.Bits/8]);

%   Draw image
himg = imshow(img.Data, 'Border', 'tight');

%   Acquire & draw 100 times
for n=1:100
    %   Acquire image
    if ~strcmp(char(cam.Acquisition.Freeze(true)), 'SUCCESS')
        error('Could not acquire image');
    end

    %   Extract image
    [ErrChk, tmp] = cam.Memory.CopyToArray(img.ID); 
    if ~strcmp(char(ErrChk), 'SUCCESS')
        error('Could not obtain image data');
    end

    %   Reshape image
    img.Data = reshape(uint8(tmp), [img.Width, img.Height, img.Bits/8]);

    %   Draw image
    set(himg, 'CData', img.Data);
    drawnow;
end


%   Close camera
if ~strcmp(char(cam.Exit), 'SUCCESS')
    error('Could not close camera');
end

答案 1 :(得分:1)

1)简短的回答是“不”,即使你知道它在哪里以及它有多大,你也不能在MATLAB中将矩阵拉出内存。但是,Image Acquisition toolbox支持此特定相机,并附带相关教程here

答案很长,如果你用一些mex / c补充你的MATLAB代码,你可以使它工作,虽然我没有任何细节。

2)正如我在对原始问题的评论中写的那样,

[a,b,c,d] = cam.InquireImageMem(0,0,0,0);

会奏效。使用cam.methods('-full')获取库中所有可能方法的列表,以及它们所需的输入/输出。

答案 2 :(得分:1)

尝试使用uEye .NET用户层 http://en.ids-imaging.com/manuals/uEye_SDK/EN/uEye_DotNET_Manual/index.html?ueyeinstallation.htm

下面是一些示例MATLAB代码


clear all

close all

computer_type=computer;

if strcmp (computer_type,'PCWIN64')

NET.addAssembly('C:\Program Files\IDS\uEye\Develop\DotNet\x64\uEyeDotNetUserLayer.dll');

NET.addAssembly('C:\Program Files\IDS\uEye\Develop\DotNet\x64\uEyeDotNetApiLayer.dll');

elseif strcmp (computer_type,'PCWIN')

NET.addAssembly('C:\Program Files\IDS\uEye\Develop\DotNet\x86\uEyeDotNetUserLayer.dll');

NET.addAssembly('C:\Program Files\IDS\uEye\Develop\DotNet\x86\uEyeDotNetApiLayer.dll');

end

cam = uEye.Camera;

cam.Exit();

CAM_ID=2;

exposure_ms=2;

cam.Init(CAM_ID);

ColorMode=uEye.Defines.ColorMode.SENSOR_RAW8;

cam.PixelFormat.Set(11);

cam.Trigger.Set(uEye.Defines.TriggerMode.Software);

[tmp, memId] = cam.Memory.Allocate(true);

[tmp, imgWidth] = cam.Memory.GetWidth(memId);

[tmp, imgHeight] = cam.Memory.GetHeight(memId);

[tmp, imgBpp] = cam.Memory.GetBitsPerPixel(memId);

imgBpp = imgBpp / 8;

imgSize = imgWidth * imgHeight * imgBpp;

bufArr = NET.createArray('System.Byte', imgSize);

soft = uEye.Software(CAM_ID);

soft.SetEnableAutoWhiteBalance(false);

soft.SetEnableAutoGain(false);

soft.SetEnableAutoShutter(false);

cam.Timing.Exposure.Set(exposure_ms); % msec

cam.Acquisition.Freeze(1);

[tmp, camMemPtr] =  cam.Memory.ToIntPtr;

System.Runtime.InteropServices.Marshal.Copy(camMemPtr, bufArr, 0, imgSize);

img = uint8(bufArr);

myImage=reshape(img, imgWidth, imgHeight)';