Using .Net Libraries in MATLAB
- From the sandbox
- Tutorial
Hi to Khabrovchanam! The issue of .Net integration with Matlab was already discussed on Habré . The purpose of this article is to show how you can quickly and conveniently solve the inverse problem: call managed code from arbitrary .Net libraries in Matlab.
Despite the rich set of algorithms in Matlab’s functionality, the main scenario in which this may be needed is the need to use libraries that have mathematical algorithms implemented in existing and possessing well-known .Net quality indicators.
The example that is discussed in the article describes a typical set of cases arising during integration, sufficient for a wide class of calculations, however, it does not cover all the possibilities of integration with .Net that are present in Matlab.
The code from this article was made and tested on a Windows platform and in a specific version of Matlab 2013a. As the version of .Net Framework was used 4.5, IDE - VS 2012.
As a simple example, consider creating a standard class object
Getting the current date-time from .Net can be written with the following Matlab code
Immediately note that this is the complete code. We are not required to explicitly connect any .Net system libraries, and the CLR variable dateTimeNow automatically becomes a Matlab variable. If this call fails, you can check the Boolean result of the command that checks for .Net support in the environment.
As an example of calling the CLR method of an object, we add 10 minutes to the current date using the method familiar to donors
As a result of launching these commands, the output displays the contents of the received objects
Before we learn how to load an arbitrary assembly into Matlab, we will prepare it.
As a simple example, we implement in the target .Net library with the name
This can be done with the following C # code:
This code is specific: we will consider calling non-static public methods from Matlab that return values using a keyword
In the Matlab directory of the project, create a new Matlab file
Using the function call,
look at the list of classes of the loaded assembly
the result will be
using the command
enable namespace Algorithms.
Create a class object
the file
Command
will show us a list of available methods of this object
Now, run the target method
If we had several
Note that the result is a CLR object of type
Reverse conversion is possible using the function
Total, we get the following listing:
We solved the problem of creating a .Net object in Matlab, running methods of .Net classes and getting results.
Separately, it is worth noting that, according to the Matlab documentation, unloading loaded .Net modules is not explicitly provided. Therefore, to replace the DLL file, you will need at least a reboot of the Matlab IDE. Otherwise, in version 2013a, there is quite complete support for .Net integration in the sense of the ability to work with various CLR elements and their attributes.
Why is this needed?
Despite the rich set of algorithms in Matlab’s functionality, the main scenario in which this may be needed is the need to use libraries that have mathematical algorithms implemented in existing and possessing well-known .Net quality indicators.
Disclaimer
The example that is discussed in the article describes a typical set of cases arising during integration, sufficient for a wide class of calculations, however, it does not cover all the possibilities of integration with .Net that are present in Matlab.
The code from this article was made and tested on a Windows platform and in a specific version of Matlab 2013a. As the version of .Net Framework was used 4.5, IDE - VS 2012.
Creating .Net objects in Matlab
As a simple example, consider creating a standard class object
DateTime
from .Net. Getting the current date-time from .Net can be written with the following Matlab code
dateTimeNow = System.DateTime.Now
Immediately note that this is the complete code. We are not required to explicitly connect any .Net system libraries, and the CLR variable dateTimeNow automatically becomes a Matlab variable. If this call fails, you can check the Boolean result of the command that checks for .Net support in the environment.
isnetsupported = NET.isNETSupported
As an example of calling the CLR method of an object, we add 10 minutes to the current date using the method familiar to donors
AddMinutes
dateTimeNow = dateTimeNow.AddMinutes(10)
As a result of launching these commands, the output displays the contents of the received objects
Date: [1x1 System.DateTime]
Day: 21
DayOfWeek: [1x1 System.DayOfWeek]
DayOfYear: 111
Hour: 13
Kind: [1x1 System.DateTimeKind]
Millisecond: 160
Minute: 49
Month: 4
Now: [1x1 System.DateTime]
UtcNow: [1x1 System.DateTime]
Second: 56
Ticks: 635021489961600559
TimeOfDay: [1x1 System.TimeSpan]
Today: [1x1 System.DateTime]
Year: 2013
MinValue: [1x1 System.DateTime]
MaxValue: [1x1 System.DateTime]
Cooking DLL
Before we learn how to load an arbitrary assembly into Matlab, we will prepare it.
As a simple example, we implement in the target .Net library with the name
Algorithms.dll
the search algorithm for the upper left corner of the bounding box of the binary image. This can be done with the following C # code:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Algorithms
{
public class ImageProcessor
{
public ImageProcessor() {}
///
/// Возвращает в массиве coordinates координаты левого верхнего угла бинарной картинки
/// на изображении. Если их нет - {-1,-1}
///
/// Входное бинарное изображение
/// Координаты левого верхнего угла
public void GetLeftUpperCornerBB(Bitmap bitmap, out int[] coordinates)
{
coordinates = null;
var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly,
PixelFormat.Format32bppRgb);
unsafe
{
//получаем указатель на память изображения
uint* p = (uint*) bitmapData.Scan0.ToPointer();
coordinates = new int[2]{-1,-1};
//пиксели записаны по строкам
for (int i = 0; i < bitmap.Height*bitmap.Width; i++)
{
if( (*p & 0xFFFFFF) == 0) //нашли первый черный пиксель
{
coordinates[0] = i / bitmap.Width;
break;
}
p++;
}
p = (uint*) bitmapData.Scan0.ToPointer();
for (int i = 0; i < bitmap.Height*bitmap.Width; i++)
{
if( (p[( i % bitmap.Height) * bitmap.Width + ( i / bitmap.Height) ] & 0xFFFFFF) == 0) //нашли первый черный пиксель
{
coordinates[1] = i / bitmap.Height;
break;
}
}
}
bitmap.UnlockBits(bitmapData);
}
}
}
This code is specific: we will consider calling non-static public methods from Matlab that return values using a keyword
out
. The method GetLeftUpperCornerBB
accepts an object of the class Bitmap
that contains the binary image as an input and returns the coordinates
coordinates of the first left upper black pixel in the array (and if there isn’t such an image, for example, in the case of an empty image, it returns null
).Loading custom .Net libraries in Matlab
In the Matlab directory of the project, create a new Matlab file
Example.m
, next to which we will place the library obtained in the previous step Algorithms.dll
(see the screenshot below) Using the function call,
addAssembly
load the assembly into Matlab.
netAssembly = NET.addAssembly('D:\Work\MatlabNetIntegrationExample\Algorithms.dll')
look at the list of classes of the loaded assembly
netAssembly.Classes
the result will be
ans =
'Algorithms.ImageProcessor'
using the command
import Algorithms.*
enable namespace Algorithms.
Create a class object
ImageProcessor
and load the input image into a variablebitmap
imageProcessor = ImageProcessor();
bitmap = System.Drawing.Bitmap('picture.bmp')
the file
picture.bmp
is located in the current working directory. Command
methods (imageProcessor)
will show us a list of available methods of this object
Methods for class Algorithms.ImageProcessor:
Equals delete le
GetHashCode eq lt
GetLeftUpperCornerBB findobj ne
GetType findprop notify
ImageProcessor ge
ToString gt
addlistener isvalid
Now, run the target method
GetLeftUpperCornerBB
and get the result coords = imageProcessor.GetLeftUpperCornerBB(bitmap);
If we had several
out
parameters (suppose, as many as three arrays with coordinates), then we would write such code to get them [coords, cords2, cords3] = imageProcessor.GetLeftUpperCornerBB(bitmap);
Note that the result is a CLR object of type
System.Int32[]
, therefore, for the possible convenience of working with it, it is possible to convert this array to Matlab's native array. For instance:arrayOfDoubles = coords.double;
arrayOfIntegers = coords.int32;
Reverse conversion is possible using the function
NET.convertArray
. Total, we get the following listing:
netAssembly = NET.addAssembly('D:\Work\MatlabNetIntegrationExample\Algorithms.dll');
netAssembly.Classes;
import Algorithms.*;
imageProcessor = ImageProcessor();
bitmap = System.Drawing.Bitmap('picture.bmp');
methods (imageProcessor);
coords = imageProcessor.GetLeftUpperCornerBB(bitmap);
arrayOfIntegers = coords.int32;
Conclusion
We solved the problem of creating a .Net object in Matlab, running methods of .Net classes and getting results.
Separately, it is worth noting that, according to the Matlab documentation, unloading loaded .Net modules is not explicitly provided. Therefore, to replace the DLL file, you will need at least a reboot of the Matlab IDE. Otherwise, in version 2013a, there is quite complete support for .Net integration in the sense of the ability to work with various CLR elements and their attributes.