裁剪掉不包含Face的图像部分

时间:2015-12-25 08:09:34

标签: c# face-detection biometrics

我在图像中检测到了脸部(只有1个人)并且具有脸部矩形的坐标。

enter image description here

由于图像可以是任何大小,我只需要图像中重要的部分(head.shoulders)。想要做的是通过某种因素扩展检测到的矩形的边界,以便重要的部分是包括在内。 这是正确的方法吗?

更新
我试过这个..但它没有给出正确的结果。注意我已经将1.7更改为2,因为它只需要整数参数。而Top和Left都是只读属性。

foreach (Rectangle f in objects)
{
    int x, y;
    x = f.Top - (f.Height / 8);
    y = f.Left - (f.Width / 2);

    Rectangle myrect = new Rectangle(x, y, f.Width * 2, f.Height * 2);

    g.DrawRectangle(Pens.Gray, myrect);
}

检测到面部矩形

Top----->62
Right----->470
Left----->217
Bottom----->315

根据答案扩展矩形

Top----->91
Right----->537
Left----->31
Bottom----->597

扩展矩形

enter image description here

2 个答案:

答案 0 :(得分:1)

作为我的previous answer偏离主题,我会在这里写下我的正确答案:

<小时/> 由于我不完全熟悉Emgu CV,我会采用以下方法:

  1. 由于Emgu CV是开源的,你可以度过不安的夜晚并更改库中的代码并重新编译它们等。
  2. (我更喜欢的方法)

    1. 你在生物学上思考它,意思是:
      您知道脸部矩形的位置和大小。如果你也知道身体姿势,你可以计算肩膀的估计宽度和垂直偏移(相对于脸部的中心)。
    2. 生物学方法的更多细节:

      想象一下无花果。 №1开始为真,并想象你有以下图像和面部矩形:

      Bitmap
        | .Width == 100
        | .Height == 160
      
      Face // type: System.Drawing.Rectangle
        | .Top == 20
        | .Left == 50
        | .Width == 60
        | .Height == 60
      

      然后,根据提供的图像,新的Rectangle应该是:

      f := Face // face rectangle
      
      Face_and_Shoulder
        | .Top = f.Top - (f.Height / 8)
        | .Left = f.Left - (f.Width / 2)
        | .Width = f.Width * 2
        | .Height = f.Height * 1.7
      

      会产生以下值:

      Face_and_Shoulder
        | .Top == 12.5
        | .Left == 20
        | .Width == 120
        | .Height == 102
      

      在图像上绘制时,生成的矩形(Face_and_Shoulder)应包括肩部和头发等。

      这种方法有一个小缺点:如果面部旋转了一定的度数(我认为超过5..10°),它就无法工作。

      要计算相应的矩形,我建议您使用此代码(您似乎在代码示例中混淆了XY

      foreach (Rectangle f in objects)
      {
          float x = f.Left - (f.Width / 2f);
          float y = f.Top - (f.Height / 8f);
      
          Rectangle myrect = new Rectangle((int)x, (int)y, f.Width * 2, (int)(f.Height * 1.3));
      
          g.DrawRectangle(Pens.Gray, myrect);
      }
      

      fig. №1
      图。 №1 (来源:http://www.idrawdigital.com/wp-content/uploads/2009/01/prop_var.gif

答案 1 :(得分:0)

我会创建第二个位图并将第一个位图绘制到第二个位图中,如下所示:

Bitmap source = Image.FromFile("/my/path/to/myimage.png") as Bitmap;

Rectangle facerectangle = /* your face detection logic */;
Bitmap target = new Bitmap(facerectangle.Width, facerectangle.Height);

using (Graphics g = Graphics.FromImage(target))
{
    g.DrawImage(source, new Rectangle(0, 0, target.Width, target.Height),
                facerectangle, GraphicsUnit.Pixel);
}

代码应该很容易理解:)
首先加载位图source,然后使用面部识别逻辑创建矩形并创建位图target,在其中使用GDI +&#39; s DrawImage绘制第一个线段