我目前正在做一个身份证照片上传系统使用C#的Windows应用程序的形式,我想让用户上传一幅图像,该图像必须只包含一个正面。为了防止用户上传超过1张脸,我想在系统检测到图像中有多张脸时提示他们错误信息,但我不确定如何去做。我用的是竹内拓屋的dlibdotnet库。
这是我当前的代码。
namespace DetectTrial
{
public partial class Form1 : Form
{
#region Fields
private readonly BackgroundWorker _BackgroundWorker;
#endregion
#region Constructors
public Form1()
{
this.InitializeComponent();
this._BackgroundWorker = new BackgroundWorker();
this._BackgroundWorker.DoWork += this.BackgroundWorkerOnDoWork;
}
#endregion
#region Methods
#region Event Handlers
private void BackgroundWorkerOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs)
{
var path = doWorkEventArgs.Argument as string;
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
return;
using (var faceDetector = Dlib.GetFrontalFaceDetector())
using (var ms = new MemoryStream(File.ReadAllBytes(path)))
using (var bitmap = (Bitmap)Image.FromStream(ms))
{
using (var image = bitmap.ToArray2D<RgbPixel>())
{
var dets = faceDetector.Operator(image);
foreach (var g in dets)
Dlib.DrawRectangle(image, g, new RgbPixel { Green = 255 }, thickness: 10);
var result = image.ToBitmap();
this.pictureBox1.Invoke(new Action(() =>
{
this.pictureBox1.Image?.Dispose();
this.pictureBox1.Image = result;
}));
}
}
}
private void button1_Click(object sender, EventArgs e)
{
using (var opnfd = new OpenFileDialog())
{
opnfd.Filter = "Image Files (*.jpg;*.jpeg;*.png;)|*.jpg;*.jpeg;*.png";
if (opnfd.ShowDialog(this) == DialogResult.OK)
{
this._BackgroundWorker.RunWorkerAsync(opnfd.FileName);
}
}
}
#endregion
#endregion
}
}我不知道下一步该怎么走。
发布于 2021-02-05 11:17:01
我不熟悉您正在使用的库,但如果dets是检测到的人脸矩形的集合,您可能可以使用以下内容:
var dets = faceDetector.Operator(image);
if (dets.Count() > 1)
{
MessageBox.Show("Too many faces! Why are there so many faces? I can't look. Please make it stop.");
return;
}
else
{
var g = dets.First();
Dlib.DrawRectangle(image, g, new RgbPixel { Green = 255 }, thickness: 10);
var result = image.ToBitmap();
this.pictureBox1.Invoke(new Action(() =>
{
this.pictureBox1.Image?.Dispose();
this.pictureBox1.Image = result;
}));
}注意,Count()和First()是来自System.Linq的扩展方法,因此您需要确保在代码文件的顶部有一个using System.Linq;指令。
此外,最好将Invoke代码移到BackgroundWorker的OnRunWorkerCompleted事件(此时将不再需要跨线程调用),这样您就可以直接访问PictureBox了。
https://stackoverflow.com/questions/66056910
复制相似问题