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;
int bH = H;
int bS = S;
int bV = V;
float fH, fS, fV;
float fR, fG, fB;
fH = (float)bH * BYTE_TO_FLOAT;
fS = (float)bS * BYTE_TO_FLOAT;
fV = (float)bV * BYTE_TO_FLOAT;
int iI;
float fI, fF, p, q, t;
if (bS == 0)
{
fR = fG = fB = fV;
}
else
{
if (fH >= 1.0f)
fH = 0.0f;
fH *= (float)6.0;
fI = (float)Math.Floor(fH);
iI = (int)fH;
fF = fH - fI;
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:
fR = fV;
fG = p;
fB = q;
break;
}
}
int bR = (int)(fR * FLOAT_TO_BYTE);
int bG = (int)(fG * FLOAT_TO_BYTE);
int bB = (int)(fB * FLOAT_TO_BYTE);
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;
return new Bgr(bB, bG, bR);
}
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)
{
m_btnCapture.Text = "Capture";
Application.Idle -= ProcessFrame;
}
else
{
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)
{
m_ClickPoint = new Point(e.X, e.Y);
}
}
}