我正在开发一个使用网络摄像头来检测脸部的程序。我有两种形式:主表单和相机表单。
Main
表单用于显示带有绿色和红色点图片的网络摄像头状态(已附加或已分离)。我使用Timer
扫描相机,如果连接了网络摄像头,则图片将为绿色,Camera
表单将显示,如果网络摄像头已分离,则图片将为红色且Camera
表单将自己关闭。Camera
表单用于显示网络摄像头的Feed。如果它检测到脸部,表格将在脸部周围画一个正方形。主要问题是:如果Camera
表格已经打开并被关闭。第二次打开。视频Feed会变黑并且Main
形式会大量滞后。 (如果我手动关闭Camera
表格,则不会有任何问题。)
这是用于检测网络摄像头的Main
形式的代码:
private System.Threading.Timer deviceScanner;
private void scanDevices() => deviceScanner = new System.Threading.Timer(checkDevices, null, 0, 1000);
private void checkDevices(object state)
{
hasCamera = checkCamera();
if (hasCamera)
{
Cam_status.Image = Properties.Resources.Aqua_Ball_Green_icon;
if (hasCamera == true && hasCameraForm == false)
{
this.BeginInvoke(new Action(() =>
{
Camera cam = new Camera();
cam.Show();
}));
}
hasCameraForm = true;
}
else if (!hasCamera)
{
Cam_status.Image = Properties.Resources.Aqua_Ball_Red_icon;
//MiscFunc.status_cam = false;
this.BeginInvoke(new MethodInvoker(() =>
{
MiscFunc.closeForm("Camera");
}));
hasCameraForm = false;
}
}
private bool checkCamera()
{
string CamTest = SelectCardModel();
return CamTest.Length > 0;
}
public string cam_name;
public string SelectWebCamModel()
{
try
{
ManagementObjectSearcher searcherAcr = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity Where Name Like '%Logitech%'");
if (searcherAcr.Get().Count == 0)
{
return cam_name = "";
}
foreach (ManagementObject usb in searcherAcr.Get())
{
cam_name = "Logitec";
}
}
catch
{
}
return cam_name;
}
这是Camera
形式的代码:
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace cameraprogram
{
public partial class Camera : Form
{
private Image<Bgr, Byte> currentFrame;
private Capture grabber;
private HaarCascade face;
private HaarCascade eye;
private MCvFont font = new MCvFont(FONT.CV_FONT_HERSHEY_TRIPLEX, 0.5d, 0.5d);
private Image<Gray, byte> result;
private Image<Gray, byte> gray = null;
private List<Image<Gray, byte>> trainingImages = new List<Image<Gray, byte>>();
private List<string> labels = new List<string>();
private List<string> NamePersons = new List<string>();
private int t;
private void Camera_Load(object sender, EventArgs e)
{
grabber = new Capture();
grabber.QueryFrame();
Application.Idle += FrameGrabber;
}
public Camera()
{
InitializeComponent();
face = new HaarCascade("haarcascade_frontalface_default.xml");
eye = new HaarCascade("haarcascade_eye.xml");
}
private void FrameGrabber(object sender, EventArgs e)
{
NamePersons.Add("");
currentFrame = grabber.QueryFrame().Resize(320, 240, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
gray = currentFrame.Convert<Gray, Byte>();
MCvAvgComp[][] facesDetected = gray.DetectHaarCascade(
face, 1.2, 10, Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, new Size(20, 20));
foreach (MCvAvgComp f in facesDetected[0])
{
t++;
result = currentFrame.Copy(f.rect).Convert<Gray, byte>().Resize(100, 100, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
currentFrame.Draw(f.rect, new Bgr(Color.Red), 2);
Status_camera = true;
}
t = 0;
imageBox1.Image = currentFrame;
}
}
}