2

I'm trying to call a MATLAB function from C# using MLApp class, feval function specifically.

Since I'm a beginner I looked through the internet and found help calling MATLAB functions. I just simply called a MATLAB function which takes two integers as input and MATLAB returns sum and difference correctly. But the reason I really need to do this is to send an image to MATLAB function and perform some analysis.

So far I haven't been able to find anything helpful over the internet. Can this class be used to pass images to MATLAB function if so, how? If not what other ways are there?

MATLAB

function [x,y] = myfunc(a,b) 
  x = a + b; 
  y = a-b;

C#

MLApp.MLApp matlab = new MLApp.MLApp();
matlab.Execute(@"cd 'D:\Program Files\MATLAB\MATLAB Production Server\R2015a\bin'");
object result = null;
matlab.Feval("myfunc", 2, out result, 3, 2);
object[] res = result as object[];
Console.WriteLine(res[0]);
Console.WriteLine(res[1]);
Console.ReadLine();
Amro
  • 123,847
  • 25
  • 243
  • 454
Atif
  • 159
  • 3
  • 11
  • What "image" do you want to send? If it is an image on the filesystem, you can open it using Matlab. Or do you want to send an C# object representing an image? That makes also no sense as you cannot do anything with it in Matlab. – DVarga Apr 09 '16 at 16:06
  • i'm trying to design the front end of an application which takes image from user and computes some image features using matlab function, i want to send the input image to matlab funcion which is already defined and get back values of the features evaluated. – Atif Apr 09 '16 at 16:16
  • *front end on visual studio C# – Atif Apr 09 '16 at 16:25
  • Som your GUI displays the image and you have some buttons for example to "put some effects on it". When the user presses the button, you want to send the image to matlab to apply the effect, then you want to send it back to C# to display it again? The problem is that Matlab has an internal representation of an image, e.g. image = imread('path_to_the_image_file') and also C# has one. You cannot covert simply from one to other. You can save the file into a temporary one between each step and just send the path or you could check the possibility to image to bytrestream and send that bytestrem. – DVarga Apr 09 '16 at 16:29
  • i did find this link that explains what i need to do using MCR https://domoreinlesstime.wordpress.com/2013/01/26/access-matlab-from-c/ but there are some confusions and MWNumericArray keeps throwing exceptions. – Atif Apr 09 '16 at 16:40
  • Of you could share this link sooner, and also: http://de.mathworks.com/help/matlab/matlab_external/call-matlab-function-from-c-client.html I guess you worked based on these two. I guess the problem us "myfunc" is not on Matlab path. Have you placed an M-file myfunc.m in "'D:\Program Files\MATLAB\MATLAB Production Server\R2015a\bin'" ? – DVarga Apr 09 '16 at 16:47
  • i found the link i mentioned after posting the question and the link you posted works totally fine but the problem is i can't send image object or even image in array form using Feval method. – Atif Apr 09 '16 at 16:58
  • I don't understand you. You shall not try to send an IMAGE, as you can do nothing with that. You shall convert the imae to a 3 dimensional array, like on this link: https://domoreinlesstime.wordpress.com/2013/01/26/access-matlab-from-c/ Then if you pass this array to a Matlab function, it will be converted to a 3D matrix. Everything is described in the "Processing Images using MATLAB function." section of the link. – DVarga Apr 09 '16 at 17:02

1 Answers1

2

An easy way would be to save the image to disk from your C# application, then call MATLAB (using COM Automation as you've shown) to evaluate your image processing function by passing it the file name as a string. The MATLAB function would simply load the image by name, process it, and save the result as another image. Then return the path to the output image from your MATLAB function to C#, which finally reads it on its own..

So in C# you would do something like:

static void Main(string[] args) 
{
    var img = ...;  // image data
    string input_image = @"C:\path\to\image.png";
    save_image(img, input_image);    // save your image to disk

    MLApp.MLApp matlab = new MLApp.MLApp(); 
    object result = null; 
    matlab.Feval("my_processing_func", 1, out result, image); 
    object[] res = result as object[]; 
    string output_image = (string) res[0];

    var img_processed = load_image(output_image);  // load image from disk
} 

On the MATLAB side, the function does something like:

function out_fname = my_processing_func(in_fname)
    % read input image
    img = imread(in_fname);

    % ... apply some image processing functions
    img = process(img);

    % write resulting image to disk
    out_fname = [tempname() '.png'];
    imwrite(img, out_fname);
end

You could also pass data between C# and MATLAB COM server using PutFullMatrix and GetFullMatrix functions. The image would simply be a matrix of numeric values. Just remember that MATLAB stores array in column-major order.

Here is a sample code that shows how to retrieve variables from MATLAB workspace in C#: https://stackoverflow.com/a/21123727/97160


A third option would be to use the MATLAB Compiler SDK toolbox. This lets you compile/package your MATLAB functions into a .NET assembly that can be used on machines without MATLAB (requires the MCR runtime).

Community
  • 1
  • 1
Amro
  • 123,847
  • 25
  • 243
  • 454
  • i honestly don't know why i didn't think of that you're a genius. this actually sounds promising, let me try this read and write image way and i'll get back to you with the feedback. also the MCR method you mentioned, i've been trying to do that as well but the MWNumericarray isn't working for some reason i figured there is some 32-bit 64-bit conflict i'm using matlab 2015a 64-bit and MS Visual studio 2015 32-bit so the MWNumericarray keeps throwing exceptions, i even tried using 32-bit MWArray.dll reference but it still doesn't work. – Atif Apr 10 '16 at 02:12
  • Like I explained, that's a completely different question from the code you've posted (one using COM Automation, the other using .NET Builder toolbox).. Anyway you should consult the documentation of Compiler SDK, it is pretty thorough: http://www.mathworks.com/help/compiler_sdk/dotnet_assembly_integration.html, http://www.mathworks.com/help/compiler_sdk/dotnet/integrate-your-net-assembly-into-a-c-application.html, https://www.mathworks.com/help/dotnetbuilder/MWArrayAPI/ – Amro Apr 10 '16 at 12:27