我正在尝试制作一个程序,以检测和匿名处理ID卡之类的面孔。我将a python example I found转换为C#,并且在大多数示例中都可以正常工作。但是,某些图像会产生超出范围的检测。
复制步骤:
要复制的代码:
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
由于我无法使用生产中使用的图像(对隐私敏感的信息),因此我发现了另外一个具有这些坐标的图像。
基本上,我的问题是为什么我要从检测中得到这些“无效”坐标,而其他有效坐标却在正确的地方,什么都在。我觉得我做错了,否则不应该得到这些检测。
答案 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;
}
因此它将立即入站。
希望有帮助!