来自CaffeModel的检测超出了图像范围

时间:2019-06-14 08:27:36

标签: c# opencv caffe

我正在尝试制作一个程序,以检测和匿名处理ID卡之类的面孔。我将a python example I found转换为C#,并且在大多数示例中都可以正常工作。但是,某些图像会产生超出范围的检测。

复制步骤:

  1. 创建一个新的控制台项目。
  2. 添加nuget包:“ OpenCvSharp4.Windows”。
  3. 下载所需文件(此问题的底部)。
  4. 插入代码并将文件放在您在程序的调试文件夹中命名的文件夹中。

要复制的代码:

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
Image

由于我无法使用生产中使用的图像(对隐私敏感的信息),因此我发现了另外一个具有这些坐标的图像。

基本上,我的问题是为什么我要从检测中得到这些“无效”坐标,而其他有效坐标却在正确的地方,什么都在。我觉得我做错了,否则不应该得到这些检测。

1 个答案:

答案 0 :(得分:0)

是的,它有时会发生,但并非总是如此(就我而言),您应该先进行以下检查,然后再寻找其他东西:

if (startX < 0) {
    startX = 0;
}
if (startY < 0) {
    startY  = 0;
}
if (startX + (endX - startX ) > frame.cols) {
    endX = frame.cols;
}
if (startY + (endY - startY ) > frame.rows) {
    endY = frame.rows;
}

因此它将立即入站。

希望有帮助!