📜 ⬆️ ⬇️

Using .Net libraries in MATLAB

Hello Habrovchanam! On Habré , the issue of .Net integration with Matlab has already been discussed . The goal of this article is to show how you can quickly and conveniently solve the inverse problem: call the managed code from arbitrary .Net libraries in Matlab.

Why do you need it?



Despite the rich set of algorithms in the Matlab functional, the main scenario in which this may be needed is the need to use already existing and well-known quality indicators for .Net libraries that implement mathematical algorithms in the calculations.

')

Disclaimer



The example, which is considered in the article, describes a typical set of cases arising in the course of integration, sufficient for carrying out a wide class of calculations, however, does not cover all the integration possibilities with .Net that are present in Matlab.
The code from this article was made and tested on the Windows platform and in a specific version of Matlab 2013a. 4.5 was used as the .Net Framework version, IDE - VS 2012.

Creating .Net objects in Matlab



As a simple example, consider the creation of a standard DateTime class object 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 dateTimeNow variable automatically becomes the Matlab variable. If this call fails, you can check the boolean result of the command that checks the .Net support in the environment.

 isnetsupported = NET.isNETSupported 


As an example of calling the CLR method of an object, let's add 10 minutes to the current date using the AddMinutes method, which is familiar to notebook AddMinutes

 dateTimeNow = dateTimeNow.AddMinutes(10) 


As a result of running 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 learning how to load an arbitrary assembly into Matlab, let's do it in preparation.
As a simple example, we implement in the target .Net library with the name Algorithms.dll algorithm for finding the upper left corner of the bounding rectangle of a binary image.

This can be done using this 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() {} /// <summary> ///    coordinates       ///  .    - {-1,-1} /// </summary> /// <param name="bitmap">  </param> /// <param name="coordinates">   </param> 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, which return values ​​using the out keyword. The GetLeftUpperCornerBB method takes as input a Bitmap class object that contains a binary image and returns the coordinates of the first left upper black pixel in the coordinates array (if there is no such image, for example, in the case of an empty image, null returned).

Loading custom .Net libraries in Matlab



In the Matlab directory of the project, create a new Matlab file Example.m , next to which we place the Algorithms.dll obtained in the previous step (see screenshot below)


By calling the addAssembly function, addAssembly load the assembly into Matlab.
 netAssembly = NET.addAssembly('D:\Work\MatlabNetIntegrationExample\Algorithms.dll') 


let's look through the list of classes of the loaded assembly

 netAssembly.Classes 


the result will be

 ans = 'Algorithms.ImageProcessor' 


using the command
 import Algorithms.* 

we include namespace Algorithms.

Create an object of the ImageProcessor class and load the input image into the bitmap variable
 imageProcessor = ImageProcessor(); bitmap = System.Drawing.Bitmap('picture.bmp') 


The picture.bmp file is located in the current working directory.
Team

  methods (imageProcessor) 

will show us the list of available methods for 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[] , so for the possible convenience of working with it, it is possible to convert this array into a native Matlab array. For example:

 arrayOfDoubles = coords.double; arrayOfIntegers = coords.int32; 


Reverse conversion is possible using the NET.convertArray function.

So, 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 task 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 restart of the Matlab IDE. Otherwise, in version 2013a, a fairly complete support for .Net integration is presented in terms of the possibilities of working with various CLR elements and their attributes.

Materials used


Source: https://habr.com/ru/post/177449/


All Articles