Click here to Skip to main content
15,861,168 members
Articles / Programming Languages / C#

Creating Your First EMGU Image Processing Project

Rate me:
Please Sign up or sign in to vote.
4.75/5 (65 votes)
2 Nov 2011CPOL12 min read 424.6K   94.1K   125   54
A complete step by step guide to show newcomers to EMGUcv how to set up their project

X64 Architecture (Updated) See Note [2] of History

X86 Architecture

Introduction

The following article is designed to show newcomers to EMGUcv how to set up a project step by step. This information is freely available here however, this article is designed to make the process a little more user friendly. EMGU is a C# wrapper for OpenCV, it differs from other wrappers as it is written purely in C# and does not use unsafe code. EMGU opens the OpenCV (Open Source Computer Vision Library) library of programming functions mainly aimed at real time computer vision to C# developers. OpenCV was originally developed by Intel and now supported by Willow Garage.

Current versions for both x86 and x64 architectures are available to download at their Sourceforge website.

As EMGU is a wrapper for C++ code. There are two types of Dynamic-link library’s (DLLs) that are used. There are the EMGU ones with EMGU syntax that always reference in the name and the opencv ones that vary. Setting up a first project is a common stumbling block for many newcomers and you are not alone.

If you have downloaded the source code, you will need to read “A Basic Program”. If you have copied an example from the EMGU extraction folder, then take a look at The EMGU.CV.Invoke Exception and Troubleshooting section.

Assumed Knowledge

It is assumed that a user has basic experience in C# and can generate a new C# project. It is assumed that each user has download the most recent update for their platform and has the HelloWorld example running from the EMGU extraction folder\EMGU.Examples\Hello World.

The Basic Requirements

As with any C# library, there are some essential DLLs that need referencing within your project. Start a new C# Windows Form Application and call it what you like. All DLLs mentioned are in the EMGU extraction Folder\bin - you will need to remember this. To start with, you need to reference 3 EMGU DLLs.

  • Emgu.CV.dll
  • Emgu.CV.UI.dll
  • Emgu.Util.dll

This is done by either right clicking on your project name or the References folder within the solution explorer. Go to Add Reference.

EMGU_Image_Processing/IMG1.jpg

Or alternatively using the menu item Project > Add Reference. When the Add Reference window opens, select the DLLs listed above and click OK.

EMGU_Image_Processing/IMG2.jpg

You will now see them listed in the References folder in the solution explorer window. These three DLLs are the EMGU specific C# libraries mentioned previously. These alone will not allow you to use any of the image processing functions, so please read the rest of the article.

Now you need to reference these in any class of form that you will be using the code. The references you will use will depend on what you are doing in image processing terms. Look at the examples and these will have the ones you require. To get you started, add the following to the top of the Form1.cs code behind.

C#
using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;

The Preferred Method

Now for the more complicated C++ libraries, to load, display, access image data and do many of the more simpler functions, you only need two files. Note that "220" is the version number - this will change according to updates (opencv_core***.dll, opencv_imgproc***.dll).

  • opencv_core220.dll
  • opencv_imgproc220.dll

Now because these are wrapped C++ files, you can’t reference them like you did with the EMGU files. You need to add these files to your project. This can be done in two ways - right click on your project name within solution explorer (This is not the one starting with “Solution ‘Your Project Name’ ...” but the one below this). Go to Add > Existing Item using the standard open file dialog. Select the two files above, in case you forgot they are located in the EMGU extraction Folder\bin.

Hint: If you can’t see .dlls, make sure you change the file filter at the bottom right to Executable Files.

EMGU_Image_Processing/IMG3.jpg

You will now be able to see your files within the solution explorer window. You will need to change their properties so select them both by holding down the Ctrl key and left clicking on them (alternatively, you can do this individually). Now look at Properties window, you will see six fields, two of these will be filled with content. You are interested in the Copy to Output Directory. Change this from “Do not Copy” to “Copy always”.

EMGU_Image_Processing/IMG4.jpg

If you are using the x64 compilations, go to the x64 section and ensure you set up your project to compile to a x64 architecture, other than that you are ready to start image processing. The reason this is the preferred method is that now, if you change from Debug to Release, these files will always be available to your program and no errors will occur. Jump to the reading and displaying an image section A Basic Program to start you off.

The Less Preferred Method

While not proffered, this is often the simplest and if you have a complex project architecture, this can prevent the solution explorer from looking very messy. Simply navigate in Windows Explorer to the EMGU extraction folder\bin and copy the relevant DLL files, opencv_core220.dll and opencv_imgproc220.dll to your project bin\Debug folder or to bin\Release folder. This will change with x64 versions as it will be the bin\x64\Debug folder or alternative Release folder.

While the benefits are not so clear here, imagine if you require all the opencv DLL files, then you will have an extra 34 files within the solution explorer, however, it is rare this will be the case.

x64 Architecture and the EMGU.CV.Invoke Exception

If you are running an x64 system or designing for them, you will have to download separate DLLs. The steps on forming a project are identical however you will need to change an additional build parameter. Right click on your project file in the solution explorer and select “Properties” at the bottom. Select the “Build” tab from the ribbon bar on the right of this window. There will be an option for Platform Target: with a drop down menu, change this from x86 to x64.

EMGU_Image_Processing/IMG5.jpg

Hint: If you are using the Express version of Visual Studio, you may not see the x64 option. In such a case, go to menu option Tools > Options. In this window, use the arrows to the left hand side to expand and collapse options. Select “Projects and Solutions” and select the Show advanced build configurations check box.

EMGU_Image_Processing/IMG6.jpg

This will now allow the compilation to run if this is not done correctly. As soon as you access any EMGU code, an exception will be thrown ‘EMGU.CV.Invoke’ through an exception with the ‘InnerException’ "An attempt was made to load a program with an incorrect format....”.

A Basic Program

To get you started, a simple program that loads an image and displays it in a picture box has been provided and a little bit more of an advanced one that will show how to access image data and convert between image types.

Only x64 Versions are currently available, x86 will be provided shortly.

If you have downloaded the sample code, you will start with 3 warnings for the references not being found. Expand the References folder within the solution explorer, delete the 3 with yellow warning icons and Add fresh references to them, the steps of which are available in the The Basic Requirements section.

There has been a button item and a picturebox item added to the main form. Their default names have not been changed. When we click on the button, we wish to open a file dialog select and image and have it displayed in the picturebox.

Double click on the button and add the following code:

C#
private void button1_Click(object sender, EventArgs e)
{
    OpenFileDialog Openfile = new OpenFileDialog();
    if (Openfile.ShowDialog() == DialogResult.OK)
    {
        Image<Bgr, Byte> My_Image = new Image<Bgr, byte>(Openfile.FileName);
        pictureBox1.Image = My_Image.ToBitmap();
    }
}

The code is very simple, an OpenFileDialog called 'Openfile' is used to select and image file. This image is then read into an colour Image object called 'My_Image'. The image is displayed by assigning the Image property of the picturebox. This requires a Bitmap and by calling the .ToBitmap() function of 'My_Image' this is achieved.

This is incredibly simple to achieve once the correct process has been taken in setting up the project. An alternative to the Picturebox item is made available through the EMGU.CV.UI library and is used in the examples. Please visit http://www.emgu.com/wiki/index.php/Add_ImageBox_Control to learn how to add this control to Visual Studio, should you wish to use it.

A Little More Image Processing

The slightly more advanced source code project will have the same warnings as described in A Basic Program has been provided. The references will need replacing. In this program, there is a demonstration of converting an Image from colour to greyscale and accessing the Data of individual pixels. While the methods of suppressing the image spectrum data is not the most efficient, it is a good example of accessing the image Data property.

A Little on Converting Images

Image conversion in EMGU can be complex. In the example program, a Bgr colour image is converted to Gray or grayscale.

C#
Image<gray,byte> gray_image = My_Image.Convert<gray,byte>();

However, you will eventually want to use a different depth (Tdepth) of image rather than Byte. The problem with this method is you can only convert a depth or colour once per call. Let's say we wish to convert from Image<bgr,byte> to Image<gray,double>, you would have to use the following syntax.

C#
Image<Gray,byte> gray_image = My_Image.Convert<Gray,byte>();
Image<Gray,double> gray_image = My_Image.Convert<Gray,double>();
//or alternatively in one line
Image<Gray,> gray_image = My_Image.Convert<Gray,byte>().Convert<Gray,double>();
//alternatively
Image<Gray,Byte> gray_image = My_Image.Convert<Bgr,double>().Convert<Gray,double>();

Accesing Image Data

There are a few ways of accessing image data and assigning values to it. There are two methods available, direct access using the Image Data property of a more remote access. Both are demonstrated here. Note it is important to respect the image spectrum depth when accessing the Data property. A grayscale image will have a depth of one so will be reference as [x,y,0] however a colour image as a depth of 3, [x,y,0], [x,y,1] & [x,y,2] representing the Blue, Green & Red spectrums respectively (Bgr).

Let's say we wish to assign a value to a pixel at position [0,0] a value. Using the easier remote method, we can use:

C#
//Colour Image
My_Image[0, 0] = new Bgr(Color.Red);

//Gray Image
gray_image[0, 0] = new Gray(200);

Or we use the Data property:

C#
//Colour Image
Color R = Color.Red;
My_Image.Data[0,0,2] = R.R; //Write to the Red Spectrum
My_Image.Data[0,0,1] = R.G; //Write to the Green Spectrum
My_Image.Data[0,0,0] = R.B; //Write to the Blue Spectrum

//Gray Image
gray_image[0, 0] = new Gray(200);

So writing to a pixel is fairly simple but what about reading a pixel value.

C#
//Colour Image
Bgr my_Bgr = My_Image[0, 0];

//Gray Image
Gray my_Gray = gray_image[0, 0]; 

Now in many cases, you will not want to work with “Bgr” or “Gray”, so converting them is important.

C#
//BGR to Color
Color my_colour = Color.FromArgb((int)value.Red, (int)value.Blue, (int)value.Green);

//Gray to int
int my_intensity = (int) my_Gray.Intensity;

You will notice that each value is cast to an integer to allow data loss, this is because the intensities are stored naturally as doubles. However in this case, the easier method is accessing the Image Data property. If you wish to work with the image data, there is not a requirement to constantly convert between Gray and integers, etc. You can access the image Data directly and use that.

C#
//Colour
Color my_colour = Color.FromArgb(My_Image.Data[0, 0, 0], 
My_Image.Data[0, 0, 1], My_Image.Data[0, 0, 2]);

//Gray Image
int my_intensity = gray_image.Data[0, 0, 0];

Much simpler and far easier to work with when processing the image Data within a loop. To examine how to implement a loop, please download the Little More Image Processing source code.

The DllNotFound Exception and Troubleshooting 0x8007007E

Now at some point, you are going to receive and error "Unable to load DLL...... (Exception from HRESULT: 0x8007007E)”. You need to read the Message section circled in red below.

EMGU_Image_Processing/IMG7.jpg

If the exception is a EMGU.CV.Invoke Exception, chances are you are not targeting the correct platform for your build. See the section regarding x64 Architecture for details.

Now if you’ve progressed through to an advanced image processing method or simply have copied an example to an alternative location than the EMGU extraction folder, you will possibly be seeing one of the following errors:

Unable to load DLL 'opencv_highgui220': The specified module could not be found. 
(Exception from HRESULT: 0x8007007E)

Usually caused when you are trying to get a image from a web camera. The solution to this is extremely simple. As discussed in The Basic Requirements section, you will need to either copy the opencv_highgui220.dll to the output directory or the more preferred method of adding the file to your project as an existing file and then changing its property “Copy to Output Directory” to “Copy always”. Look back at this section for reference if required.

Unable to load DLL 'cvextern': The specified module could not be found. 
(Exception from HRESULT: 0x8007007E)

This error has a little more of a substantial solution. The cvextern.dll error cannot be fixed by simply adding the this one file, in fact, this file requires all of the files listed below to correctly execute. As discussed in The Basic Requirements section, you will need to either copy files to the output directory or the more preferred method of adding the files to your project as an existing file and then changing each of their properties “Copy to Output Directory” to “Copy always”. Look back at this section for reference if required.

Note that "220" is the version number - this will change according to updates.

  • cudart64_32_16.dll
  • cufft64_32_16.dll
  • cvextern.dll
  • npp64_32_16.dll
  • opencv_calib3d220.dll
  • opencv_contrib220.dll
  • opencv_core220.dll
  • opencv_features2d220.dll
  • opencv_flann220.dll
  • opencv_gpu220.dll
  • opencv_highgui220.dll
  • opencv_imgproc220.dll
  • opencv_legacy220.dll
  • opencv_ml220.dll
  • opencv_objdetect220.dll
  • opencv_video220.dll

Any other Unable to load DLL ‘...’ errors can be fixed by attempting the same process and loading the relevant listed DLLs into your project. If you still get stuck, then feel free to ask the community for help.

System.TypeInitializationException:

Convertion from Image<Emgu.CV.Structure.Bgr*,System.Byte*> to Image<Emgu.CV.Structure.Structure.Bgr*,System.Byte*> is not supported by OpenCV

Where * is the the relevant image depth or data type.

This error is thrown up in version 2.3.* onwards and is caused by the programs inability to access opencv_imgproc***.dll or opencv_core***.dll even though they are present in the output "bin" directory.

There are two solutions, adding them to the project and set their properties to copy always as they are the two key files. Or by replacing the current ones in the Bin folder with new copies can also solve the problem.

If both methods fail, then there may be a problem with the build so download a new copy from SourceForge and try again.

I hope this article sets you on the right path. Thanks for reading!

History

  • [1] The x64 source code file links have been correctly linked.
  • [2] Added some notes about version number and DLL added x86 versions and updated x64
    The old x64 Versions will have a problem when reading image data values as eventually they will be out of bounds especially with small images. To solve this, the picturebox is set to Autosize and placed within a panel with autoscroll turned on.
  • [3] A new error has become apparent in version 2.3.* the solution has been added, thanks to Mikos for finding this problem.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Engineer Manchester Metropolitan University
United Kingdom United Kingdom
I have a large amount of experience in image processing undertaking it as a major part of my PhD. As an assistant lecturer I have helped teach the subject mater at masters level and programming skills to undergraduates. I have a good grasp of the abilities of various image processing methods and an expertise in there practical application.

What makes my experience unique is the ability to design a high-specification machine vision system from principle up. Using my extensive knowledge of electronics to produce the custom electronics often required to help provide the best images possible. Such well designed systems assist image processing algorithms and increase their abilities. Additional expertise developed from my education focuses around software engineering, electronic engineering and practical skills developed in mechanical engineering. My PHD research has produced industry quality designs that surpass the ability of products currently available to end users with in-depth experience of Image processing, microcontrollers (PIC’s) and FPGA devices. I am also experience with the new range of development boards that are replacing traditional microcontroller programming methods.

Comments and Discussions

 
QuestionCapture and save Facial recognition from file (.jpg, .png, etc.) Pin
relston20-Dec-21 4:01
relston20-Dec-21 4:01 
QuestionRequested value 'Bgr2Bgr' was not found. Pin
Weries22-Feb-18 6:24
Weries22-Feb-18 6:24 
QuestionThanks for the code, but might need to use Mat class in the future Pin
rugby231223-Nov-16 18:43
rugby231223-Nov-16 18:43 
QuestionGreat ! Pin
_Klent_19-Sep-15 6:48
_Klent_19-Sep-15 6:48 
GeneralMy vote of 5 Pin
Member 1176562321-Jul-15 16:00
Member 1176562321-Jul-15 16:00 
QuestionHi! Pin
Member King Fisher19-Apr-15 18:35
Member King Fisher19-Apr-15 18:35 
QuestionEMGU Correct Version.... Pin
Wahaj Khan7-Dec-14 5:03
Wahaj Khan7-Dec-14 5:03 
QuestionThanks Pin
KL Lawingco12-Sep-14 4:21
KL Lawingco12-Sep-14 4:21 
QuestionIt solved my problem Pin
Member 1052206628-Jun-14 13:17
Member 1052206628-Jun-14 13:17 
QuestionHow do I get more than one result in face recognition? Pin
micmdk28-Jan-14 23:16
micmdk28-Jan-14 23:16 
QuestionByte and Double Pin
dommy1A27-Jan-14 6:29
dommy1A27-Jan-14 6:29 
AnswerRe: Byte and Double Pin
C_Johnson27-Jan-14 9:04
C_Johnson27-Jan-14 9:04 
GeneralRe: Byte and Double Pin
dommy1A27-Jan-14 21:59
dommy1A27-Jan-14 21:59 
QuestionWindow mobile 6.5 Pin
swetaparmar27-Jan-14 0:18
swetaparmar27-Jan-14 0:18 
AnswerRe: Window mobile 6.5 Pin
C_Johnson27-Jan-14 9:15
C_Johnson27-Jan-14 9:15 
QuestionEmgu.CV.CvInvolke always throw exception Pin
Member 160489418-Jan-14 7:02
Member 160489418-Jan-14 7:02 
AnswerRe: Emgu.CV.CvInvolke always throw exception Pin
Member 160489418-Jan-14 7:06
Member 160489418-Jan-14 7:06 
AnswerRe: Emgu.CV.CvInvolke always throw exception Pin
Member 160489418-Jan-14 15:12
Member 160489418-Jan-14 15:12 
GeneralRe: Emgu.CV.CvInvolke always throw exception Pin
Member 1147306431-May-15 6:57
Member 1147306431-May-15 6:57 
QuestionHow to check image has yellow spot Pin
arun_pk4-Sep-13 22:36
arun_pk4-Sep-13 22:36 
QuestionEMGU.CV.CvInvoke exception :( Pin
Member 42909159-May-13 2:23
Member 42909159-May-13 2:23 
AnswerRe: EMGU.CV.CvInvoke exception :( Pin
Member 160489418-Jan-14 6:58
Member 160489418-Jan-14 6:58 
GeneralRe: EMGU.CV.CvInvoke exception :( Pin
Member 1007305112-Jul-14 23:06
Member 1007305112-Jul-14 23:06 
GeneralMy vote of 3 Pin
aisp14-May-13 1:22
aisp14-May-13 1:22 
SuggestionMy 5 but update on CvInvoke error Pin
Serge Desmedt19-Jan-13 5:47
professionalSerge Desmedt19-Jan-13 5:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.