Я пытаюсь создать программу, которая распознает и анонимизирует лица на таких вещах, как удостоверения личности. Я перевел пример Python, который нашел , на C #, и он работал безупречно на большинстве примеров. Тем не менее, некоторые изображения дают обнаружения, которые находятся за пределами.
Шаги для воспроизведения:
- Создание нового консольного проекта.
- Добавьте пакет nuget: ' OpenCvSharp4.Windows '.
- Загрузите необходимые файлы (внизу этого вопроса).
- Вставьте код и поместите файлы в папку с именами файлов в папке отладки программы.
Код для воспроизведения:
static void Main( string[] args )
{
anonymize( new byte[][] { File.ReadAllBytes("files\\elon-musk.jpg") }, "files\\deploy.prototxt", "files\\model.caffemodel" );
Console.ReadKey();
}
private static void anonymize( byte[][] files, string caffeProtoTxtFile, string caffeModelFile )
{
int i = 0;
foreach( var fileBytes in files )
{
i++;
Console.WriteLine( $"Image nr.{i}" );
using( var net = OpenCvSharp.Dnn.Net.ReadNetFromCaffe( caffeProtoTxtFile, caffeModelFile ) )
{
var image = Cv2.ImDecode( fileBytes, ImreadModes.AnyColor | ImreadModes.AnyDepth );
Console.WriteLine( $"\nImage size:\nWidth:{image.Width}\nHeight:{image.Height}\n\n" );
var detections = detectFaceDNN( image, net, true );
image.Dispose();
}
}
}
private static Rect[] detectFaceDNN( Mat image, OpenCvSharp.Dnn.Net net, bool draw )
{
var detectionRectangles = new List<Rect>();
using( var blob = OpenCvSharp.Dnn.CvDnn.BlobFromImage( image, 1, size: new Size( image.Width, image.Height ), mean: new Scalar( 91.4953, 103.8827, 131.0912 ) ) )
{
net.SetInput( blob );
using( var detections = net.Forward() )
{
for( int i = 0; i < detections.Size( 2 ); i++ )
{
var confidence = detections.At<float>( 0, 0, i, 2 );
if( confidence > 0.85 )
{
var startX = (int)Math.Round( detections.At<float>( 0, 0, i, 3 ) * image.Width );
var startY = (int)Math.Round( detections.At<float>( 0, 0, i, 4 ) * image.Height );
var endX = (int)Math.Round( detections.At<float>( 0, 0, i, 5 ) * image.Width );
var endY = (int)Math.Round( detections.At<float>( 0, 0, i, 6 ) * image.Height );
var coordinatesOutOfBounds = endX > image.Width || endY > image.Height || startX < 0 || startY < 0;
//Don't draw if its out of bounds
if( coordinatesOutOfBounds )
{
Console.WriteLine( $"Coordinates:\nX: {startX} - {endX}\nY: {startY.ToString().PadLeft(4)} - {endY.ToString().PadLeft(4)}\n" );
continue;
}
if( draw )
Cv2.Rectangle( image, pt1: new Point( startX, startY ), pt2: new Point( endX, endY ), color: new Scalar(), thickness: -1 );
detectionRectangles.Add( new Rect( startX, startY, endX - startX, endY - startY ) );
}
}
}
}
return detectionRectangles.ToArray();
}
Этот код выведет любые координаты, выходящие за пределы.
Файлы:
CaffeModel
Prototxt
Изображение
Поскольку я не могу использовать изображения, используемые в производстве (конфиденциальная информация), я нашел другое изображение, которое также имеет эти координаты.
По сути, мой вопрос заключается в том, почему я получаю эти «недействительные» координаты из обнаружений, но другие действительные координаты находятся в правильном месте и во всем. Я чувствую, что делаю что-то не так и не должен получать эти обнаружения в противном случае.