public static int Augmentate(ImageInfo imageInfo, AugmentationContext context, AugmentationOptions options) { var sb = new StringBuilder(); foreach (var a in imageInfo.Annotations) { if (context.Classes.ContainsKey(a.Label)) { sb.Append($"{context.Classes[a.Label]} {a.Cx.ConvertToString()} {a.Cy.ConvertToString()} {a.Width.ConvertToString()} {a.Height.ConvertToString()}"); sb.Append("\n"); } } var local = new LocalAnnotationContext { SourceAnnotationText = sb.ToString(), Image = imageInfo }; if (options.HasAugmentation == false && options.Cut == false && options.ResizeOriginal == false) { // Простое копирование var(imgName, lblName) = context.GetNextObjFileNames(); File.Copy(imageInfo.FilePath, imgName); File.WriteAllText(lblName, local.SourceAnnotationText); } else { var resize = new Func <AImage, AImage>(img => { if (img.Width > MAX_SIDE_LIMIT || img.Height > MAX_SIDE_LIMIT) { float scale = 1.0f; if (img.Width > img.Height) { scale = MAX_SIDE_LIMIT / img.Width; } else { scale = MAX_SIDE_LIMIT / img.Height; } img.Resize((int)(img.Width * scale), (int)(img.Height * scale)); img.SaveAsSource(); } return(img); }); var store = new Action <AImage, string>((ifac, ann) => { var(imgName, lblName) = context.GetNextAugFileNames(); ifac.Write(imgName); File.WriteAllText(lblName, ann); }); using (var factory = new AImage(imageInfo.FilePath)) { if (options.ResizeOriginal) { using (var original = resize(factory.Clone())) { // Save resized original image var(imgName, lblName) = context.GetNextObjFileNames(); original.Write(imgName); File.WriteAllText(lblName, local.SourceAnnotationText); ApplyAugmentations(original, local, context, options); } } else { using (var original = factory.Clone()) { // Save resized original image var(imgName, lblName) = context.GetNextObjFileNames(); original.Write(imgName); File.WriteAllText(lblName, local.SourceAnnotationText); ApplyAugmentations(original, local, context, options); } } if ((context.WithoutClass || local.Image.Annotations.Any()) && options.Cut && options.CutWidth > 0 && options.CutHeight > 0 && options.CutWidth < (factory.Width / 1.5) && options.CutHeight < (factory.Height / 1.5)) { foreach (var cropped in factory.Crop(local.Image.Annotations, options.CutWidth, options.CutHeight, options.CutOverlaps)) { using (cropped.Item1) { var sbCropped = new StringBuilder(); foreach (var cropped_annotation in cropped.Item2) { if (context.Classes.ContainsKey(cropped_annotation.Label)) { sbCropped.Append($"{context.Classes[cropped_annotation.Label]} {cropped_annotation.Cx.ConvertToString()} {cropped_annotation.Cy.ConvertToString()} {cropped_annotation.Width.ConvertToString()} {cropped_annotation.Height.ConvertToString()}"); sbCropped.Append("\n"); } } if (context.WithoutClass || sbCropped.Length > 0) // no augmentation for empty crops { var croppedContext = new LocalAnnotationContext { SourceAnnotationText = sbCropped.ToString(), Image = new ImageInfo(imageInfo.FilePath, imageInfo.TrainType, cropped.Item2) }; using (var croppedAndResized = resize(cropped.Item1)) { store(croppedAndResized, croppedContext.SourceAnnotationText); ApplyAugmentations(cropped.Item1, croppedContext, context, options); } } } } } } } return(context.Counter); }
private static void ApplyAugmentations(AImage factory, LocalAnnotationContext localContext, AugmentationContext context, AugmentationOptions options) { var boxes = new BBOXES(localContext.Image.Annotations.Where(a => context.Classes.ContainsKey(a.Label)), factory.Width, factory.Height); var store = new Action <AImage, string>((ifac, ann) => { var(imgName, lblName) = context.GetNextAugFileNames(); ifac.Write(imgName); File.WriteAllText(lblName, ann); }); var storeWithBB = new Action <AImage, BBOXES>((ifac, bb) => { var(imgName, lblName) = context.GetNextAugFileNames(); ifac.Write(imgName); File.WriteAllText(lblName, bb.ToString()); }); var app = new Action <AImage, Func <AImage, Action> >((img, gf) => { gf(img).Invoke(); store(img, localContext.SourceAnnotationText); img.Reset(); }); if (options.Blur) { app.Invoke(factory, im => im.Blur); } if (options.Grayscale) { app.Invoke(factory, im => im.Grayscale); } if (options.Moonlight) { app.Invoke(factory, im => im.Moonlight); } if (options.Noise) { app.Invoke(factory, im => im.Noise); } if (options.Sepia) { app.Invoke(factory, im => im.SepiaTone); } if (options.Charcoal) { app.Invoke(factory, im => im.Charcoal); } if (options.LinesNoise) { app.Invoke(factory, im => im.LineNoize); } if (options.Sin) { app.Invoke(factory, im => im.FSin); } if (options.Mirrors) { var horizontallAnn = new StringBuilder(); var verticalAnn = new StringBuilder(); localContext.Image.Annotations.Apply(a => { if (context.Classes.ContainsKey(a.Label)) { horizontallAnn.Append($"{context.Classes[a.Label]} {(1.0f - a.Cx).ConvertToString()} {a.Cy.ConvertToString()} {a.Width.ConvertToString()} {a.Height.ConvertToString()}"); horizontallAnn.Append("\n"); verticalAnn.Append($"{context.Classes[a.Label]} {a.Cx.ConvertToString()} {(1 - a.Cy).ConvertToString()} {a.Width.ConvertToString()} {a.Height.ConvertToString()}"); verticalAnn.Append("\n"); } }); factory.Flop(); store(factory, horizontallAnn.ToString()); factory.Reset(); factory.Flip(); store(factory, verticalAnn.ToString()); factory.Reset(); } if (options.BBoxBlur) { factory.BlurBoxes(boxes); storeWithBB(factory, boxes); factory.Reset(); } }
public static void Merge(MergeOptions options, Action <int> progress) { if (PrepareRootFolder(options.TargetFolder) == false) { return; } if (PrepareObjFolder(options.TargetFolder) == false) { return; } if (PrepareAugFolder(options.TargetFolder) == false) { return; } var objFolder = Path.Combine(options.TargetFolder, "obj"); var files = new List <string>(); var counter = 0; var classIndex = 0; var classes = new Dictionary <string, int>(); var classesNames = new Dictionary <string, int>(); var lastIndex = -1; foreach (var c in options.Classes.OrderBy(c => c.Index)) { if (c.Active) { if (lastIndex != -1 && lastIndex != c.Index) { classIndex++; } classes.Add(c.Name, classIndex); if (c.IsPriorityInIndex) { classesNames.Add(c.Name, classIndex); } lastIndex = c.Index; } } var augmentationContext = new AugmentationContext(counter, objFolder, files) { Classes = classes, WithoutClass = options.WithoutClass }; int image_progress = 0; foreach (var dataset in options.Datasets) { foreach (var image in dataset.Images) { try { if (options.WithoutClass == false) { if (!image.Annotations.Any(a => classes.ContainsKey(a.Label))) { continue; } } var imagePath = image.FilePath; if (File.Exists(imagePath) == false) { imagePath = Path.Combine(dataset.DatasetPath, "obj", Path.GetFileNameWithoutExtension(image.FilePath)); } if (File.Exists(imagePath) == false) { continue; } var sb = new StringBuilder(); foreach (var a in image.Annotations) { if (classes.ContainsKey(a.Label)) { sb.Append($"{classes[a.Label]} {a.Cx.ConvertToString()} {a.Cy.ConvertToString()} {a.Width.ConvertToString()} {a.Height.ConvertToString()}"); sb.Append("\n"); } } counter = Augmentator.Augmentate(image, augmentationContext, dataset.Augmentations); progress(image_progress); image_progress++; } catch (Exception ex) { Log.Error(ex, "[DatasetMerger.Merge] Augmentations"); } } } // Store sets int test_step = 10; var trainData = new StringBuilder(); var testData = new StringBuilder(); for (int i = 0; i < files.Count; i++) { if (i != 0 && i % test_step == 0) { testData.Append(files[i]); testData.Append("\n"); } else { trainData.Append(files[i]); trainData.Append("\n"); } } File.WriteAllLines(Path.Combine(options.TargetFolder, "obj.names"), classesNames.Select(pair => pair.Key)); File.WriteAllText(Path.Combine(options.TargetFolder, "train.txt"), trainData.ToString()); File.WriteAllText(Path.Combine(options.TargetFolder, "test.txt"), testData.ToString()); // Store data var dataInfo = new StringBuilder(); dataInfo.Append($"classes= {classesNames.Count}"); dataInfo.Append("\n"); dataInfo.Append($"train= train.txt"); dataInfo.Append("\n"); dataInfo.Append($"valid= test.txt"); dataInfo.Append("\n"); dataInfo.Append($"names= obj.names"); dataInfo.Append("\n"); dataInfo.Append($"backup= backup/"); File.WriteAllText(Path.Combine(options.TargetFolder, "obj.data"), dataInfo.ToString()); }