Click here to Skip to main content
15,885,757 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
How shall i identify yellow spot in Images using EMGUCV
Posted

EMGUCV wraps most functions from the OpenCV library API so most OpenCV examples (in C/C++) are also valid for EmguCV. There're lots of samples also for the Android port (in Java/C++). With so many samples out there (e.g. this one http://opencv-srf.blogspot.com.es/2010/09/object-detection-using-color-seperation.html[^]) I think it could be of more help telling you part of the rationale behind the code:

Detecting color regions from one image can be simplified to the following steps:

1) Convert your captured image color space to HSV as it is more convenient for this type of processing. See cvtColor() function.
2) You may optionaly pyrDown() your image to make processing faster.
3) Filter the image for reducing noise, you may use the gaussian filter. See function cvSmooth() with filter type CV_GAUSSIAN.
4) The funny part, now you just have to thresshold your image using two limits High and Low. Take a look at function cvInRangeS().

After this processing you'll have one binary image, not null in pixels that match the color cryteria used in cvInRangeS(). Next steps depend on your application and could involve findContours() or whatever other primitive used to detect objects in the scene.
 
Share this answer
 
Comments
arun_pk 5-Sep-13 10:47am    
Hi,
I am facing issues in using cvInRangeS() method..
Destination image parameter is creating issues for me :(
i get an exception like this
" Emgu.CV.Util.CvException: OpenCV: src1.size == dst.size && dst.type() == CV_8U"
V.Lorz 5-Sep-13 10:55am    
Hi, you have to create the destination matrix with the same size as the source matrix. The destination matrix should also be of 1 byte elements. This link could be of some help: http://www.emgu.com/wiki/files/2.0.0.0/html/17acc2fc-f298-5e57-102f-17e2f67003de.htm.
arun_pk 15-Sep-13 4:33am    
InRange method output is a gray image . still not able to find the no yellow color objects present
Hi,

(posted as solution as it is too long for one comment)

From your question tags I suppose you're using C#. I've tried this code (after the comment) and it works for me. It will have bugs and the values should surely require trimming. It uses the wrapping classes and avoids using the native/interop calls.

Create one form and place two Emgu.CV.UI.ImageBox objects named 'captureImageBox' and 'processedImageBox'. Also place one button named 'm_btnCapture'. Add the code below to the form's code file.

The codes uses the second webcam (for using other than the embedded one in my pc), one imagebox shows the original (filtered) frame and the other the binary processed frame. Black is scene background and white detected (thresholded) color regions.

When you click the button it starts/stops captures. Click on the captured image to select one color.

Hope it works for you.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.Structure;

namespace ColorDet
{
    public partial class Form1 : Form
    {
        private Capture _capture;
        private bool _captureInProgress;
        private Rectangle m_Rect;
        private Point m_ClickPoint;
        private Hsv m_TargetColor;
        private bool m_TrackColor;
        private Hsv m_Lower;
        private Hsv m_Higher;

        public Form1()
        {
            m_Rect = Rectangle.Empty;
            m_ClickPoint = Point.Empty;
            m_TrackColor = false;

            InitializeComponent();
        }


        private void ProcessFrame(object sender, EventArgs arg)
        {
            Image<Bgr, Byte> frame = _capture.QueryFrame();

            frame = frame.SmoothGaussian(3, 3, 1, 1);

            if (!m_ClickPoint.Equals(Point.Empty))
            {
                Rectangle Rect = new Rectangle(m_ClickPoint.X - 5, m_ClickPoint.Y - 5, 10, 10);

                if (Rect.X < 0)
                    Rect.X = 0;

                if (Rect.Y < 0)
                    Rect.Y = 0;

                using (Image<Bgr, Byte> TouchRegion = frame.GetSubRect(Rect))
                {
                    using (Image<Hsv, Byte> TouchRegionHsv = TouchRegion.Convert<Hsv, byte>())
                    {
                        int Points = TouchRegion.Width*TouchRegion.Height;

                        m_TargetColor = TouchRegionHsv.GetAverage();
                        Bgr Colr = Convert(m_TargetColor);

                        m_Lower = new Hsv(m_TargetColor.Hue - 30, m_TargetColor.Satuation - 30, m_TargetColor.Value - 30);
                        m_Higher = new Hsv(m_TargetColor.Hue + 30, m_TargetColor.Satuation + 30, m_TargetColor.Value + 30);

                        panel2.BackColor = Color.FromArgb((int)Colr.Red, (int)Colr.Green, (int)Colr.Blue);

                        frame.Draw(Rect, new Bgr(Color.Red), 1);
                        m_TrackColor = true;
                    }
                }

                m_ClickPoint = Point.Empty;
            }

            if (m_TrackColor)
            {
                Image<Hsv, Byte> HsvFrame = frame.Convert<Hsv, byte>();
                HsvFrame = HsvFrame.SmoothGaussian(5, 5, 0.1, 0.1);
                Image<Gray, byte> InRageFrame = HsvFrame.InRange(m_Lower, m_Higher);
                processedImageBox.Image = InRageFrame;
            }

            captureImageBox.Image = frame;
        }


        const float FLOAT_TO_BYTE = 255.0f;
        const float BYTE_TO_FLOAT = 1.0f / FLOAT_TO_BYTE;

        private Bgr Convert(Hsv hsv)
        {
            int H = (int)hsv.Hue;
            int S = (int)hsv.Satuation;
            int V = (int)hsv.Value;
            // HSV to RGB color conversion in OpenCV

            int bH = H; // H component
            int bS = S; // S component
            int bV = V; // V component
            float fH, fS, fV;
            float fR, fG, fB;

            // Convert from 8-bit integers to floats
            fH = (float)bH * BYTE_TO_FLOAT;
            fS = (float)bS * BYTE_TO_FLOAT;
            fV = (float)bV * BYTE_TO_FLOAT;

            // Convert from HSV to RGB, using float ranges 0.0 to 1.0
            int iI;
            float fI, fF, p, q, t;

            if (bS == 0)
            {
                // achromatic (grey)
                fR = fG = fB = fV;
            }
            else
            {
                // If Hue == 1.0, then wrap it around the circle to 0.0
                if (fH >= 1.0f)
                    fH = 0.0f;

                fH *= (float)6.0; // sector 0 to 5
                fI = (float)Math.Floor(fH); // integer part of h (0,1,2,3,4,5 or 6)
                iI = (int)fH; // " " " "
                fF = fH - fI; // factorial part of h (0 to 1)

                p = fV * (1.0f - fS);
                q = fV * (1.0f - fS * fF);
                t = fV * (1.0f - fS * (1.0f - fF));

                switch (iI)
                {
                    case 0:
                        fR = fV;
                        fG = t;
                        fB = p;
                        break;

                    case 1:
                        fR = q;
                        fG = fV;
                        fB = p;
                        break;

                    case 2:
                        fR = p;
                        fG = fV;
                        fB = t;
                        break;

                    case 3:
                        fR = p;
                        fG = q;
                        fB = fV;
                        break;

                    case 4:
                        fR = t;
                        fG = p;
                        fB = fV;
                        break;

                    default: // case 5 (or 6):
                        fR = fV;
                        fG = p;
                        fB = q;
                        break;
                }
            }

            // Convert from floats to 8-bit integers
            int bR = (int)(fR * FLOAT_TO_BYTE);
            int bG = (int)(fG * FLOAT_TO_BYTE);
            int bB = (int)(fB * FLOAT_TO_BYTE);

            // Clip the values to make sure it fits within the 8bits.
            if (bR > 255)
                bR = 255;
            if (bR < 0)
                bR = 0;
            if (bG > 255)
                bG = 255;
            if (bG < 0)
                bG = 0;
            if (bB > 255)
                bB = 255;
            if (bB < 0)
                bB = 0;

            // Set the RGB cvScalar with G B R, you can use this values as you want too..
            return new Bgr(bB, bG, bR); // R component
        }


        private void m_btnCapture_Click(object sender, EventArgs e)
        {
            if (_capture == null)
            {
                try
                {
                    _capture = new Capture(1);
                }
                catch (NullReferenceException excpt)
                {
                    MessageBox.Show(excpt.Message);
                }
            }

            if (_capture != null)
            {
                _captureInProgress = !_captureInProgress;

                if (!_captureInProgress)
                {  //stop the capture
                    m_btnCapture.Text = "Capture";
                    Application.Idle -= ProcessFrame;
                }
                else
                {
                    //start the capture
                    m_btnCapture.Text = "Stop";
                    Application.Idle += ProcessFrame;
                }
            }
        }


        private void ReleaseData()
        {
            if (_capture != null)
            {
                _capture.Dispose();
                _capture = null;
            }
        }

        private void captureImageBox_MouseClick(object sender, MouseEventArgs e)
        {
            //e.X;
            m_ClickPoint = new Point(e.X, e.Y);
        }
    }
}
 
Share this answer
 
Comments
V.Lorz 15-Sep-13 10:09am    
I grabbed the code for converting one value from Hsv to rgb from internet (function 'Convert') and adapted the original code to C# (it was C++) just enough to make it work, so it is ugly and probably not accurate. I can't remember where I took the code from. The intention was to give one idea about how the average colour would look like.

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900