Search code examples
c#.net-coreemgucv

Running Emgu.CV on linux


I am attempting to use Emgu on linux, but getting the error message:

Unhandled exception. System.TypeInitializationException:
The type initializer for 'Emgu.CV.CvInvoke' threw an exception.
---> System.DllNotFoundException: Unable to load shared library 'cvextern' or one of its dependencies

After looking around in SO and the documentation I understand that I need to:

Make sure the unmanaged DLLs are in the execution directory.

But - how do I get them?
If I run the same project on a windows machine (+ un commenting the reference to the Emgu.CV.runtime.windows package), I indeed get x86 & x64 folders in my bin folder which I can get the binaries from, but apparently when using Emgu.CV.runtime.ubuntu package, those folders are not created.


Minimal, Reproducible Example:
Program.cs:

using Emgu.CV;
using Emgu.CV.Structure;
using System;

namespace temp
{
    class Program
    {
        static void Main(string[] args)
        {
            // Works on windows, fails on linux
            var imageFromBytes = new Image<Rgb, byte>(2, 2);


            //// Later on I would like this to work as well...
            // var bytes = new byte[] { 1, 2, 3, 4 };
            // CvInvoke.Imdecode(bytes, Emgu.CV.CvEnum.ImreadModes.Color, imageFromBytes.Mat);
        }

    }
}

The project file:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Emgu.CV.runtime.ubuntu" Version="4.4.0.4061" />

    <!-- When running on windows & uncommenting this line - I get can get the binaries-->
    <!-- <PackageReference Include="Emgu.CV.runtime.windows" Version="4.4.0.4061" /> -->

  </ItemGroup>

</Project>


Additional information:
dotnet version: 3.1.301
Emgu version: 4.4.0.4061


Solution

  • So, after few days of struggling - answering my own question.

    As far as I understand, there were two issues here:

    1. libcvextern.so was missing.
    2. libcvextern.so dependencies were missing.

    Fixing the issues:

    1. Missing libcvextern.so:

    1. Downloaded the Emgu.CV.runtime.ubuntu
    2. unzip it and get the libcvextern.so file (build/x64/libcvextern.so).
    3. Add the libcvextern.so file to the project and set Copy to Output directory to Copy if Newer

    Note: For the windows nuget package the files that you need are added automatically. Not sure why this does not happen for linux.

    2. Missing dependencies:

    1. As per the documentation (Linux -> Getting ready), I have cloned the repo and ran the script that makes sure that all dependencies are installed:

    get dotnet Framework:

    wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
    dpkg -i packages-microsoft-prod.deb
    

    Get the source code:

    git clone https://github.com/emgucv/emgucv emgucv 
    cd emgucv
    git submodule update --init --recursive
    

    Make sure the dependencies are available:

    # cd into the relevant platform
    cd platforms/ubuntu/20.04
    
    # As per documentation: This only needs to be run once.
    ./apt_install_dependency
    
    # This is what actually builds the dependencies. This will take a while...
    ./cmake_configure
    
    

    Bonus:
    If you, like me, don't have root permissions to your machine, you can use docker.

    I'll try and keep posting docker files for new versions as they come out with my conclusions after making emgu work...

    Last Update: MAR-2024:

    The Dockerfile I have used:

    .NET 8, emgu 4.8, (also updated to ubuntu:22.04) MAR-2022:

    FROM ubuntu:22.04
    ENV LC_ALL=C.UTF-8 LANG=C.UTF-8
    RUN  apt-get update && apt-get install -y sudo wget git
    
    # Dotnet Framework
    # https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu
    WORKDIR /tmp
    RUN wget https://packages.microsoft.com/config/ubuntu/20.10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
    RUN dpkg -i packages-microsoft-prod.deb
    
    RUN apt-get update && apt-get install -y dotnet-host
    RUN apt-get update && apt-get install -y dotnet-sdk-8.0
    
    # Make sure all emgu dependencies are in place
    # http://www.emgu.com/wiki/index.php/Download_And_Installation#Getting_ready
    WORKDIR /mnt/emgu_repo
    RUN git clone https://github.com/emgucv/emgucv emgucv
    WORKDIR /mnt/emgu_repo/emgucv
    RUN git fetch origin 4.8.0
    RUN git checkout 4.8.0
    RUN git submodule update --init --recursive
    
    
    # install cmake for compiling open cv dependencies & emgu dependencies
    RUN apt-get update && apt-get install -y build-essential cmake protobuf-compiler ffmpeg libgtk-3-dev libgstreamer1.0-dev libavcodec-dev libswscale-dev libavformat-dev libv4l-dev ocl-icd-dev freeglut3-dev libgeotiff-dev libusb-1.0-0-dev libdc1394-dev
    
    WORKDIR /mnt/emgu_repo/emgucv/platforms/ubuntu/22.04
    RUN ./apt_install_dependency
    
    # this takes a long time
    RUN ./cmake_configure
    
    WORKDIR /mnt/my_app_root
    

    .NET 7, emgu 4.6, Dec-2022:

    FROM ubuntu:20.04
    ENV LC_ALL=C.UTF-8 LANG=C.UTF-8
    
    RUN apt-get update && apt-get -y install sudo
    
    # Dotnet Framework
    # https://docs.microsoft.com/en-us/dotnet/core/install/linux-ubuntu
    WORKDIR /tmp
    RUN wget https://packages.microsoft.com/config/ubuntu/20.10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
    RUN dpkg -i packages-microsoft-prod.deb
    RUN apt-get update; \
      apt-get install -y apt-transport-https && \
      apt-get update && \
        apt-get install -y dotnet-sdk-7.0
    
    
    # Make sure all emgu dependencies are in place
    # http://www.emgu.com/wiki/index.php/Download_And_Installation#Getting_ready
    WORKDIR /mnt/emgu_repo
    RUN git clone https://github.com/emgucv/emgucv emgucv
    WORKDIR /mnt/emgu_repo/emgucv
    RUN git fetch origin 4.6.0
    RUN git checkout 4.6.0
    RUN git submodule update --init --recursive
    
    # install cmake for compiling open cv dependencies
    RUN apt-get update && apt-get install -y cmake protobuf-compiler ffmpeg libgtk-3-dev libgstreamer1.0-dev libavcodec-dev libswscale-dev libavformat-dev libv4l-dev ocl-icd-dev freeglut3-dev libgeotiff-dev libusb-1.0-0-dev libdc1394-dev
    
    WORKDIR /mnt/emgu_repo/emgucv/platforms/ubuntu/20.04
    RUN ./apt_install_dependency
    # this takes a long time
    RUN ./cmake_configure
    
    
    WORKDIR /mnt/my_app_root
    # emgu needs the libcvextern.so file & dependency in the rrot folder
    RUN cp /mnt/emgu_repo/emgucv/libs/runtimes/ubuntu-x64/native/* ./
    
    
    ENTRYPOINT ["bash"]
    

    .NET core 3.1, emgu 4.3, Sep-2020:

    FROM ubuntu
    ENV LC_ALL=C.UTF-8 LANG=C.UTF-8
    
    
    # Bring the dotnet Framework
    RUN wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
    RUN dpkg -i packages-microsoft-prod.deb
    RUN apt-get update; \
      apt-get install -y apt-transport-https && \
      apt-get update && \
      apt-get install -y dotnet-sdk-3.1
    
    
    # Make sure all emgu dependencies are in place
    # http://www.emgu.com/wiki/index.php/Download_And_Installation#Getting_ready
    WORKDIR /mnt/emgu_repo
    RUN git clone https://github.com/emgucv/emgucv emgucv
    WORKDIR /mnt/emgu_repo/emgucv
    RUN git submodule update --init --recursive
    WORKDIR /mnt/emgu_repo/emgucv/platforms/ubuntu/18.04
    RUN apt-get update && apt-get -y install sudo
    RUN `cat ./apt_install_dependency.sh | grep -Ev "\#\!"` -y
    RUN ./cmake_configure.sh
    
    
    ENTRYPOINT ["bash"]