Я пытаюсь реализовать функцию распознавания лиц с захватом видео с использованием библиотеки EmguCV 3.1.0.1 , устанавливаемой пакетами NuGet VS15 на 64-битную ОС Windows 10 ПК в настольном приложении WinForms.
Моя цель - получить обнаружение и отслеживание человеческого лица с видеокамеры и обнаружить улыбку, но для примеров ниже я буду использовать только лицо HaarCascade
.xml с CascadeClassifier
.
Итак,использование с DirectShowLib
библиотекой для videoDevice
из comboBox1_SelectedIndexChanged
SelectedItem
:
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.UI;
using DirectShowLib;
Путь к HaarCascade xml-s:
string facePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "dir\\haarcascade_frontalface_default.xml");
Таймер:
private void timer1_Tick(object sender, EventArgs e)
{
detectFace();
}
Попытка 1:
private void detectFace()
{
CascadeClassifier face = new CascadeClassifier(facePath);
Image<Bgr, Byte> currentframe = null;
Image<Gray, byte> grayFrame = null;
Capture grabber;
grabber = new Capture(videoDevice);
currentframe = grabber.QueryFrame().Resize(500, 320, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
if (currentframe != null)
{
grayFrame = currentframe.Convert<Gray, Byte>();
Rectangle[] faceDetected = face.DetectMultiScale(grayFrame, 1.1, 10, Size.Empty, Size.Empty);
foreach (Rectangle faceFound in faceDetected)
{
currentframe.Draw(faceFound, new Bgr(Color.Red), 2);
}
pictureBox1.Image = currentframe.ToBitmap();
}
}
строка currentframe = grabber.QueryFrame().Resize(500, 320, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
говорит:
Ошибка CS0234 Тип или имя пространства имен «INTER» не существует в пространстве имен «Emgu».CV.CvEnum '(вам не хватает ссылки на сборку?)
Вместо этого я попытался использовать currentframe = grabber.QueryFrame().Resize(500, 320, Emgu.CV.CvEnum.TemplateMatchingType.CcoeffNormed);
с grabber.QueryFrame().MatchTemplate
или grabber.QueryFrame().Retrieve
, но другая ошибка по-прежнему сохраняетсястрока как:
Ошибка CS1061 'Mat' не содержит определения для 'Resize', и не найден метод расширения 'Resize', принимающий первый аргумент типа 'Mat' (вы пропускаетеиспользуя директиву или ссылку на сборку?)
Я не уверен, где я должен загрузить требуемые dll-ы (если это является причиной отсутствия?) и какие dll-ы именно я должен добавить к ссылкам дополнительно.
Попытка 2:
private Capture _capture;
private CascadeClassifier _cascadeClassifier;
private void detectFace()
{
_capture = new Capture(videoDevice);
_cascadeClassifier = new CascadeClassifier(facePath);
using (var imageFrame = _capture.QueryFrame().ToImage())
{
if (imageFrame != null)
{
var grayframe = imageFrame.Convert();
var faces = _cascadeClassifier.DetectMultiScale(grayframe, 1.1, 10, Size.Empty);
foreach (var face in faces)
{
imageFrame.Draw(face, new Bgr(Color.Red), 3);
}
}
pictureBox1.Image = imageFrame.ToBitmap();
}
}
line using (var imageFrame = _capture.QueryFrame().ToImage())
:
Ошибка CS0411 Theаргументы типа для метода 'Mat.ToImage (bool)' не могут быть выведены из использования.Попробуйте явно указать аргументы типа.
line var grayframe = imageFrame.Convert();
:
Ошибка CS0411 Аргументы типа для метода 'Image.Convert ()' не могут быть выведены из использования,Попробуйте явно указать аргументы типа.
line imageFrame.Draw(face, new Bgr(Color.Red), 3);
:
Ошибка CS1503 Аргумент 2: невозможно преобразовать из Emgu.CV.Structure.Bgr в TColor'
Любое руководство, совет или пример будут полезны
Редактировать Михал Навроцик ответ ниже:
Метод 1:
private void detectFace()
{
CascadeClassifier face = new CascadeClassifier(facePath);
Image<Bgr, Byte> currentframe = null;
Image<Gray, byte> grayFrame = null;
Capture grabber;
grabber = new Capture(videoDevice);
var dstMat = new Mat();
var frame = grabber.QueryFrame();
CvInvoke.Resize(frame, dstMat, new Size(500, 320), interpolation: Emgu.CV.CvEnum.Inter.Cubic);
currentframe = dstMat.ToImage<Bgr, byte>();
if (currentframe != null)
{
grayFrame = currentframe.Convert<Gray, Byte>();
Rectangle[] faceDetected = face.DetectMultiScale(grayFrame, 1.1, 10, Size.Empty, Size.Empty);
foreach (Rectangle faceFound in faceDetected)
{
currentframe.Draw(faceFound, new Bgr(Color.Red), 2);
}
pictureBox1.Image = currentframe.ToBitmap();
}
}
Необработанное исключение:
System.AccessViolationException 'произошло в Emgu.CV.World.dll Дополнительная информация: Попытка чтения или записи в защищенную память.Это часто указывает на то, что другая память повреждена
Метод 2:
private Capture _capture;
private CascadeClassifier _cascadeClassifier;
private void detectFace()
{
_capture = new Capture(videoDevice);
_cascadeClassifier = new CascadeClassifier(facePath);
using (var imageFrame = _capture.QueryFrame().ToImage<Bgr, byte>())
{
if (imageFrame != null)
{
var grayframe = imageFrame.Convert<Gray, byte>();
var faces = _cascadeClassifier.DetectMultiScale(grayframe, 1.1, 10, Size.Empty);
foreach (var face in faces)
{
imageFrame.Draw(face, new Bgr(Color.Red), 3);
}
}
pictureBox1.Image = imageFrame.ToBitmap();
}
}
}
исключение:
Emgu.CV.Util.CvException 'произошла в Emgu.CV.World.dll Дополнительная информация: OpenCV: нераспознанный или неподдерживаемый тип массива