예제 #1
0
        public static void SaveFromTemplate(YoloProject project)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }
            if (project.ObjData == null)
            {
                throw new ArgumentException($"{nameof(project)}.{nameof(project.ObjData)} cannot be null", nameof(project));
            }

            var objData = project.ObjData;

            int classes = GetClassCount(project);

            string objDataTemplate = File.ReadAllText(Path.Combine("darknet", "obj.data.template"));
            string objDataText     = objDataTemplate
                                     .Replace("%classes%", classes.ToString())
                                     .Replace("%train%", objData.Train)
                                     .Replace("%valid%", objData.Valid)
                                     .Replace("%names%", objData.Names)
                                     .Replace("%backup%", objData.Backup);

            // make sure backup folder exists
            var baseDir      = Path.GetDirectoryName(project.DarknetExecutableFilePath);
            var backupFolder = Path.Combine(baseDir, objData.Backup);

            Directory.CreateDirectory(backupFolder);

            File.WriteAllText(project.ObjectDataFilePath, objDataText);

            UpdateTrainList(project);
        }
예제 #2
0
        public static int GetClassCount(YoloProject project)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }
            if (project.ObjData == null)
            {
                throw new ArgumentException($"{nameof(project)}.{nameof(project.ObjData)} cannot be null", nameof(project));
            }

            var objData = project.ObjData;

            var baseDir       = Path.GetDirectoryName(project.DarknetExecutableFilePath);
            var namesFileName = Path.Combine(baseDir, objData.Names);

            int classes = 0;

            if (File.Exists(namesFileName))
            {
                classes = File.ReadAllLines(namesFileName).Length;
            }

            return(classes);
        }
예제 #3
0
        public static int GetTrainImageCount(YoloProject project)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }
            if (project.ObjData == null)
            {
                throw new ArgumentException($"{nameof(project)}.{nameof(project.ObjData)} cannot be null", nameof(project));
            }

            var objData = project.ObjData;

            var baseDir       = Path.GetDirectoryName(project.DarknetExecutableFilePath);
            var trainFileName = Path.Combine(baseDir, objData.Train);

            if (!File.Exists(trainFileName))
            {
                return(0);
            }

            return(File.ReadAllLines(trainFileName).Length);
        }
예제 #4
0
        public static void UpdateTrainList(YoloProject project)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }
            if (project.ObjData == null)
            {
                throw new ArgumentException($"{nameof(project)}.{nameof(project.ObjData)} cannot be null", nameof(project));
            }

            var objData = project.ObjData;

            var baseDir = Path.GetDirectoryName(project.DarknetExecutableFilePath);

            // update train/valid files
            var imgsDirectory = Path.Combine(baseDir, project.ImagesDirectory);

            Directory.CreateDirectory(imgsDirectory);
            var txtFiles = Directory.GetFiles(imgsDirectory, "*.txt", SearchOption.AllDirectories);
            var sb       = new StringBuilder();

            foreach (var txtFile in txtFiles)
            {
                var jpgFile = Path.Combine(Path.GetDirectoryName(txtFile), Path.GetFileNameWithoutExtension(txtFile)) + ".jpg";
                if (!File.Exists(jpgFile))
                {
                    continue;
                }

                sb.AppendLine(jpgFile.Substring(baseDir.Length + 1).Replace('\\', '/'));
            }
            File.WriteAllText(Path.Combine(baseDir, objData.Train), sb.ToString());
            // TODO (judwhite): separate validation file
            File.WriteAllText(Path.Combine(baseDir, objData.Valid), sb.ToString());
        }
예제 #5
0
        public static void SaveFromTemplate(YoloProject project, string anchors)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }
            if (project.ObjData == null)
            {
                throw new ArgumentException($"{nameof(project)}.{nameof(project.TrainConfig)} cannot be null", nameof(project));
            }

            var cfg = project.TrainConfig;

            var baseDir = Path.GetDirectoryName(project.DarknetExecutableFilePath);

            if (string.IsNullOrWhiteSpace(anchors) && ObjectDataConfig.GetTrainImageCount(project) > 0)
            {
                try
                {
                    // ensure we don't read stale values
                    var anchorsFileName = Path.Combine(baseDir, "anchors.txt");
                    if (File.Exists(anchorsFileName))
                    {
                        File.Delete(anchorsFileName);
                    }

                    // calculate anchors
                    var pinfo = new ProcessStartInfo();
                    pinfo.FileName         = project.DarknetExecutableFilePath;
                    pinfo.Arguments        = $"detector calc_anchors {project.ObjectDataFilePath} -num_of_clusters 9 -width {cfg.Width} -heigh {cfg.Height}";
                    pinfo.WorkingDirectory = baseDir;
                    pinfo.ErrorDialog      = true;
                    pinfo.UseShellExecute  = false;
                    Process.Start(pinfo).WaitForExit();

                    // read from anchors.txt
                    var parts = File.ReadAllText(anchorsFileName)
                                .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                    // convert doubles to ints
                    var sb = new StringBuilder();
                    foreach (var part in parts)
                    {
                        if (sb.Length != 0)
                        {
                            sb.Append(",  ");
                        }

                        var coords = part.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < coords.Length; i++)
                        {
                            if (i != 0)
                            {
                                sb.Append(',');
                            }
                            var coord = double.Parse(coords[i]);
                            sb.Append((int)Math.Round(coord, MidpointRounding.AwayFromZero));
                        }
                    }

                    anchors = sb.ToString();
                }
                catch
                {
                }
            }

            if (string.IsNullOrWhiteSpace(anchors))
            {
                anchors = "10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326";
            }

            int classes = ObjectDataConfig.GetClassCount(project);
            int filters = (classes + 5) * 3;

            string yoloTemplate = File.ReadAllText(Path.Combine("darknet", "yolov3.cfg.template"));
            string yoloCfg      = yoloTemplate
                                  .Replace("%batch%", cfg.BatchSize.ToString())
                                  .Replace("%subdivisions%", cfg.Subdivisions.ToString())
                                  .Replace("%width%", cfg.Width.ToString())
                                  .Replace("%height%", cfg.Height.ToString())
                                  .Replace("%filters%", filters.ToString())
                                  .Replace("%classes%", classes.ToString())
                                  .Replace("%anchors%", anchors)
                                  .Replace("%random%", cfg.Random ? "1" : "0")
                                  .Replace("%max%", cfg.Max.ToString());

            Directory.CreateDirectory(Path.GetDirectoryName(project.YoloConfigFilePath));
            File.WriteAllText(project.YoloConfigFilePath, yoloCfg);
        }