J'ai détecté le visage dans une image (1 personne seulement) et j'ai les coordonnées du rectangle du visage.

enter image description here

Étant donné que l'image peut être de n'importe quelle taille, je n'ai besoin que de la partie de l'image qui est importante (tête, épaules) .L'intention de faire est d'étendre les limites du rectangle détecté d'un certain facteur afin que les parties importantes soient incluses. Est-ce la bonne approche?

Mettre à jour:
J'ai essayé ceci .. mais ce n'est pas donner le résultat correct. Notez que j'ai changé 1.7 en 2 car il ne prend que des arguments entiers. Et Haut et Gauche sont des propriétés en lecture seule.

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);
}

Rectangle de visage détecté

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

Rectangle étendu selon la réponse

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

Rectangle étendu

enter image description here

4
techno 25 déc. 2015 à 11:09

2 réponses

Meilleure réponse

Comme ma réponse précédente est hors sujet, j'écrirai ma réponse correcte ici:


Emgu CV
  1. Comme Emgu CV est open-source, vous pourriez passer des nuits agitées et changer le code à l'intérieur des bibliothèques et les recompiler, etc.

Ou (mon approche préférable) :

  1. Vous y pensez biologiquement, c'est-à-dire:
    Vous connaissez la position et la taille de votre rectangle de visage. Si vous connaissez également les proportions du corps, vous pouvez calculer la largeur estimée des épaules et leur décalage vertical (par rapport au centre du visage).

Plus de détails sur l'approche biologique:

Imaginez fig. №1 commencez vrai et imaginez que vous avez l'image et le rectangle de visage suivants:

Bitmap
  | .Width == 100
  | .Height == 160

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

Puis, selon l'image fournie, le nouveau Rectangle doit être:

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

Ce qui donnerait les valeurs suivantes:

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

Le rectangle obtenu (Face_and_Shoulder) doit inclure l'épaule et les cheveux, etc. lors du dessin sur votre image.

Cette méthode présente cependant un inconvénient mineur: elle ne fonctionnera pas, si le visage est tourné d'un certain nombre de degrés (je crois plus de 5..10 °).


Pour calculer le rectangle respectif, je vous conseillerais d'utiliser ce code (vous semblez avoir confondu X et Y dans votre exemple de code) :

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
fig. №1 (source: http: //www.idrawdigital.com/wp-content/uploads/2009/01/prop_var.gif)

1
Community 23 mai 2017 à 12:34

Je créerais un deuxième bitmap et dessinerais le premier dans le second comme suit:

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);
}

Le code doit être assez simple à comprendre :)
Vous chargez d'abord votre bitmap source, puis créez votre rectangle en utilisant votre logique de reconnaissance faciale et créez le bitmap target, dans lequel vous dessinez le premier segment à l'aide de GDI + DrawImage.

0
unknown6656 25 déc. 2015 à 08:48