Tutorial: Difference between revisions

From EMGU
Jump to navigation Jump to search
No edit summary
Line 55: Line 55:
|}
|}


==Working with images==
==Objects in Emgu CV (Image, Matrix ...)==
=== Depth and Color as Generic Parameter ===
An Image is defined by its generic parameters: '''color''' and '''depth'''. To create a 8bit unsigned Grayscale image, in [[Emgu CV]] it is done by calling
<source lang="csharp">
Image<Gray, Byte> image = new Image<Gray, Byte>( width, height);
</source>
Not only this syntax make you aware the color and the depth of the image, it also restrict the way you use functions and capture errors in compile time. For example, the <code>SetValue([[#Image Color |TColor]] color, Image<Gray, Byte>  mask)</code> function in Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]> class (version >= [[Version_History#Emgu.CV-1.2.2.0|1.2.2.0]]) will only accept colors of the same type, and mask has to be an 8-bit unsigned grayscale image. Any attempts to use a 16-bit floating point or non-grayscale image as a mask will results a compile time error!


===Creating Image===
[[Image]]
Although it is possible to create image by calling <code>CvInvoke.cvCreateImage</code>, it is suggested to construct a Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]> object instead. There are several advantages using the managed Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]> class
* Memory is automatically released when the garbage collector dispose the Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]> Object
* Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]> class contains advanced method that is not available on [[OpenCV]], for example, [[Tutorial#Generic_Operation | generic operation on image pixels]], conversion to Bitmap etc.
 
====Image Color====
The first generic parameter of the Image class specific the color of the image type. For example
 
<code>Image<Gray, ...> img1; </code>
 
indicates that <code>img1</code> is a single channel grayscale image.
Color Types supported in [[Version_History#Emgu.CV-1.3.0.0|Emgu CV 1.3.0.0]] includes:
* Gray
* Bgr (Blue Green Red)
* Bgra (Blue Green Red Alpha)
* Hsv (Hue Saturation Value)
* Hls (Hue Lightness Saturation)
* Lab (CIE L*a*b*)
* Luv (CIE L*u*v*)
* Xyz (CIE XYZ.Rec 709 with D65 white point)
* Ycc (YCrCb JPEG)
 
====Image Depth====
Image Depth is specified using the second generic parameter <code>Depth</code>.
The types of depth supported in [[Version_History#Emgu.CV-1.4.0.0|Emgu CV 1.4.0.0]] include
* Byte
* SByte
* Single (float)
* Double
* UInt16
* Int16
* Int32 (int)
 
====Creating a new image====
To create an 480x320 image of Bgr color and 8-bit unsigned depth. The code in C# would be
<source lang="csharp">
Image<Bgr, Byte> img1 = new Image<Bgr, Byte>(480, 320);
</source>
If you wants to specify the background value of the image, let's say in Blue. The code in C# would be
<source lang="csharp">
Image<Bgr, Byte> img1 = new Image<Bgr, Byte>(480, 320, new Bgr(255, 0, 0));
</source>
====Reading image from file====
Creating image from file is also simple. If the image file is "MyImage.jpg", in C# it is
<source lang="csharp">
Image<Bgr, Byte> img1 = new Image<Bgr, Byte>("MyImage.jpg");
</source>
 
====Creating image from Bitmap====
It is also possible to create an Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]> from a .Net Bitmap object. The code in C# would be
<source lang="csharp">
Image<Bgr, Byte> img = new Image<Bgr, Byte>(bmp); //where bmp is a Bitmap
</source>
 
===Automatic Garbage Collection===
The Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]> class automatically take care of the memory management and garbage collection.
 
Once the garbage collector decided that there is no more reference to the Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]> object, it will call the <code>Disposed</code> method, which release the unmanaged IplImage structure.
 
The time of when garbage collector decides to dispose the image is not guaranteed. When working with large image, it is recommend to call the <code>Dispose()</code> method to explicitly release the object. Alternatively, use the '''''using''''' keyword in C# to limit the scope of the image
 
<source lang="csharp">
using (Image<Gray, Single> image = new Image<Gray, Single>(1000, 800))
{
  ... //do something here in the image
} //The image will be disposed here and memory freed
</source>
 
===Getting or Setting Pixels===
* Suppose you are working on an Image<Bgr, Byte>. You can obtain the pixel on the y-th row and x-th column by calling
<source lang="csharp">
Bgr color = img[y, x];
</source>
* Setting the pixel on the y-th row and x-th column is also simple
<source lang="csharp">
img[y,x] = color;
</source>
 
===Methods===
====Naming Convention====
* Method <code>XYZ</code> in Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]> class corresponds to the [[OpenCV]] function <code>cvXYZ</code>. For example, Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]>.Not() function corresponds to <code> cvNot </code> function with the resulting image being returned.
* Method <code>_XYZ</code> is usually the same as Method <code>XYZ</code> except that the operation is performed '''inplace''' rather than returning a value. For example, Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]>._Not() function performs the bit-wise inversion inplace.
 
===Operators Overload===
The operators <code>+ - * /</code> has been overloaded (version > [[Version_History#Emgu.CV-1.2.2.0|1.2.2.0]]) such that it is perfectly legal to write codes like:
 
Image<Gray, Byte> image3 = (image1 + image2 - 2.0) * 0.5;
 
===Generic Operation===
One of the advantage of using [[Emgu CV]] is the ability to perform generic operations.
 
It's best if I demonstrate this with an example. Suppose we have an grayscale image of bytes
<source lang="csharp">
Image<Gray, Byte> img1 = new Image<Gray, Byte>(400, 300, new Gray(30));
</source>
To invert all the pixels in this image we can call the Not function
<source lang="csharp">
Image<Gray, Byte> img2 = img1.Not();
</source>
As an alternative, we can also use the generic method <code> Convert </code> available from the Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]> class
<source lang="csharp">
Image<Gray, Byte> img3 = img1.Convert<Byte>( delegate(Byte b) { return (Byte) (255-b); } );
</source>
The resulting image <code>img2</code> and <code>img3</code> contains the same value for each pixel.
 
At first glance it wouldn't seems to be a big gain when using generic operations. In fact, since [[OpenCV]] already has an implementation of the <code>Not</code> function and performance-wise it is better than the generic version of the equivalent <code>Convert</code> function call. However, there comes to cases when generic functions provide the flexibility with only minor performance penalty. 
 
Let's say you have an <code>Image<Gray, Byte> img1</code> with pixels set. You wants to create a single channel floating point image of the same size, where each pixel of the new image, correspond to the old image, described with the following delegate
<source lang="csharp">
delegate(Byte b) { return (Single) Math.cos( b * b / 255.0); }
</source>
This operation can be completed as follows in [[Emgu CV]]
<source lang="csharp">
Image<Gray, Single> img4 = img1.Convert<Single>( delegate(Byte b) { return (Single) Math.cos( b * b / 255.0); }  );
</source>
The syntax is simple and meaningful. On the other hand, this operation in [[OpenCV]] is hard to perform since equivalent function such as <code>Math.cos</code> is not available.
 
===Drawing Objects on Image===
The <code> Draw( )</code> method in Image< [[#Image Color |Color]], [[#Image Depth |Depth]]> can be used to draw different types of objects, including fonts, lines, circles, rectangles, boxes, ellipses as well as contours. Use the documentation and intellisense as a guideline to discover the many functionality of the <code> Draw </code> function.
 
===Color and Depth Conversion===
Converting an Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]> between different colors and depths are simple. For example, if you have <code> Image<Bgr, Byte> img1 </code> and you wants to convert it to a grayscale image of Single, all you need to do is
<source lang="csharp">
Image<Gray, Single> img2 = img1.Convert<Gray, Single>();
</source>
 
=== Displaying Image ===
====Using ImageBox====
[[Emgu CV]] recommand the use of [[ImageBox]] control for display purpose. The reasons are
* [[ImageBox]] is a high performance control for displaying image. Whenever possible, it display a Bitmap that shared memory with the Image object, therefore no memory copy is need (very fast).
* The user will be able to exam the image pixel values, video frame rates, color types when the image is being displayed.
* It is convenience to perform simple image operation with just a few mouse click.
To find out more about [[ImageBox]], go to [[ImageBox|this page]]
 
====Converting to Bitmap====
The Image class has a <code>ToBitmap()</code> function that return a Bitmap object, which can easily be displayed on a PictureBox control using Windows Form.
 
===Image XML Serialization===
====Why do I care about Xml Serialization?====
One of the future of Emgu CV is that Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]> can be XML serializated. You might ask why we need to serialization an Image. The answer is simple, we wants to use it in a web service!
 
Since the Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]> class implements ISerializable, when you work in WCF (Windows Communication Fundation), you are free to use Image<[[#Image Color |TColor]], [[#Image Depth |TDepth]]> type as parameters or return value of a web service.
 
This will be ideal, for example, if you are building a cluster of computers to recognize different groups of object and have a central computer to coordinate the tasks. I will also be useful if your wants to implement remote monitoring software that constantly query image from a remote server, which use the <code>Capture</code> class in [[Emgu CV]] to capture images from camera.
 
====Converting image to XML====
You can use the following code to convert an <code>Image<Bgr, Byte> image</code> to <code>XmlDocument</code>:
<source lang="csharp">
StringBuilder sb = new StringBuilder();
(new XmlSerializer(typeof(Image<Bgr, Byte>))).Serialize(new StringWriter(sb), o);
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(sb.ToString());
</source>
 
====Converting XML to image====
You can use the following code to convert a <code>XmlDocument xDoc</code> to <code>Image<Bgr,Byte></code>
<source lang="csharp">
Image<Bgr, Byte> image = (Image<Bgr, Byte>)
(new XmlSerializer(typeof(Image<Bgr, Byte>))).Deserialize(new XmlNodeReader(xDoc));
</source>


==Working with Matrix==
==Working with Matrix==

Revision as of 20:19, 22 May 2009

Namespace

Emgu

All libraries implemented by Emgu® belongs to the namespace of Emgu.

Emgu.CV

The Emgu.CV namespace implement wrapper functions for OpenCV. To use this namespace in your code, it is recommended to include

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

in the beginning of your C# code.

Function Mapping - Emgu.CV.CvInvoke

The CvInvoke class provides a way to directly invoke OpenCV function within .NET languages. Each method in this class corresponds to a function in OpenCV of the same name. For example, a call to

 
 IntPtr image = CvInvoke.cvCreateImage(new System.Drawing.Size(400, 300), CvEnum.IPL_DEPTH.IPL_DEPTH_8U, 1);

is equivalent to the following function call in C

 
 IplImage* image = cvCreateImage(cvSize(400, 300), IPL_DEPTH_8U, 1);

Both of which create a 400x300 of 8-bit unsigned grayscale image.

Enumeration Mapping - Emgu.CV.CvEnum

The CvEnum namespace provides direct mapping to OpenCV enumerations. For example, CvEnum.IPL_DEPTH.IPL_DEPTH_8U has the same value as IPL_DEPTH_8U in OpenCV; both of which equals 8.

Structure Mapping - Emgu.CV.Structure.Mxxx

This type of structure is a direct mapping to OpenCV structures.

Emgu CV Structure OpenCV structure
Emgu.CV.Structure.MIplImage IplImage
Emgu.CV.Structure.MCvMat CvMat
... ...
Emgu.CV.Structure.Mxxxx xxxx

The prefix M here stands for Managed structure.

Emgu CV also borrows some existing structures in .Net to represent structures in OpenCV:

.Net Structure OpenCV structure
System.Drawing.Point CvPoint
System.Drawing.PointF CvPoint2D32f
System.Drawing.Size CvSize
System.Drawing.Rectangle CvRect

Objects in Emgu CV (Image, Matrix ...)

Image

Working with Matrix

Depth as Generic Parameter

A Matrix is defined by its generic parameters depth. To create a 32bit floating point matrix, in Emgu CV it is done by calling

Matrix<Single> matrix = new Matrix<Single>(width, height);

Matrix Depth

The types of depth supported in Emgu CV 1.4.0.0 include

  • Byte
  • SByte
  • Single (float)
  • Double
  • UInt16
  • Int16
  • Int32 (int)

Error Handling

Pop up box is out. Exception is the way to go!

In Emgu CV we register our custom error handler in OpenCV. When error is encountered a CvException will be thrown, from where you can find the detail information. It is up to you to decide what to do next.

Code Documentation

Xml Documentation

Documentation is embedded in the code using xml format, which can then be compiled as HTML documentation using Sandcastle. You can browse our Online Documentation for the latest stable and development code.

Intellisense in Visual Studio

If you are using Visual Studio as your development tools, you will have intellisense support when developing Emgu CV applications. For example, if you wants to create an image directly using cvCreateImage function, which is wrapped by the CvInvoke Class, just type CvInvoke.

and a list of functions belongs to CvInvoke class is displayed along with a description for each of the function. Since you are creating an image, select the cvCreateImage function

The list of parameters for this function will be displayed as well as a description for each of the parameters.

Examples

C#

Image Processing Examples

Machine Learning Examples

C++

IronPython

VB.NET