Thursday, September 10, 2015

Vote for the fo-dicom logo!

Create your own user feedback survey

Thursday, January 29, 2015

Portable AForge and Accord libraries - Now on NuGet!

I have finally taken the step and published the Portable AForge.NET and Portable Accord.NET libraries on NuGet!

This means that it has now become a no-brainer to effortlessly include these libraries in your mobile or tablet application, regardless of whether you are developing with Visual Studio or Xamarin Studio.

As a bonus teaser, I have also included evaluation builds of Shim.Drawing (the bridging library between the Bitmap class representation in AForge and Accord with the platform specific image classes) for Xamarin Android, Xamarin iOS, Windows Phone 8.1 (non-Silverlight) and Windows 8.1. For Xamarin iOS, both the Unified and Classic APIs are supported.

The evaluation builds offer all functionality of the full version, but a watermark is added to images processed by Shim.Drawing. This means that it has now become extremely easy to test the AForge.NET and Accord.NET functionality on all relevant mobile and tablet platforms. After successful evaluation, the full version (without watermarks) of the Shim.Drawing library is available for purchase from Cureos. The license cost as of January 29, 2015 is $100 for one platform (Android, iOS, Windows Phone or Windows 8.1), $150 for two platforms and $200 for all supported platforms.

I have also updated the samples repository on Github to use NuGet. In the samples repository you'll currently find an image stitching application for Windows Phone Silverlight 8 and a Xamarin Forms face detection application for Android, iOS and Windows Phone Silverlight 8. The face detection application has recently been presented in more detail in this blog post. More examples to get you started will be published soon.

Link summary

Wednesday, October 22, 2014

Smartphone image processing development made easy!

A very popular open source C# project for image processing, neural networks, machine learning etc. is the AForge.NET Framework, developed by Andrew Kirillow. AForge.NET has been used in numerous applications. It also forms the basis for the Accord.NET Framework, developed by César de Souza, which substantially extends AForge.NET with additional image processing filters, machine learning algorithms, statistical distributions and much much more. Numerous examples of what Accord.NET Framework is capable of are available here.

AForge.NET was developed to run on the .NET Framework and uses the System.Drawing assembly as basis for image manipulation and processing. In particular the dependency on System.Drawing heavily limits the applicability of AForge.NET (and subsequently, Accord.NET) to more modern platforms, like WPF, Windows (for tablet and desktop, as opposed to desktop-only applications), and Windows Phone.

It seemed like a terrible waste that these frameworks would only be available to the outdated range of Windows Forms applications. So, to enable the invaluable functionality of AForge.NET and Accord.NET for modern Microsoft platforms, I started the project of porting these frameworks into Portable Class Libraries, PCL. These efforts are also open sourced and are available on Github: Portable AForge and Portable Accord.

It should be noted that Portable AForge and Portable Accord cover a subset of the assemblies in the pure .NET based frameworks. Video and robotics support is not included, and audio support is limited. Windows Forms UI controls have not been ported. Nevertheless, practically all image processing and scientific computing functionality is included in the portable frameworks.

To facilitate continuous inclusion of updated code for the two frameworks, I have striven to keep the original AForge.NET and Accord.NET code bases as untouched as realistically possible. To cover up for those parts of the framework codes that are not applicable in the portable class libraries, I have therefore developed two support assemblies called Shim and Shim.Drawing.

Shim, which contains simple implementations of non-UI types and methods unavailable in the PCL profiles, is maintained in a separate Github repository, since this assembly is also immediately applicable as a legacy code bridge in other modern target adaptations, such as the port of the fo-dicom library to the (modern) Windows and Windows Phone platforms.

Shim.Drawing is internal to the Portable AForge and Accord assemblies, and is contained in the Portable AForge Github repository. It provides a down-scaled replacement for the System.Drawing assembly. Along with the platforms of primary interest, Shim.Drawing can also be contained in a .NET Framework WPF project as long as System.Drawing is not simultaneously referenced. Portable AForge and Accord is thus a also shortcut to using AForge.NET and Accord.NET in WPF applications.

To enable the portable framework assemblies on a specific target platform, the Shim and Shim.Drawing assemblies come in various flavors. There are for example specific Windows Phone (Silverlight) 8 versions of Shim and Shim.Drawing that should be referenced in a WP8 application using the Portable AForge and Accord assemblies.

Currently, Portable AForge and Portable Accord are available for the following target platforms:

  • .NET Framework 4.5 and higher (for WPF applications)
  • Windows 8 and higher (modern tablet/desktop applications)
  • Windows Phone Silverlight 8 and higher
  • Universal applications, i.e. Windows Phone 8.1 + Windows 8.1
  • Xamarin.iOS
  • Xamarin.Android

Yes, you read it right! My most recent developments also incorporate the ability to target the Xamarin.iOS and Xamarin.Android platforms. The Xamarin assemblies are however not available as open source. If you are interested in developing AForge and Accord based applications for Xamarin.iOS and/or Xamarin.Android, please contact me directly at licenses@cureos.com.

And now, with AForge and Accord available on the three mobile platforms, cross-platform development using Xamarin.Forms has also become a reality! This means that it is practically possible to contain an entire C# code base in a PCL core library that uses AForge and Accord, and consume this core library from end applications for all three mobile platforms, Windows Phone, Xamarin.iOS and Xamarin.Android.

Just to show what can now be very quickly done, I copied the functionality of the Face Detection (Haar Object Selector) sample application from the Accord.NET samples and contained it in a Xamarin.Forms project. All application code, including setting up the graphical layout and the face detection operation, is contained in the PCL core project. The platform specific end application projects only wrap the core assembly.

And this is what the face detection sample application looks like on the three mobile platforms:


A first small step, perhaps, but the possibilities that have now been opened up are practically infinite :-)


Monday, August 18, 2014

PCL Tips and Tricks: String sbyte* constructor

The introduction of Portable Class Libraries, PCL, considerably facilitates the sharing of functionality across managed Microsoft and Xamarin platforms. I am very enthusiastic about the PCL concept, and I have ported several .NET Framework open source projects to Portable Class Libraries. Along the way I have stumbled across various issues of making .NET Framework source code PCL compliant. In this mini-series I'll share my experiences and workarounds to facilitate the transfer to PCL for other developers.

Some of the PCL profiles do support unsafe code, in particular those profiles targeting Windows 8 and Windows Phone 8.1 (non-Silverlight). This means that it is possible to include for example pointers in the PCL code. On the other hand, methods dealing with unsafe code are rare in the .NET Portable Subset.

One case I ran into the other day is the String constructor. In .NET Framework, there are a few constructors taking an sbyte pointer as an argument, for example:

public String(sbyte* value, int startIndex, int length)

This constructor is not available in the .NET Portable Subset, so I had to come up with a replacement. And I came up with this portable method:

static unsafe String NewString(
    sbyte* value, int startIndex, int length)
{
  var chars = new char[length];
  for (var i = 0; i < length; ++i)
    chars[i] = (char)value[startIndex + i];
  return new String(chars);
}

So, instead of calling new String(...), the calls were changed to NewString(...).

I am still not entirely pleased with this approach of adding a new method to solve the issue. If any blog reader has a leaner solution to this issue, I am all ears.

Saturday, June 7, 2014

Upgrading Caliburn Micro from 1.5 to 2.0 for a WPF application

I am happy to see that the Model-View-View Model (MVVM) framework Caliburn Micro is adopting the Portable Class Library approach in version 2.0, and I thought that now would also be a good time to upgrade some of my existing applications from Caliburn Micro 1.5 to version 2.0.

So far, this seems to be a painless experience, but I ran to a few issues after upgrading to 2.0 via NuGet. I'd thought I share these experiences in case someone else is facing the same issues.

The application in question is a WPF application, and it is using the Managed Extensibility Framework (MEF) for bootstrapping the application.

When trying to build the application immediately after the upgrade, I ran into a compilation error in the class definition line of my MEF bootstrapper class:

public MefBootstrapper : Bootstrapper<IShell>

error CS0246: The type or namespace name 'Bootstrapper' could not be found (are you missing a using directive or an assembly reference?)

Searching the Caliburn Micro documentation, I found that the bootstrapper base class is now called ... BootstrapperBase! And it is non-generic.

OK, this change seems easy:

public MefBootstrapper : BootstrapperBase

Hooray, the application builds! Let's run it. And wait ... and wait ... and wait ... but it never starts?

Of course! Since the bootstrapper base class is now non-generic, there is no way for the bootstrapper to know which View it should start displaying, unless it is explicitly being told which View it should display. And according to this documentation page, the fix is easy; just add

DisplayRootViewFor<IShell>();

to the overridden OnStartup method.

Let's try to run the application again. Still no sight of the root window. What is missing?

Looking more closely into the bootstrapper implementation example here, the constructor also seems to perform some initialization operation. This was not necessary with the pre-2.0 Caliburn Micro versions, most likely because the base class constructor performed this operation instead. But with 2.0 it seems to be necessary to also implement the bootstrapper constructor explicitly. According to the migration instructions here it also seems like the Start method has been renamed Initialize. So, here goes:

public MefBootstrapper() { Initialize(); }

Run the application, and ... Yes! The start-up window appears!

To summarize: when upgrading a WPF/MEF application from using Caliburn Micro version 1.5 or earlier to version 2.0, make sure the following details are in place:

  • The MEF based bootstrapper class should inherit from BootstrapperBase.
  • The root view will be displayed by calling DisplayRootViewFor<> in the overridden OnStartup method.
  • The bootstrapper default constructor must be explicitly defined, and call the Initialize() method.

EDIT

Ironically, when I started upgrading my second application I faced a completely different compilation error:

error CS1501: No overload for method 'Publish' takes 1 arguments

But this issue has a quick and easy fix, as pointed out in the migration instructions:

EventAggregator.Publish now takes an action to marshal the event. Use EventAggregator.PublishOnUIThread for the existing behaviour.


Thursday, June 5, 2014

PCL Tips and Tricks: Extension methods to the rescue

The introduction of Portable Class Libraries, PCL, considerably facilitates the sharing of functionality across managed Microsoft and Xamarin platforms. I am very enthusiastic about the PCL concept, and I have ported several .NET Framework open source projects to Portable Class Libraries. Along the way I have stumbled across various issues of making .NET Framework source code PCL compliant. In this mini-series I'll share my experiences and workarounds to facilitate the transfer to PCL for other developers.

Now, here is a very common scenario when porting .NET class libraries to PCL:

public class SomeClassToPort
{
    public static byte[] SomeMethodToPort()
    {
        var stream = new MemoryStream();
        var writer = new StreamWriter(stream);
        writer.Write("Result: {0}, {1}", 10, "Hello");
        // some more writer operations ...

        writer.Close();   // Non-existent in PCL
        stream.Close();   // Non-existent in PCL

        return stream.ToArray();
    }
}

Correct, the Close() method is not available for streams, readers or writers in Portable Class Libraries! Since the method in practice only executes Dispose(), the Close() method has been excluded from PCL. Trying to build this code yields the following error:

error CS1061: 'System.IO.MemoryStream' does not contain a definition for 'Close' and no extension method 'Close' accepting a first argument of type 'System.IO.MemoryStream' could be found (are you missing a using directive or an assembly reference?)

Dispose() is generally available in PCL, so one solution is to replace all Close() calls with Dispose(). For those wanting to avoid the hassle and maintenance issues of replacing (potentially numerous) Close() calls, there is however a workaround.


Extension methods are a perfect fit for dealing with a scenario like the above. You can just add a static class with an arbitrary name to the PCL library, with code similar to this:

public static class CloseExtensions
{
    public static void Close(this Stream stream)
    {
        stream.Dispose();
    }

    public static void Close(this TextWriter writer)
    {
        writer.Dispose();
    }
}

Now, the compiler will "translate" stream.Close() into the call CloseExtensions.Close(stream) (analogously for the StreamWriter object) and the Portable Class Library can then build successfully. The extension methods perform practically the same operations as the Close() methods in the .NET Framework. Subsequent calls to Dispose() have no effect, so this implementation should be fail-safe. 

There is also no risk of name clashes; even when the PCL library is used in a .NET application the original Close() methods and the corresponding extension methods have completely different signatures (they can just be expressed equivalently in the code).

The Close() methods are probably the most obvious examples where this extension method technique can be applied, but whenever a PCL profile is not including an instance method of one type, the same technique may be applied. Other examples from the top of my head are:
  • several methods from the Type class which are not available for Windows 8 (f.k.a. Store or Metro apps); much of this functionality has been replaced by TypeInfo instance and extension methods,
  • Stream.BeginRead, Stream.EndRead, Stream.BeginWrite and Stream.EndWrite; again not available for Windows 8 but can be simulated using extension methods.

Thursday, May 22, 2014

BioSuite and DICOM

A few years ago Dr. Julian Uzan together with Professor Alan Nahum developed a comprehensive research tool for radiobiological evaluation and optimization, called BioSuite. The tool has continuously evolved and has been made available at no extra cost for the participants of the Clatterbridge Radiobiological Modeling course that is being held (more or less) annually.

BioSuite uses input from treatment planning systems in the form of differential dose-volume histograms (DVHs). More specifically, the tool supports DVHs exported from Philips Pinnacle³ and Varian Eclipse. One format BioSuite does not support though, is DICOM!

To overcome this limitation, I have developed a simple preprocessing tool called the BioSuite Exporter. This tool allows the user to import DICOM RT Plans, RT Structure Sets and RT Doses,


and based on this data the tool computes the resulting dose volume-histograms associated with each RT Plan for the regions of interest in the RT Structure Set. The user can view the dose-volume histograms and select a subset of the DVHs for export.


Upon export, BioSuite Exporter writes absolute volume, differential dose-volume histograms for each of the selected regions-of-interest in a comma-separated value (CSV) format that can be imported by BioSuite.

For BioSuite users and others interested in obtaining a free copy of this tool, please contact me at biosuite@cureos.com.