static void Main(string[] args) { FolderBrowserDialog fbd = new FolderBrowserDialog(); string allImagesTesting = ""; if (fbd.ShowDialog() == DialogResult.OK) { allImagesTesting = fbd.SelectedPath; } string protoTxtPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "deploy.prototxt"); string mdlBinPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "resnet_50_1by2_nsfw.caffemodel"); var classifier = new ImageClassifier(protoTxtPath, mdlBinPath); Console.WriteLine("Loaded classifier."); Console.WriteLine("Classifier has cutoff of {0}.", classifier.Cutoff); /* * string badImagesTesting = @"E:\img_malas"; * string goodImagesTesting = @"E:\img_buenas"; * string allImagesTesting = @"G:\Temp\$Temp\pics"; */ //string allImagesTesting = @"G:\Temp\$Temp\pics"; //classifier.Cutoff = 0.15; //var badImgs = Directory.GetFiles(badImagesTesting).ToList(); //var goodImgs = Directory.GetFiles(goodImagesTesting).ToList(); //Esto lista todas las .jpg en la carpeta seleccionada y todas sus subcarpetas var allImgs = Directory.GetFiles(allImagesTesting, "*.jpg", SearchOption.AllDirectories).ToList(); var total = allImgs.Count; //Creo subcarpeta para mover los falsos negativos Directory.CreateDirectory(Path.Combine(allImagesTesting, "wrong")); // Cut down our test base so it's not so huge. /* * var min = Math.Min(badImgs.Count, goodImgs.Count); * * if(min > 1000) * { * min = 1000; * } * * badImgs = badImgs.GetRange(0, min); * goodImgs = goodImgs.GetRange(0, min); * * * // Shuffle things up a bit. * Random r = new Random(); * badImgs = badImgs.OrderBy(x => r.Next()).ToList(); * goodImgs = goodImgs.OrderBy(x => r.Next()).ToList(); */ int goodRight = 0, goodWrong = 0, badRight = 0, badWrong = 0; var sw = new Stopwatch(); sw.Start(); foreach (var img in allImgs) { var imgData = File.ReadAllBytes(img); if (classifier.ClassifyImage(imgData)) { ++badRight; } else { // If you feel like inspecting false negatives. var outPath = Path.Combine(allImagesTesting, "wrong", Path.GetFileName(img)); //File.Move(img, outPath); File.Copy(img, outPath); ++badWrong; } //Publica avance cada 10 imágenes procesadas if ((badRight + badWrong) % 10 == 0) { Console.WriteLine("Classified {0} of {1} bad images.", badRight + badWrong, total); } } /* * * foreach(var img in badImgs) * { * var imgData = File.ReadAllBytes(img); * * if(classifier.ClassifyImage(imgData)) * { ++badRight; * } * else * { * // If you feel like inspecting false negatives. * // var outPath = Path.Combine(SOME_BASE_PATH_FOR_FALSE_NEGATIVES, Path.GetFileName(img)); * // File.Move(img, outPath); * var outPath = Path.Combine(badImagesTesting,"wrong", Path.GetFileName(img)); * File.Move(img, outPath); ++badWrong; * } * * if((badRight + badWrong) % 10 == 0) * { * Console.WriteLine("Classified {0} of {1} bad images.", badRight + badWrong, min); * } * } * * foreach(var img in goodImgs) * { * var imgData = File.ReadAllBytes(img); * * if(classifier.ClassifyImage(imgData)) * { ++goodWrong; * } * else * { ++goodRight; * } * * if((goodWrong + goodRight) % 10 == 0) * { * Console.WriteLine("Classified {0} of {1} good images.", goodWrong + goodRight, min); * } * } * */ sw.Stop(); Console.WriteLine("Classified pornographic images with an accuracy of {0}%.", 100d * ((double)badRight / (double)(badRight + badWrong))); Console.WriteLine("Classified non-pornographic images with an accuracy of {0}%.", 100d * ((double)goodRight / (double)(goodRight + goodWrong))); //Console.WriteLine("Took an average of {0} msec per image to classify.", sw.ElapsedMilliseconds / (double)(min * 2)); Console.WriteLine("Took an average of {0} msec per image to classify.", sw.ElapsedMilliseconds / (double)(total)); Console.ReadLine(); //Pausa para que no cierre consola }
private static void TestClassifier(ImageClassifier classifier, ClassifierType type, bool verbose = false) { Console.WriteLine("{0} classifier has cutoff of {1}.", type, classifier.Cutoff); string badImagesTesting = @"SOME BAD STUFF BRO"; string goodImagesTesting = @"SOME GOOD STUFF KIDDO"; var badImgs = Directory.GetFiles(badImagesTesting, "*.jpg", SearchOption.AllDirectories).ToList(); var goodImgs = Directory.GetFiles(goodImagesTesting, "*.jpg", SearchOption.AllDirectories).ToList(); // Cut down our test base so it's not so huge. var min = Math.Min(badImgs.Count, goodImgs.Count); if (min > 1000) { min = 1000; } Console.WriteLine("Testing against a total of {0} images, {1} from each class.", min * 2, min); badImgs = badImgs.GetRange(0, min); goodImgs = goodImgs.GetRange(0, min); // Shuffle things up a bit. Random r = new Random(); badImgs = badImgs.OrderBy(x => r.Next()).ToList(); goodImgs = goodImgs.OrderBy(x => r.Next()).ToList(); int goodRight = 0, goodWrong = 0, badRight = 0, badWrong = 0; var sw = new Stopwatch(); sw.Start(); foreach (var img in badImgs) { var imgData = File.ReadAllBytes(img); if (classifier.ClassifyImage(imgData)) { ++badRight; } else { // If you feel like inspecting false negatives. //var outPath = Path.Combine(SOME PLACE FOR FALSE NEGATIVES, Path.GetFileName(img)); //File.Move(img, outPath); ++badWrong; } if (verbose && (badRight + badWrong) % 10 == 0) { Console.WriteLine("Classified {0} of {1} bad images.", badRight + badWrong, min); } } foreach (var img in goodImgs) { var imgData = File.ReadAllBytes(img); if (classifier.ClassifyImage(imgData)) { ++goodWrong; } else { ++goodRight; } if (verbose && (goodWrong + goodRight) % 10 == 0) { Console.WriteLine("Classified {0} of {1} good images.", goodWrong + goodRight, min); } } sw.Stop(); Console.WriteLine("Classifier with type {0} classified pornographic images with an accuracy of {1}%.", type, 100d * ((double)badRight / (double)(badRight + badWrong))); Console.WriteLine("Classifier with type {0} classified non-pornographic images with an accuracy of {1}%.", type, 100d * ((double)goodRight / (double)(goodRight + goodWrong))); Console.WriteLine("Classifier with type {0} took an average of {1} msec per image to classify.", type, sw.ElapsedMilliseconds / (double)(min * 2)); }
private static void RunClassifier(ImageClassifier classifier, string ClassifierPath, bool classifyPorn = true, bool verbose = false, bool copyWrongs = false, string wrongsPath = "", double cutoff = 0) { //cutoff = 2 --> usar default if (cutoff != 2) { classifier.Cutoff = cutoff; } Console.WriteLine("Classifier has cutoff of {0}.", classifier.Cutoff); //REVISAR falla al encontrar directorios con acceso denegado (ej. SVI ó RECYCLE.BIN) // Y es lento para grandes tamaños, ver exploración recursiva y EnumerateFiles en su lugar //var allImgs = Directory.GetFiles(ClassifierPath, "*.jpg", SearchOption.AllDirectories).ToList(); //var allImgs = Directory.GetFiles(ClassifierPath, "*.png", SearchOption.AllDirectories).ToList(); //var allImgs = Directory.GetFiles(ClassifierPath, "*.jpg").ToList(); var allImgs = Directory.GetFiles(ClassifierPath).ToList(); var total = allImgs.Count; bool tPorn = classifyPorn; Console.WriteLine("{0} imágenes a clasificar.", total); int imgRight = 0, imgWrong = 0; var sw = new Stopwatch(); sw.Start(); foreach (var img in allImgs) { var imgData = File.ReadAllBytes(img); var outPath = Path.Combine(wrongsPath, Path.GetFileName(img)); //var outPath = Path.Combine(@"D:\img_wrong", Path.GetFileName(img).Replace(".png", "_" + ctStr + score.ToString("F6") + ".png")); //Path.Combine(img, "wrong", Path.GetFileName(img)); try { if (classifier.ClassifyImage(imgData)) { if (tPorn) { ++imgRight; } else { ++imgWrong; if (copyWrongs) { File.Copy(img, outPath); } } } else { // If you feel like inspecting false negatives. //var outPath = Path.Combine(SOME PLACE FOR FALSE NEGATIVES, Path.GetFileName(img)); //File.Move(img, outPath); //var outPath = Path.Combine(img, "wrong", Path.GetFileName(img)); //File.Copy(img, outPath); if (tPorn) { ++imgWrong; //if (verbose) Console.WriteLine("score: {0}", classifier.GetPositiveProbability(imgData)); if (copyWrongs) { File.Copy(img, outPath); } } else { ++imgRight; } } if (verbose && (imgRight + imgWrong) % 100 == 0) { if (tPorn) { Console.WriteLine("Classified {0} of {1} pornographic images.", imgRight + imgWrong, total); } else { Console.WriteLine("Classified {0} of {1} non-pornographic images.", imgRight + imgWrong, total); } } //Console.WriteLine("score: {0}", score); } catch (Exception e) { // Extract some information from this exception, and then // throw it to the parent method. if (e.Source != null) { Console.WriteLine("Exception source: {0}", e.Source); } throw; } } sw.Stop(); if (tPorn) { Console.WriteLine("Classified {0} pornographic images with an accuracy of {1}%.", imgRight + imgWrong, 100d * ((double)imgRight / (double)(imgRight + imgWrong))); } else { Console.WriteLine("Classified {0} non-pornographic images with an accuracy of {1}%.", imgRight + imgWrong, 100d * ((double)imgRight / (double)(imgRight + imgWrong))); } Console.WriteLine("Classifier took an average of {0} msec per image to classify.", sw.ElapsedMilliseconds / (double)(total * 2)); }
static void Main(string[] args) { string protoTxtPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "deploy.prototxt"); string mdlBinPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "resnet_50_1by2_nsfw.caffemodel"); var classifier = new ImageClassifier(protoTxtPath, mdlBinPath); Console.WriteLine("Loaded classifier."); Console.WriteLine("Classifier has cutoff of {0}.", classifier.Cutoff); //string badImagesTesting = PATH_TO_BAD_IMAGES; //string goodImagesTesting = PATH_TO_GOOD_IMAGES; string badImagesTesting = @"E:\img_malas"; string goodImagesTesting = @"E:\img_malas"; var badImgs = Directory.GetFiles(badImagesTesting).ToList(); var goodImgs = Directory.GetFiles(goodImagesTesting).ToList(); // Cut down our test base so it's not so huge. var min = Math.Min(badImgs.Count, goodImgs.Count); if (min > 1000) { min = 1000; } badImgs = badImgs.GetRange(0, min); goodImgs = goodImgs.GetRange(0, min); // Shuffle things up a bit. Random r = new Random(); badImgs = badImgs.OrderBy(x => r.Next()).ToList(); goodImgs = goodImgs.OrderBy(x => r.Next()).ToList(); int goodRight = 0, goodWrong = 0, badRight = 0, badWrong = 0; var sw = new Stopwatch(); sw.Start(); foreach (var img in badImgs) { var imgData = File.ReadAllBytes(img); if (classifier.ClassifyImage(imgData)) { ++badRight; } else { // If you feel like inspecting false negatives. // var outPath = Path.Combine(SOME_BASE_PATH_FOR_FALSE_NEGATIVES, Path.GetFileName(img)); // File.Move(img, outPath); ++badWrong; } if ((badRight + badWrong) % 10 == 0) { Console.WriteLine("Classified {0} of {1} bad images.", badRight + badWrong, min); } } foreach (var img in goodImgs) { var imgData = File.ReadAllBytes(img); if (classifier.ClassifyImage(imgData)) { ++goodWrong; } else { ++goodRight; } if ((goodWrong + goodRight) % 10 == 0) { Console.WriteLine("Classified {0} of {1} good images.", goodWrong + goodRight, min); } } sw.Stop(); Console.WriteLine("Classified pornographic images with an accuracy of {0}%.", 100d * ((double)badRight / (double)(badRight + badWrong))); Console.WriteLine("Classified non-pornographic images with an accuracy of {0}%.", 100d * ((double)goodRight / (double)(goodRight + goodWrong))); Console.WriteLine("Took an average of {0} msec per image to classify.", sw.ElapsedMilliseconds / (double)(min * 2)); //Console.WriteLine("min = {0}", min); Console.ReadLine(); }