Click here to Skip to main content
15,886,919 members
Articles / Programming Languages / C#
Tip/Trick

Emgu CV -Select ROI (Region Of Interest) With Mouse - C#

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
3 Jan 2015CPOL2 min read 67.7K   3.7K   17   6
Emgu CV - Select ROI (Region of interest) with the mouse in images that do not have the same measurements. This tip was prepared using the framework Emgu CV and C # .NET language.

Introduction

This tip deals with a way to select a ROI (Region of Interest) using the mouse on identical images that do not have the same size. This product was developed based on Emgu CV framework by C# .NET language. The creation of this tip is justified because many developers are paralyzed when using ImageBox or PictureBox to render and manipulate a region of interest in an image, so I decided to prepare a tip that would allow the reader an understanding of how to select a ROI same the input image and output do not have the same sizes. I hope this tip is useful to you. Share it! Happy reading and successes.

Image 1

Background

For a better understanding of the reasons for this product, please read the posts below present in the Emgu CV forum.

Using the Code

Below is the main function that returns the actual coordinates of an image. This function is essential for the implementation of ROI selection by mouse and found the csharphelper site.

C#
/// <summary>
/// Convert the coordinates for the image's SizeMode.
/// </summary>
/// http://csharphelper.com/blog/2014/10/select-parts-of-a-scaled-image-picturebox-different-sizemode-values-c/</a>
/// http://csharphelper.com/blog/2014/10/select-parts-of-a-scaled-image-picturebox-different-sizemode-values-c/</a>
/// <param name="pic"></param>
/// <param name="X0">out X coordinate</param>
/// <param name="Y0">out Y coordinate</param>
/// <param name="x">atual coordinate</param>
/// <param name="y">atual coordinate</param>
        public static void ConvertCoordinates(PictureBox pic,
            out int X0, out int Y0, int x, int y)
        {
            int pic_hgt = pic.ClientSize.Height;
            int pic_wid = pic.ClientSize.Width;
            int img_hgt = pic.Image.Height;
            int img_wid = pic.Image.Width;

            X0 = x;
            Y0 = y;
            switch (pic.SizeMode)
            {
                case PictureBoxSizeMode.AutoSize:
                case PictureBoxSizeMode.Normal:
                    // These are okay. Leave them alone.
                    break;
                case PictureBoxSizeMode.CenterImage:
                    X0 = x - (pic_wid - img_wid) / 2;
                    Y0 = y - (pic_hgt - img_hgt) / 2;
                    break;
                case PictureBoxSizeMode.StretchImage:
                    X0 = (int)(img_wid * x / (float)pic_wid);
                    Y0 = (int)(img_hgt * y / (float)pic_hgt);
                    break;
                case PictureBoxSizeMode.Zoom:
                    float pic_aspect = pic_wid / (float)pic_hgt;
                    float img_aspect = img_wid / (float)img_wid;
                    if (pic_aspect > img_aspect)
                    {
                        // The PictureBox is wider/shorter than the image.
                        Y0 = (int)(img_hgt * y / (float)pic_hgt);

                        // The image fills the height of the PictureBox.
                        // Get its width.
                        float scaled_width = img_wid * pic_hgt / img_hgt;
                        float dx = (pic_wid - scaled_width) / 2;
                        X0 = (int)((x - dx) * img_hgt / (float)pic_hgt);
                    }
                    else
                    {
                        // The PictureBox is taller/thinner than the image.
                        X0 = (int)(img_wid * x / (float)pic_wid);

                        // The image fills the height of the PictureBox.
                        // Get its height.
                        float scaled_height = img_hgt * pic_wid / img_wid;
                        float dy = (pic_hgt - scaled_height) / 2;
                        Y0 = (int)((y - dy) * img_wid / pic_wid);
                    }
                    break;
            }
        } 

Assign the following events in the form of events.

C#
#region EVENTOS PICTURE BOX | DEFINIÇÃO DE ROI
        private Point RectStartPoint;
        private Rectangle Rect = new Rectangle();
        private Rectangle RealImageRect = new Rectangle();
        private Brush selectionBrush = new SolidBrush(Color.FromArgb(128, 64, 64, 64));
        private int thickness = 3;

        /// <summary>
        /// Start Rectangle
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            // Determine the initial rectangle coordinates...
            RectStartPoint = e.Location;
            Invalidate();
        }

        /// <summary>
        /// Draw Rectangle
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            #region SETS COORDINATES AT INPUT IMAGE BOX
            int X0, Y0;
            Utilities.ConvertCoordinates(imageBoxInput, out X0, out Y0, e.X, e.Y);
            labelPostionXY.Text = "Last Position: X:" + X0 + "  Y:" + Y0;

            //Coordinates at input picture box
            if (e.Button != MouseButtons.Left)
                return;
            Point tempEndPoint = e.Location;
            Rect.Location = new Point(
                Math.Min(RectStartPoint.X, tempEndPoint.X),
                Math.Min(RectStartPoint.Y, tempEndPoint.Y));
            Rect.Size = new Size(
                Math.Abs(RectStartPoint.X - tempEndPoint.X),
                Math.Abs(RectStartPoint.Y - tempEndPoint.Y));
            #endregion

            #region SETS COORDINATES AT REAL IMAGE
            //Coordinates at real image - Create ROI
            Utilities.ConvertCoordinates(imageBoxInput, out X0, out Y0, 
            RectStartPoint.X, RectStartPoint.Y);
            int X1, Y1;
            Utilities.ConvertCoordinates(imageBoxInput, out X1, out Y1, tempEndPoint.X, tempEndPoint.Y);
            RealImageRect.Location = new Point(
                Math.Min(X0, X1),
                Math.Min(Y0, Y1));
            RealImageRect.Size = new Size(
                Math.Abs(X0 - X1),
                Math.Abs(Y0 - Y1));

            imgEntrada = new Image<Bgr, byte>("lena.jpg");
            imgEntrada.Draw(RealImageRect, new Bgr(Color.Red), thickness);
            imageBoxOutputROI.Image = imgEntrada;
            #endregion

            ((PictureBox)sender).Invalidate();
        }

        /// <summary>
        /// Desenha retângulo
        /// </summary>
        /// http://stackoverflow.com/questions/11088154/graphics-fillrectangle-except-specified-area-net-gdi
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
        {
            // Draw the rectangle...
            if (imageBoxInput.Image != null)
            {
                if (Rect != null && Rect.Width > 0 && Rect.Height > 0)
                {
                    //Seleciona a ROI
                    e.Graphics.SetClip(Rect, System.Drawing.Drawing2D.CombineMode.Exclude);
                    e.Graphics.FillRectangle(selectionBrush, new Rectangle
            (0, 0, ((PictureBox)sender).Width, ((PictureBox)sender).Height));
                    //e.Graphics.FillRectangle(selectionBrush, Rect);
                }
            }
        }

        private void pictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            //Define ROI. Valida altura e largura para evitar index range exception.
            if (RealImageRect.Width > 0 && RealImageRect.Height > 0)
            {
                imgEntrada.ROI = RealImageRect;
                imageBoxROI.Image = imgEntrada;
            }

        }

        private void pictureBox_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Rect = new Rectangle();
            ((PictureBox)sender).Invalidate();
        }

        #endregion

To succeed in the build of the attached application in this tip referencing the DLLs Emgu CV on the project preventing them stay with an exclamation highlighted in yellow. In the image below, the DLLs are properly referenced in the project.

Image 2

Another point worth mentioning is present in the wrapper DLLs (which are linked to C++ code) that must be referenced pointing to the application of the output directory. Below is an example of applied configuration in Visual Studio 2013.

Image 3

Points of Interest

I stayed a week researching ways to implement the ROI with the mouse but did not succeed . After a week without resolving, I returned to the research and managed to solve it in half an hour.

Reference

This tip is based on doubts in the official forum Emgu CV. As a research source, I used the site: http://csharphelper.com/blog/2014/10/select-parts-of-a-scaled-image-picturebox-different-sizemode-values-c/

License

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


Written By
Software Developer G&P Projetos e Sistemas SA
Brazil Brazil
I am software developer and researcher in the fields of image processing . I like to learn new information and share content . I hope to contribute more and at the same time acquire more knowledge with new articles.

Comments and Discussions

 
Questionhow to prevent Image from resizing when mouse is up? Pin
OriCpp22-Jan-21 23:52
OriCpp22-Jan-21 23:52 
Questionim missing library Pin
Frank Lopez24-Nov-15 20:50
Frank Lopez24-Nov-15 20:50 
QuestionZoom Scale Pin
Member 1200878010-Nov-15 1:09
Member 1200878010-Nov-15 1:09 
AnswerRe: Zoom Scale Pin
Member 1278845716-Oct-16 16:25
Member 1278845716-Oct-16 16:25 
SuggestionNo file to download :( Pin
marcinjutag10-Jan-15 5:31
marcinjutag10-Jan-15 5:31 
GeneralRe: No file to download :( Pin
Richard J. Algarve10-Jan-15 5:54
professionalRichard J. Algarve10-Jan-15 5:54 

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.