/// <summary> /// Writes a csv file containing fish species and frame numbers. /// </summary> /// <param name="count_path">Path to model file.</param> /// <param name="out_path">Path to output csv file.</param> /// <param name="roi">Region of interest, needed for image dims.</param> /// <param name="detections">Detections for each frame.</param> /// <param name="scores">Cover and species scores for each detection.</param> static void WriteCounts( string count_path, string out_path, Rect roi, VectorVectorDetection detections, VectorVectorClassification scores) { // Create and initialize keyframe finder. KeyframeFinder finder = new KeyframeFinder(); ErrorCode status = finder.Init(count_path, roi[2], roi[3]); if (status != ErrorCode.kSuccess) { throw new Exception("Failed to initialize keyframe finder!"); } // Process keyframe finder. VectorInt keyframes = new VectorInt(); status = finder.Process(scores, detections, keyframes); if (status != ErrorCode.kSuccess) { throw new Exception("Failed to process keyframe finder!"); } // Write the keyframes out. using (var csv = new System.IO.StreamWriter(out_path)) { csv.WriteLine("id,frame,species_index"); int id = 0; foreach (var i in keyframes) { Classification c = scores[i][0]; float max_score = 0.0F; int species_index = 0; for (int j = 0; j < c.species.Count; ++j) { if (c.species[j] > max_score) { max_score = c.species[j]; species_index = j; } } var line = string.Format("{0},{1},{2}", id, i, species_index); csv.WriteLine(line); id++; } } }
/// <summary> /// Writes a new video with bounding boxes around detections. /// </summary> /// <param name="vid_path">Path to the original video.</param> /// <param name="out_path">Path to the output video.</param> /// <param name="roi">Region of interest output from FindVideoRoi.</param> /// <param name="endpoints">Transform output from FindVideoRoi.</param> /// <param name="detections">Detections for each frame.</param> /// <param name="scores">Cover and species scores for each detection.</param> static void WriteVideo( string vid_path, string out_path, Rect roi, PointPair endpoints, VectorVectorDetection detections, VectorVectorClassification scores) { // Initialize the video reader. VideoReader reader = new VideoReader(); ErrorCode status = reader.Init(vid_path); if (status != ErrorCode.kSuccess) { throw new Exception("Failed to read video!"); } // Initialize the video writer. VideoWriter writer = new VideoWriter(); status = writer.Init( out_path, reader.FrameRate(), Codec.kWmv2, new PairIntInt(reader.Width(), reader.Height())); if (status != ErrorCode.kSuccess) { throw new Exception("Failed to write video!"); } // Iterate through frames. for (int i = 0; i < detections.Count; ++i) { Image frame = new Image(); status = reader.GetFrame(frame); if (status != ErrorCode.kSuccess) { throw new Exception("Error retrieving video frame!"); } Color blue = new Color(); blue[0] = 255; blue[1] = 0; blue[2] = 0; Color red = new Color(); red[0] = 0; red[1] = 0; red[2] = 255; Color green = new Color(); green[0] = 0; green[1] = 255; green[2] = 0; frame.DrawRect(roi, blue, 1, endpoints); for (int j = 0; j < detections[i].Count; ++j) { Color det_color = red; double clear = scores[i][j].cover[2]; double hand = scores[i][j].cover[1]; if (j == 0) { if (clear > hand) { det_color = green; } else { det_color = red; } } frame.DrawRect(detections[i][j].location, det_color, 2, endpoints, roi); } status = writer.AddFrame(frame); if (status != ErrorCode.kSuccess) { throw new Exception("Error adding frame to video!"); } } }
/// <summary> /// Finds and classifies detections for all frames in a video. /// </summary> /// <param name="detect_path">Path to detect model file.</param> /// <param name="classify_path">Path to classify model file.</param> /// <param name="roi">Region of interest output from FindVideoRoi.</param> /// <param name="endpoints">Ruler endpoints output from FindVideoRoi.</param> /// <param name="detections">Detections for each frame.</param> /// <param name="scores">Cover and species scores for each detection.</param> static void DetectAndClassify( string detect_path, string classify_path, string vid_path, Rect roi, PointPair endpoints, out VectorVectorDetection detections, out VectorVectorClassification scores) { // Determined by experimentation with GPU having 8GB memory. const int kMaxImg = 32; // Initialize the outputs. detections = new VectorVectorDetection(); scores = new VectorVectorClassification(); // Create and initialize the detector. Detector detector = new Detector(); ErrorCode status = detector.Init(detect_path, 0.5); if (status != ErrorCode.kSuccess) { throw new Exception("Failed to initialize detector!"); } // Create and initialize the classifier. Classifier classifier = new Classifier(); status = classifier.Init(classify_path, 0.5); if (status != ErrorCode.kSuccess) { throw new Exception("Failed to initialize classifier!"); } // Initialize the video reader. VideoReader reader = new VideoReader(); status = reader.Init(vid_path); if (status != ErrorCode.kSuccess) { throw new Exception("Failed to open video!"); } // Iterate through frames. bool vid_end = false; while (true) { // Find detections. VectorVectorDetection dets = new VectorVectorDetection(); VectorImage imgs = new VectorImage(); for (int i = 0; i < kMaxImg; ++i) { Image img = new Image(); status = reader.GetFrame(img); if (status != ErrorCode.kSuccess) { vid_end = true; break; } img = openem.Rectify(img, endpoints); img = openem.Crop(img, roi); imgs.Add(img); status = detector.AddImage(img); if (status != ErrorCode.kSuccess) { throw new Exception("Failed to add frame to detector!"); } } status = detector.Process(dets); if (status != ErrorCode.kSuccess) { throw new Exception("Failed to process detector!"); } for (int i = 0; i < dets.Count; ++i) { } detections.AddRange(dets); for (int i = 0; i < detections.Count; ++i) { } // Classify detections. for (int i = 0; i < dets.Count; ++i) { VectorClassification score_batch = new VectorClassification(); for (int j = 0; j < dets[i].Count; ++j) { Image det_img = openem.GetDetImage(imgs[i], dets[i][j].location); status = classifier.AddImage(det_img); if (status != ErrorCode.kSuccess) { throw new Exception("Failed to add frame to classifier!"); } } status = classifier.Process(score_batch); if (status != ErrorCode.kSuccess) { throw new Exception("Failed to process classifier!"); } scores.Add(score_batch); } if (vid_end) { break; } } }