裁剪掉不包括人脸的图像部分
Crop off Parts of the Image that does not include the Face
我检测到图像中的人脸(只有 1 个人),并且有人脸矩形的坐标。
由于图像可以是任意大小,我只需要图像中重要的部分 (head.shoulders)。这样做的目的是将检测到的矩形的边界扩展一些因素,以便包括重要部分。
这是正确的方法吗?
更新:
我试过这个 .. 但它没有给出正确的 result.Note 我已经将 1.7 更改为 2 因为它只需要整数 arguments.And 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
扩展矩形
我将创建第二个位图并将第一个位图绘制到第二个位图中,如下所示:
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+ 的 DrawImage
.
绘制第一段
作为我的previous answer和off-topic一样,我把我的正确答案写在这里:
由于我对Emgu CV
不是很熟悉,我会有以下做法:
- 由于 Emgu CV 是 open-source,您可以度过不安的夜晚,更改库中的代码并重新编译它们等
或(我的首选方法):
- 你从生物学角度考虑,意思是:
您知道面部矩形的位置和大小。如果你也知道 body 比例,你可以计算出肩膀的估计宽度和垂直偏移量(相对于面部中心)。
生物学方法的更多细节:
想象一下图。 №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°),它将不起作用。
要计算相应的矩形,我建议您使用此代码 (您似乎混淆了代码示例中的 X
和 Y
):
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);
}
图。 №1 (来源:http://www.idrawdigital.com/wp-content/uploads/2009/01/prop_var.gif)
我检测到图像中的人脸(只有 1 个人),并且有人脸矩形的坐标。
由于图像可以是任意大小,我只需要图像中重要的部分 (head.shoulders)。这样做的目的是将检测到的矩形的边界扩展一些因素,以便包括重要部分。 这是正确的方法吗?
更新:
我试过这个 .. 但它没有给出正确的 result.Note 我已经将 1.7 更改为 2 因为它只需要整数 arguments.And 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
扩展矩形
我将创建第二个位图并将第一个位图绘制到第二个位图中,如下所示:
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+ 的 DrawImage
.
作为我的previous answer和off-topic一样,我把我的正确答案写在这里:
由于我对
Emgu CV
不是很熟悉,我会有以下做法:
- 由于 Emgu CV 是 open-source,您可以度过不安的夜晚,更改库中的代码并重新编译它们等
或(我的首选方法):
- 你从生物学角度考虑,意思是:
您知道面部矩形的位置和大小。如果你也知道 body 比例,你可以计算出肩膀的估计宽度和垂直偏移量(相对于面部中心)。
生物学方法的更多细节:
想象一下图。 №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°),它将不起作用。
要计算相应的矩形,我建议您使用此代码 (您似乎混淆了代码示例中的 X
和 Y
):
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);
}
图。 №1 (来源:http://www.idrawdigital.com/wp-content/uploads/2009/01/prop_var.gif)