You are on page 1of 23

1

Suriya Phiokham 2013 06, 20 Reference : http://www.emgu.com/wiki/index.php/

Working with Images
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 Image<Gray, Byte> image = new Image<Gray, Byte>( width, height); 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 SetValue(TColor color, Image<Gray, Byte> mask) function in Image<TColor, TDepth> class (version >= 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
Although it is possible to create image by calling CvInvoke.cvCreateImage, it is suggested to construct a Image<TColor, TDepth> object instead. There are several advantages using the managed Image<TColor, TDepth> class    Memory is automatically released by the garbage collector Image<TColor, TDepth> class can be examined by Debugger Visualizer Image<TColor, TDepth> class contains advanced method that is not available on OpenCV, for example, 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 Image<Gray, ...> img1; indicates that img1 is a single channel grayscale image. Color Types supported in 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 Depth. The types of depth supported in Emgu CV 1.4.0.0 include   Byte SByte

2
     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 Image<Bgr, Byte> img1 = new Image<Bgr, Byte>(480, 320); If you wants to specify the background value of the image, let's say in Blue. The code in C# would be Image<Bgr, Byte> img1 = new Image<Bgr, Byte>(480, 320, new Bgr(255, 0, 0));

Reading image from file
Creating image from file is also simple. If the image file is "MyImage.jpg", in C# it is Image<Bgr, Byte> img1 = new Image<Bgr, Byte>("MyImage.jpg");

Creating image from Bitmap
It is also possible to create an Image<TColor, TDepth> from a .Net Bitmap object. The code in C# would be Image<Bgr, Byte> img = new Image<Bgr, Byte>(bmp); //where bmp is a Bitmap

Automatic Garbage Collection
The Image<TColor, 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<TColor, TDepth> object, it will call the Disposed 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 Dispose() method to explicitly release the object. Alternatively, use the using keyword in C# to limit the scope of the image 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

Getting or Setting Pixels
The safe (slow) way
 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

Bgr color = img[y, x];  Setting the pixel on the y-th row and x-th column is also simple img[y,x] = color;

The fast way
The Image pixels values are stored in the Data property, a 3D array. Use this property if you need to iterate through the pixel values of the image. For example, in an grayscale image (Image<Gray, Byte>), instead of doing this: Gray byCurrent = imageGray[x, y];

rectangles. ellipses as well as contours.Not().3 You would do this: Byte byCurrent = imageGray. For example. Single> img4 = img1. this operation in OpenCV is hard to perform since equivalent function such as Math. } ). The resulting image img2 and img3 contains the same value for each pixel._Not() function performs the bit-wise inversion inplace.cos is not available. To invert all the pixels in this image we can call the Not function Image<Gray.0). You wants to create a single channel floating point image of the same size.cos( b * b / 255. Image<TColor. At first glance it wouldn't seems to be a big gain when using generic operations. Let's say you have an Image<Gray.Not() function corresponds to cvNot function with the resulting image being returned. TDepth> class Image<Gray. However. It's best if I demonstrate this with an example. Byte> img1 = new Image<Gray. 0]. there comes to cases when generic functions provide the flexibility with only minor performance penalty. } This operation can be completed as follows in Emgu CV Image<Gray.  Operators Overload The operators + .2.cos( b * b / 255. In fact.Convert<Byte>( delegate(Byte b) { return (Byte) (255b).0). TDepth>.5.2. since OpenCV already has an implementation of the Not function and performance-wise it is better than the generic version of the equivalent Convert function call.* / has been overloaded (version > 1. including fonts. correspond to the old image.Data[x. Depth> can be used to draw different types of objects.0) such that it is perfectly legal to write codes like: Image<Gray. y. Generic Operation One of the advantage of using Emgu CV is the ability to perform generic operations. Drawing Objects on Image The Draw( ) method in Image< Color. TDepth>. Byte> img3 = img1. Use the documentation and intellisense as a guideline to discover the many functionality of the Draw function. TDepth> class corresponds to the OpenCV function cvXYZ. described with the following delegate delegate(Byte b) { return (Single) Math. Image<TColor.Convert<Single>( delegate(Byte b) { return (Single) Math.0) * 0. } ). 300. The syntax is simple and meaningful. Byte> img1 with pixels set. On the other hand. Method _XYZ is usually the same as Method XYZ except that the operation is performed inplace rather than returning a value.2. Byte> img2 = img1. Methods Naming Convention  Method XYZ in Image<TColor. Byte>(400. For example. we can also use the generic method Convert available from the Image<TColor. Color and Depth Conversion . boxes. As an alternative. Byte> image3 = (image1 + image2 . Suppose we have an grayscale image of bytes Image<Gray. circles. where each pixel of the new image. new Gray(30)). lines.

XmlDocument xDoc = new XmlDocument(). TDepth> between different colors and depths are simple. Conversion from XML You can use the following code to convert a XmlDocument xDoc to Image<Bgr. TDepth> class implements ISerializable. (new XmlSerializer(typeof(Image<Bgr. Converting to Bitmap The Image class has a ToBitmap() function that return a Bitmap object.LoadXml(sb.ToString()).Byte> Image<Bgr. all you need to do is Image<Gray. Conversion to XML You can use the following code to convert an Image<Bgr. XML Serialization Why do I care? One of the future of Emgu CV is that Image<TColor. if you are building a cluster of computers to recognize different groups of object and have a central computer to coordinate the tasks. if you have Image<Bgr. Working with Matrices Depth as Generic Parameter A Matrix is defined by its generic parameters depth. color types when the image is being displayed.Deserialize(new XmlNodeReader(xDoc)). when you work in WCF (Windows Communication Fundation). Whenever possible. therefore no memory copy is needed (very fast). The answer is simple. o). Single>(). TDepth> can be XML serializated. Single> img2 = img1. Byte>))). I will also be useful if your wants to implement remote monitoring software that constantly query image from a remote server. Byte>))). it displays a Bitmap that shares memory with the Image object. for example. To create a 32bit floating point matrix. Byte> image = (Image<Bgr. you are free to use Image<TColor. The user will be able to examine the image pixel values. for the following reasons    ImageBox is a high performance control for displaying image. which can easily be displayed on a PictureBox control using Windows Form. video frame rates. For example. Byte> image to XmlDocument: StringBuilder sb = new StringBuilder(). Displaying Image Using ImageBox Emgu CV recommends the use of ImageBox control for display purpose.Convert<Gray. Byte> img1 and you wants to convert it to a grayscale image of Single.4 Converting an Image<TColor. This will be ideal. in Emgu CV it is done by calling . we wants to use it in a web service! Since the Image<TColor. You might ask why we need to serialization an Image. Byte>) (new XmlSerializer(typeof(Image<Bgr. It is convenient to perform simple image operations with just a few mouse clicks. which use the Capture class in Emgu CV to capture images from camera.Serialize(new StringWriter(sb). xDoc. TDepth> type as parameters or return value of a web service.

Matrix Depth The types of depth supported in Emgu CV 1.CV. new Bgr(0. . world". 1. .5 Matrix<Single> matrix = new Matrix<Single>(width. 0)). 255. o). using Emgu. written in C# using Emgu.ToString()). C# Image Processing Examples Hello World .cvNamedWindow(win1). height).0 include        Byte SByte Single (float) Double UInt16 Int16 Int32 (int) XML Serialization Conversion to XML You can use the following code to convert an Matrix<double> matrix to XmlDocument: StringBuilder sb = new StringBuilder().0). (new XmlSerializer(typeof(Matrix<double>))). 1. byte>(400.Drawing. using System.CV." on the image using the specific font img.Structure. 0. //The name of the window String win1 = "Test Window". using Emgu. new Bgr(255. //Create the window using the specific name CvInvoke..CV_FONT_HERSHEY_COMPLEX. ref f.Version 1 We will start by the Hello World sample.CV. Conversion from XML You can use the following code to convert a XmlDocument xDoc to Matrix<double> Matrix<double> matrix = (Matrix<double>) (new XmlSerializer(typeof(Matrix<double>))). //Draw "Hello.LoadXml(sb. 0))) { //Create the font MCvFont f = new MCvFont(CvEnum.Draw("Hello. Byte> img = new Image<Bgr.0.Deserialize(new XmlNodeReader(xDoc)). //Create an image of 400x200 of Blue color using (Image<Bgr. XmlDocument xDoc = new XmlDocument().CvEnum. 80).4.FONT. world. new Point(10..Serialize(new StringWriter(sb). 200.0. xDoc.

} . //Draw "Hello. new Bgr(255.cvShowImage(win1. 1. ref f. using Emgu." on the image using the specific font img.Drawing.FONT. img.. //Create an image of 400x200 of Blue color using (Image<Bgr.CV.CV. Hello World . 255. 0. 200.Structure. world" in green on the foreground.UI namespace. but Emgu CV has an event better tool for the same purpose. } The above code will create an image of 400x200 with blue background color and the text "Hello. the ImageViewer class under Emgu. using Emgu. using Emgu.0). using Emgu.Draw("Hello.cvWaitKey(0). world. 80). .Ptr).Show(img. 0)).CV. world". using System.Version 2 Showing image using cvNamedWindow is good.CV_FONT_HERSHEY_COMPLEX.6 //Show the image CvInvoke.cvDestroyWindow(win1). new Point(10. The image will be displayed a window named "Test Window".UI.CvEnum. 1.UI ImageViewer. //Destory the window CvInvoke. "Test Window"). Byte> img = new Image<Bgr. //Wait for the key pressing event CvInvoke. that is.CV. //Show the image using ImageViewer from Emgu.CV. new Bgr(0..0. byte>(400.CV. 0))) { //Create the font MCvFont f = new MCvFont(CvEnum.

CV. There are the EMGU ones with EMGU syntax always reference in the name and the opencv ones that vary. 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. As EMGU is a wrapper for c++ code there are two types of Dynamic-link library’s (DLL’s) that are used. EMGU opens the OpenCV (Open Source Computer Vision Library) library of programming functions mainly aimed at real time computer vision to C# developers. Assumed Knowledge It is assumed that a user has basic experience in c# and can generate a new c# project. EMGU is a c# wrapper for OpenCV it differs from other wrappers as it written purely in c# and does not use unsafe code. If you have downloaded the source code you will need to read “ A Basic Program”. Start a new c# Windows Form Application and call it what you like.dll This is done by either right clicking on your project name or the References folder within the solution explorer.CV.dll  Emgu.dll  Emgu.UI. Setting up a first project is a common stumbling block for many newcomers and you are not alone. Or alternatively using the menu item Project > Add Reference.Examples\Hello World. Current versions for both x86 and x64 architectures are available to download at their Sourceforge website.7 Introduction The following article is designed to show new comers to EMGUcv how to set up a project step by step.Util. OpenCV was originally developed by Intel and now supported by Willow Garage. When the Add Reference window opens select the DLL’s listed above and click OK.CV.  Emgu. The Basic Requirements As with any c# library there are some essential DLL’s that need referencing within your project.Invoke Exception and Troubleshooting section. . All DLL mentioned are in the EMGU extraction Folder\bin you will need to remember this. This article is designed to make the process a little more user friendly. To start with you need to reference 3 EMGU DLL’s. Go to Add Reference. If you have copied an example from the EMGU extraction folder then take a look at The EMGU.

The references you will use will depend on what you are doing in image processing terms. To get you started add the following to the top of the Form1. using Emgu.dll). You will need to change there properties so select them both by holding down the Ctl key and left clicking on them (alternatively you can do this individually). using Emgu.8 You will now see them listed in the References folder in the solution explorer window. Right click on your project name within solution explorer (This is not the one starting with “Solution ‘Your Project Name’ . Hint: if you can’t see . in case you forgot they are located in the EMGU extraction Folder\bin. You will now be able to see your files within the solution explorer window. Now you need to reference these in any class of form that you will be using the code. The Preferred Method Now for the more complicated c++ libraries.. Now look at Properties window. display. This can be done in two ways. you will see 6 fields two of these will be filled with content.CV. You need to add these files to your project.Structure.dll. These alone will not allow you to use any of the image processing functions so please read the rest of the article.Util. These three DLL’s are the EMGU specific c# libraries mentioned previously. opencv_imgproc***.” but the one bellow this).dll Now because these are wrapped c++ files you can’t reference them like you did with the EMGU files. Note that the "220" is the version number this will change according to updates (opencv_core***.dll  opencv_imgproc220.dll's make sure you change the file filter at the bottom right to Executable Files. Go to Add > Existing Item using the standard open file dialog. to load.. Select the two files above. Look at the examples and these will have the ones your require. using Emgu. You are interested in the Copy to Output Directory.cs code behind.  opencv_core220. Change this from “Do not Copy” to “Copy always”. access image data and do many of the more simpler functions you only need two files.CV. .

Right click on your project file in the solution explorer and select “Properties” at the bottom. There will be an option for Platform Target: with a drop down menu change this from x86 to x64. Simply navigate in windows explorer to the EMGU extraction folder\bin copy the relevant dll files opencv_core220. 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. This will change with x64 versions as it will be the bin\x64\Debug folder or alternative Release folder. it is rare this will be the case. Select the “Build” tab from the ribbon bar on the right of this window. The steps on forming a project are identical however you will need to change an additional build parameter. . The reason this is the preferred method is that now.CV. imagine if you require all the opencv DLL files then you will have an extra 34 files within the solution explorer however.dll to your project bin\Debug folder or to bin\Release folder. if you change from Debug to Release these files will always be available to your program and no errors will occur. While the benefits are not so clear here.9 If you are using the x64 compilations go to the x64 section and ensure you set up you project to compile to a x64 architecture other than that you are ready to start image processing. Jump to the reading and displaying an image section A Basic Program to start you off.Invoke Exception If you are running an x64 system or designing for them you will have to download separate DLL’s. x64 Architecture and the EMGU.dll and opencv_imgproc220.

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. This will now allow the compilation to run if this is not done correctly. In this window using the arrows to the left hand side to expand and collapse options.ShowDialog() == DialogResult.10 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. Only x64 Versions are currently available.CV..Invoke’ through an exception with the ‘InnerException’ "An attempt was made to load a program with an incorrect format. pictureBox1. Expand the References folder within the solution explorer delete the 3 with yellow warning icons and Add fresh references to them.FileName). } . There has been a button item and a picturebox item added to the main form. the steps of which are available The Basic Requirements section. byte>(Openfile.. Byte> My_Image = new Image<Bgr. EventArgs e) { OpenFileDialog Openfile = new OpenFileDialog(). x86 will be provided shortly. As soon as you access any EMGU code an exception will be thrown ‘EMGU.ToBitmap()..”. if (Openfile.OK) { Image<Bgr. Select “Projects and Solutions” and select the Show advanced build configurations check box. Double click on the button and add the following code: private void button1_Click(object sender. If you have downloaded the sample code you will start with 3 warnings for the references not being found. When we click on the button we wish to open a file dialog select and image and have it displayed in the picturebox. There default names have not been changed.Image = My_Image.

Please visit http://www.UI library and is used in the examples. However you will eventually want to use a different depth (Tdepth) of image rather than Byte.0] a value. //alternatively Image<Gray.y. This is incredibly simple to achieve once the correct process has been taken in setting up the project.emgu. A little on Converting Images Image conversion in EMGU can be complex. The references will need replacing. Image<Gray. 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.double> gray_image = My_Image.y. Lets say we wish to assign a value to a pixel at position [0.11 } The code is very simple an OpenFileDialog called 'Openfile' is used to select and image file.> gray_image = My_Image.y. Lets say we wish to convert from Image<bgr.Convert<Bgr.double> you would have to use the following syntax.y.double>().1] & [x. direct access using the Image Data property of a more remote access. In this program there is a demonstration of converting an Image from colour to greyscale and accessing the Data of individual pixels.com/wiki/index. An alternative to the Picturbox item is made available through the EMGU. Using the easier remote method we can use: //Colour Image My_Image[0.Red). Image<gray.Convert<Gray. The problem with this method is you can only convert a depth or colour once per call. This requires a Bitmap and by calling the .double>().CV.0]. Or we use the Data property //Colour Image . Accesing Image Data There are a few ways of accessing image data and assigning values to it. //or alternatively in one line Image<Gray. 0] = new Bgr(Color. [x.byte> to Image<gray.Convert<gray. Green & Red spectrums respectively (Bgr).double>().byte>().Convert<Gray.php/Add_ImageBox_Control to learn how to add this control to visual studio should you wish to use it. While the methods of suppressing the image spectrum data is not the most efficient it is a good example on accessing the image Data property. In the example program a Bgr colour image is converted the Gray or grayscale. Image<Gray. Note it is important to respect the image spectrum depth when accessing the Data property. There are two methods available.Convert<Gray. A grayscale image will have a depth of one so will be reference as [x.ToBitmap() function of 'My_Image' this is achieved.2] representing the Blue. //Gray Image gray_image[0. The image is displayed by assigning the Image property of the picturebox. 0] = new Gray(200).Convert<Gray. [x.Convert<Gray.byte> gray_image = My_Image. This image is then read into an colour Image object called 'My_Image'.0] however a colour image as a depth of 3.Byte> gray_image = My_Image.double>().byte>().byte> gray_image = My_Image. Both are demonstrated here.byte>().

1].Intensity. You can access the image Data directly and use that.Data[0.0. Much simpler and far easier to work with when processing the image Data within a loop.Blue. Now in many cases you will not want to work with “Bgr” or “Gray” so converting them is important.. //Gray Image Gray my_Gray = gray_image[0.2] = R. //Write to the Blue Spectrum //Gray Image gray_image[0. My_Image. However in this case the easier method is accessing the Image Data property. You need to read the Message section circled in red bellow. 0].Green). 2]). //Write to the Red Spectrum My_Image.Red. 0. //Colour Image Bgr my_Bgr = My_Image[0.G..Data[0. 0]. 0. //Gray Image int my_intensity = gray_image. //BGR to Color Color my_colour = Color. . (Exception from HRESULT: 0x8007007E)”.Data[0.Data[0.. To examine how to implement a loop please download the Little More Image Processing source code. 0].Data[0.0..12 Color R = Color. (int)value. //Write to the Green Spectrum My_Image. 0.Red. //Gray to int int my_intensity = (int) my_Gray.FromArgb((int)value.R.. (int)value. My_Image. 0] = new Gray(200). So writing to a pixel is fairly simple but what about reading a pixel value.0] = R. The DllNotFound Exception and Troubleshooting 0x8007007E Now at some point you are going to receive and error "Unable to load DLL.B. 0].0. If you wish to work with the image data there is not a requirement to constantly convert between Gray and integers etc. //Colour Color my_colour = Color. 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.Data[0. 0.1] = R.FromArgb(My_Image.Data[0. My_Image.

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”.dll opencv_objdetect220. As discussed in The Basic Requirements section you will need to either copy theopencv_highgui220. Look back at this section for reference if required.’ errors can be fixed by attempting the same process an loading the relevant listed DLLs into your project. . Look back at this section for reference if required.dll error can not be fixed by simply adding the this one file in fact this file requires all of the files listed bellow to correctly execute. Unable to load DLL 'opencv_highgui220': The specified module could not be found.13 If the exception is a EMGU. See the section regarding x64 Architecture for details.dll opencv_calib3d220. The solution to this is extremely simple. 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.dll opencv_core220.dll cvextern.dll opencv_gpu220.dll opencv_legacy220. chances are you are not targeting the correct platform for your build.dll cufft64_32_16. Note that the "220" is the version number this will change according to updates..                 cudart64_32_16. The cvextern.dll opencv_contrib220.dll opencv_imgproc220. (Exception from HRESULT: 0x8007007E) This error has a little more of a substantial solution.dll opencv_flann220.dll opencv_features2d220..dll Any other Unable to load DLL ‘.dll opencv_ml220.dll opencv_video220. Unable to load DLL 'cvextern': The specified module could not be found.CV.dll opencv_highgui220.Invoke Exception. 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”. If you still get stuck than feel free to ask the community for help. (Exception from HRESULT: 0x8007007E) Usually caused when you are trying to get a image from a web camera.dll npp64_32_16.

Resize(400.Windows.CV.CV. using Emgu. I hope this article sets you on the right path.System.Structure.Structure.Bgr*.Convert<Gray. Rectangle. . we demonstrate how to perform Hough Line and Circle detection using Emgu CV. adding them to the project and set there properties to copy always as they are the two key files. pic3. Circle. true). viewer..14 System.Byte*> is not supported by OpenCV Where * is the the relavent image depth or data type.Text). //show the image viewer Shape (Triangle. Line) Detection in CSharp This project is part of the Emgu.0 Excluding the using statements in the beginning.TypeInitializationException: Convertion from Image<Emgu. Byte> gray = img.dll even though they are present in the output "bin" directory. //create an image viewer Capture capture = new Capture().5.Structure.Bgr*. This error is thrown up in version 2.Image = capture. using System.* onwards and is caused by the programs inability to access opencv_imgproc***.Structure. There are two solutions.CV. ImageViewer viewer = new ImageViewer(). only 7 lines of code are required to perform a camera capture loop. .System.ShowDialog(). //create a camera captue Application. using System. //draw the image obtained from camera }). EventArgs e) { //run this until application closed (close button click on image viewer) viewer. as well as using the Contour class to detect Triangles and Rectangles in the image. Byte> img = new Image<Bgr.CV. The "pic3. Byte>(). using Emgu.png from opencv Source Code //Load the image from file Image<Bgr..CV. Camera Capture in 7 lines of code This example requires Emgu CV 1. //Convert the image to grayscale and filter out the noise Image<Gray.PyrDown().PyrUp().dll or opencv_core***.Example solution Shape Detection In this tutorial. Thanks for reading.Drawing.Byte*> to Image<Emgu.Idle += new EventHandler(delegate(object sender. 400.png" file from the OpenCV sample folder is used here.3. using Emgu.CV.0. If both methods fail then there may be a problem with the build so download a new copy from SourceForge and try again.UI. byte>(fileNameTextBox. Or by replacing the current ones in the Bin folder with new copies can also solve the problem.QueryFrame().Forms.

if (contours. LineSegment2D[] lines = cannyEdges. circleAccumulatorThreshold.0. i++) { double angle = Math.Canny(cannyThreshold. for (int i = 0. contours = contours. //min Line width 10 //gap between lines )[0].Total == 4) //The contour has 4 vertices. //Resolution of the accumulator used to detect centers of the circles 10.Length.ToArray(). Gray cannyThresholdLinking = new Gray(120). 100] degree bool isRectangle = true. storage). CircleF[] circles = gray.HNext) { Contour<Point> currentContour = contours. } else if (currentContour. i < edges. List<MCvBox2D> boxList = new List<MCvBox2D>().05.Perimeter * 0.0.HoughCircles( cannyThreshold. if (angle < 80 || angle > 100) { . Point[] pts = currentContour. Byte> cannyEdges = gray.FindContours().Area > 250) //only consider contours with area greater than 250 { if (currentContour. //Get the lines from the first channel #region Find triangles and rectangles List<Triangle2DF> triangleList = new List<Triangle2DF>(). pts[1].PolyLine(pts. it is a triangle { Point[] pts = currentContour. cannyThresholdLinking). using (MemStorage storage = new MemStorage()) //allocate storage for contour approximation for (Contour<Point> contours = cannyEdges. LineSegment2D[] edges = PointCollection. 20.15 Gray cannyThreshold = new Gray(180). //Get the circles from the first channel Image<Gray. //threshold 30. contours != null.Length]. true). Gray circleAccumulatorThreshold = new Gray(120). //Angle resolution measured in radians. //Distance resolution in pixel-related units Math.Abs( edges[(i + 1) % edges. //min radius 0 //max radius )[0].0. triangleList.HoughLinesBinary( 1. //min distance 5.PI / 45.GetExteriorAngleDegree(edges[i])).Add(new Triangle2DF( pts[0].ApproxPoly(contours. { #region determine if all the angles in the contour are within the range of [80.ToArray().Total == 3) //The contour has 3 vertices. pts[2] )). 5.

Image = circleImage.Green).CopyBlank().DarkBlue).Add(currentContour. 2).Image = lineImage.CopyBlank(). lineImageBox. new Bgr(Color. foreach (CircleF circle in circles) circleImage. 2). foreach (MCvBox2D box in boxList) triangleRectangleImage.Draw(box. foreach (Triangle2DF triangle in triangleList) triangleRectangleImage.Image = triangleRectangleImage. circleImageBox. Byte> circleImage = img. #endregion Result Creating First Emgu CV Project Introduction . #endregion #region draw circles Image<Bgr.Image = img. 2). triangleRectangleImageBox. foreach (LineSegment2D line in lines) lineImage. break. } } } #endregion originalImageBox.Draw(line. } } #endregion if (isRectangle) boxList.CopyBlank(). 2). new Bgr(Color. new Bgr(Color.DarkOrange). #endregion #region draw lines Image<Bgr. new Bgr(Color. Byte> triangleRectangleImage = img.GetMinAreaRect()).16 isRectangle = false. Byte> lineImage = img.Brown). #region draw triangles and rectangles Image<Bgr.Draw(triangle.Draw(circle.

in my case it is Emgu.VS2010.CV" (choose only one among Emgu.VS2010. in the bin folder there must be some dlls add all those starting with "Emgu.1416\bin ). Browse for the Emgu bin folder (by default it is located at C:\Emgu\emgucv-windows-x86 2.3. Now let's start.0.CV. Emgu CV is not so difficult.dll depending on the Visual Studio you are using.VS2008. snap to grid and many others. now here we will start our first Emgu CV project.dll) .CV. all we have to do is to add certain references and make use of Emgu Controls.DebuggerVisualizers. Let's get started.DebuggerVisualizers. The first thing we will do is to Add References.dll and Emgu. You will get a new project created for you.17 In the last article we read about Starting with Emgu CV. before starting further enable "show all settings" under tools. this enables many features like form designer layout.DebuggerVisualizers.CV. Let's start creating a blank Windows Forms application.

18 Now we need to add some existing items. we will be using two ImageBox (Emgu Control). . now let's design our form. We already have added the Emgu custom controls to our toolbox. that is why we added them to our project directory. one Button and a Textbox. select all the DLLs added and select properties and change the "Copy to Output Directory" to "Copy Always". So. Go to "Project" > "Add Existing Items" and now again browse for the bin directory of Emgu CV and this time choose all the dll files starting with "opencv_". we will also change there the property so that they get copied always to the output folder. design the form as below. these dll files are required each time the output is generated via Emgu.

Byte> imgOrg. This will associate the default webcam with the capturecam object.CV. //instance for capture using webcam bool CapturingProcess = false. //boolean stating the capturing process status Image<Bgr. //processed image will be grayscale so a gray image Now it's time to add a "form load event".Structure. capturecam = new Capture(). using Emgu.UI. we will start capturing via webcam under it. Byte> imgProc.CvEnum. using Emgu. //image type RGB (or Bgr as we say in Open CV) Image<Gray. Next create some member variables : Capture capturecam = null.CV.CV.19 Coding Now go to the form1. using Emgu.CV. .cs code view. and add the following namespaces: using Emgu.

"ProcessFunction" is called at every idle state of the application. the minimum and maximum values of the Bgr range. "SmoothGaussian" applies the Gaussian smoothing with the x. if it is null it means there is some problem and hence we stop our app there.y length = 9. and the task is to get the next frame.Idle". we can pass other parameters for x and y also. "QueryFrame" gets the next frame from the webcam. Now let's come to the coding part of the "playorpause" button: .20 We have added the association to the capture object in the try/catch block to avoid the error if the webcam is already in use. The "InRange" function takes two parameters. We added an event handler to "Application. so that it performs the task when the application is idle.

In most cases an ANN is an adaptive system that changes its structure based on external or internal information that flows through the network during the learning phase. Emgu. They can be used to model complex relationships between inputs and outputs or to find patterns in data.CV. It consists of an interconnected group of artificial neurons and processes information using a connectionist approach to computation.21 This is the simplest part. An artificial neural network (ANN)..CV. it checks the boolean value of CapturingProcess and changes the button text correspondingly and stops the streaming from the webcam.ML.Structure.Structure.. OpenCV implements Multi-Layer Perceptrons Neural Network.ML. Source Code using using using using .CV. System. In more practical terms neural networks are non-linear statistical data modeling tools.Drawing. Emgu. . Sample Output ANN MLP (Neural Network) in CSharp What is an Artificial Neural Network (ANN) According to wikipedia. usually called "neural network" (NN). Emgu. hence the name ANN_MLP. is a mathematical model or computational model based on biological neural networks.

2). trainClasses. . } } } // display the original training samples for (int i = 0. 1). trainSampleCount >> 1.1. Matrix<float> trainClasses = new Matrix<float>(trainSampleCount. i++) { PointF p1 = new PointF(trainData1[i. null.ANN_MLP_ACTIVATION_FUNCTION. Matrix<float> prediction = new Matrix<float>(1.ML. 0]. trainSampleCount >> 1. 1). 1).MlEnum.Draw(new CircleF(p1. 1]). j] = response < 1.ImageViewer. img. 0) : new Bgr(0. for (int i = 0. using (ANN_MLP network = new ANN_MLP(layerSize.MlEnum. PointF p2 = new PointF((int)trainData2[i.MlEnum. 1. j < img.CV.SIGMOID_SYM. 255. 100).0)) { network.Height.GetRows(trainSampleCount >> 1.CV.Train(trainData. Emgu. 1).Width. 2).CV. #endregion Matrix<int> layerSize = new Matrix<int>(new int[] { 2. 0). 1.22 int trainSampleCount = 100. sample.term_crit = new MCvTermCriteria(10. Matrix<float> trainData1 = trainData. trainData1[i. } Emgu.Data[0. img. network.SetValue(1). #region Generate the traning data and classes Matrix<float> trainData = new Matrix<float>(trainSampleCount.ML. -1). trainData1. (int)trainData2[i. i++) { for (int j = 0. // highlight the pixel depending on the accuracy (or confidence) img[i.GetRows(0. trainClasses1. trainData2.ML. 1. 0]. 1). null.GetRows(0. 2). Matrix<float> trainData2 = trainData. parameters. 1] = i.Draw(new CircleF(p2. Matrix<float> trainClasses1 = trainClasses. i < (trainSampleCount >> 1).Show(img). 0.DEFAULT). 5.0].0. new Bgr(255. parameters.Data[0.ANN_MLP_TRAINING_FLAG. new Bgr(100. 2).5 ? new Bgr(90. j++) { sample.1.bp_moment_scale = 0. Matrix<float> trainClasses2 = trainClasses.SetRandNormal(new MCvScalar(200). new MCvScalar(50)). Matrix<float> sample = new Matrix<float>(1.train_method = Emgu. Image<Bgr.0e-8).Data[0.ANN_MLP_TRAIN_METHOD. trainSampleCount.UI. // estimates the response and get the neighbors' labels float response = prediction.SetRandNormal(new MCvScalar(300). trainClasses2. -1).bp_dw_scale = 0. 500). 1]).BACKPROP. MCvANN_MLP_TrainParams parameters = new MCvANN_MLP_TrainParams(). prediction). trainSampleCount. Byte> img = new Image<Bgr. 90. parameters.CV. Emgu. 1 }). byte>(500. i < img. parameters. 100.Predict(sample. new MCvScalar(50)). 1).SetValue(2).GetRows(trainSampleCount >> 1. 100). parameters. 0] = j.

23 Result .