DlibDo tNet - кластеризация и прогнозирование лица вручную - PullRequest
0 голосов
/ 21 апреля 2020

Я новичок в распознавании лиц, поэтому я даже не уверен, какую именно фразу нужно попросить. У меня DlibDo tNet и приложение, которое я пишу, запущено, и я могу передать ему кучу изображений, чтобы он нашел лица и создал кластеры похожих лиц:

var FaceDetector = Dlib.GetFrontalFaceDetector();
var ShapePredictor = ShapePredictor.Deserialize("shape_predictor_5_face_landmarks.dat");
var LossMetric = DlibDotNet.Dnn.LossMetric.Deserialize("dlib_face_recognition_resnet_model_v1.dat");
List<Matrix<RgbPixel>> faces = new List<Matrix<RgbPixel>>();
foreach (string imageFile in ImageFiles)
{
   var image = Dlib.LoadImage<RgbPixel>(imageFile);
   var faceRects = FaceDetector.Operator(image);
   foreach (var faceRect in faceRects)
   {
      var shape = ShapePredictor.Detect(image, faceRect);
      var faceChipDetail = Dlib.GetFaceChipDetails(shape, 150, 0.25);
      Array2D<RgbPixel> imageChip = Dlib.ExtractImageChip<RgbPixel>(img, faceChipDetail);
      Matrix<RgbPixel> face = new Matrix<RgbPixel>(imageChip);
      faces.Add(face);
   }
}
var FaceDescriptors = LossMetric.Operator(faces);
var edges = new List<SamplePair>();
for (uint i = 0; i < FaceDescriptors.Count; ++i)
{
    for (var j = i; j < FaceDescriptors.Count; ++j)
    {
        var diff = FaceDescriptors[i] - FaceDescriptors[j];
        if (Dlib.Length(diff) < 0.6)
            edges.Add(new SamplePair(i, j));
    }
}
Dlib.ChineseWhispers(edges, 100, out var numClusters, out var labels);

Это дает мне кучу групп лиц, которые в основном правильные.

Теперь я не уверен, как двигаться вперед. Я хочу создать нечто похожее на то, что раньше было в Picasa, где человеку был представлен список лиц и их вероятных кластеров, и его попросили подтвердить каждое. Я мог бы представить, что это грубая сила:

uint AssignProbableClusterToNewFace(Matrix<float> descriptorOfNewFace)
{
    double minDistance = double.MaxValue;
    Matrix<float> closestDescriptor = null;

    foreach (var knownDescriptor in KnownDescriptors)
    {
       var diff = descriptorOfNeWface - knownDescriptor;
       double distance = Dlib.Length(diff);
       if (distance < minDistance)
       {
          minDistance = distance;
          closestDescriptor = knownDescriptor;
       }
    }
    return (closestDescriptor == null) ? 0 : MapDescriptorToCluster[closestDescriptor];
}

Но по мере увеличения масштабов, я думаю, что это будет довольно медленно (у меня есть десятки тысяч изображений, содержащих сотни, если не тысячи отдельных людей) , Есть ли какая-нибудь умная нейронная сеть, которую я могу сделать, чтобы эффективно получить ответ на вопрос «на какое существующее лицо это новое лицо больше всего похоже?»

Или я задаю неправильный вопрос? Я представляю, что в каждом кластере лиц есть группа, которые достаточно похожи, а затем некоторые выбросы. Могу ли я на самом деле спросить «на какой центроид кластера это новое лицо больше всего похоже?»

...