使用Emgu识别图像中的黄点 [英] Identify Yellow spot's in Images using Emgu

查看:118
本文介绍了使用Emgu识别图像中的黄点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用EMGUCV识别图像中的黄斑

How shall i identify yellow spot in Images using EMGUCV

推荐答案

EMGUCV包含OpenCV库API中的大部分功能,因此大多数OpenCV示例(在C / C ++中)都是也适用于EmguCV。 Android端口也有很多样本(在Java / C ++中)。有这么多样本(例如这一个 http:// opencv-srf.blogspot.com.es/2010/09/object-detection-using-color-seperation.html [ ^ ])我认为这可能会更有助于告诉你部分理由背后的原因代码:



从一个图像中检测颜色区域可以简化为以下步骤:



1)将捕获的图像颜色空间转换为HSV,因为这种类型的处理更方便。参见 cvtColor()函数。

2)你可以选择 pyrDown()你的形象使处理更快。

3)过滤图像以减少噪音,你可以使用高斯滤波器。请参阅函数 cvSmooth(),过滤器类型为CV _ GAUSSIAN

4)有趣的部分,现在你只需要使用两个极限高低来压制你的图像。看一下函数 cvInRangeS()



在这个处理之后,你将有一个二进制图像,而不是null,以与 cvInRangeS()中使用的颜色cryteria匹配的像素为单位。后续步骤取决于您的应用程序,可能涉及 findContours()或用于检测场景中对象的任何其他原语。
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.






(发布为解决方案,因为一条评论太长了)



来自你的问题标签我假设您正在使用C#。我已经尝试过这段代码(在评论之后),它对我有用。它会有错误,值肯定需要修剪。它使用包装类并避免使用native / interop调用。



创建一个表单并放置两个名为'captureImageBox'和'的Emgu.CV.UI.ImageBox对象processedImageBox。还可以放置一个名为m_btnCapture的按钮。将下面的代码添加到表单的代码文件中。



代码使用第二个网络摄像头(用于在我的电脑中使用嵌入式网络摄像头以外),一个图像框显示原始图像(过滤)帧和另一个二进制处理帧。黑色是场景背景和白色检测(阈值)颜色区域。



当您单击按钮时,它会启动/停止捕获。点击拍摄的图像选择一种颜色。



希望它适合你。



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);
        }
    }
}


这篇关于使用Emgu识别图像中的黄点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆