Conversation
|
@SMRayeed, could you please add a requirements file and README describing the process with these scripts in the folder? |
Added README for the BioREPO Detection Pipeline, detailing installation, usage, modules, and output structure.
egrace479
left a comment
There was a problem hiding this comment.
Assuming you don't want to rename the folder, the references to it need to be updated.
Otherwise, this looks fine.
There was a problem hiding this comment.
Pull request overview
Adds a new detection-pipeline/ package containing scripts and documentation for detecting beetles (Grounding DINO), colorpickers (Moondream), and scalebars (Moondream) from tray images, along with pinned-ish runtime dependencies.
Changes:
- Introduces three new detection runner scripts for beetles, colorpickers, and scalebars.
- Adds a pipeline README describing usage, SLURM chunking, inputs/outputs, and credential setup.
- Adds a
requirements.txtcapturing the Python dependencies for the pipeline.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| detection-pipeline/requirements.txt | Adds dependency list for running the detection scripts. |
| detection-pipeline/README.md | Documents pipeline purpose, setup, credentials, and how to run each module. |
| detection-pipeline/detection_scalebar.py | Implements Moondream-based scalebar detection with overlap/area filtering and resumable output. |
| detection-pipeline/detection_colorpicker.py | Implements Moondream-based colorpicker detection with overlap reconciliation and CSV logging. |
| detection-pipeline/detection_beetles.py | Implements Grounding DINO-based beetle detection, cropping, and results logging. |
Comments suppressed due to low confidence (1)
detection-pipeline/README.md:74
- The install instructions
cd BioREPO-Processingpoint to a directory that doesn’t exist in this repo. Update it to the actual subdirectory so the quickstart works copy/paste.
cd BioREPO-Processing
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| with open(csv_path, "w", newline="") as csvfile: | ||
| fieldnames = ["image_name", "plotted_image", "num_colorpickers", "colorpicker_coords", "verify"] | ||
| writer = csv.DictWriter(csvfile, fieldnames=fieldnames) | ||
| writer.writeheader() | ||
| writer.writerows(rows) | ||
|
|
| iou = calculate_iou(all_detected_boxes[0], all_detected_boxes[1]) | ||
| if iou >= 0.6: | ||
| merged_box = { | ||
| "x_min": int((all_detected_boxes[0]["x_min"] + all_detected_boxes[1]["x_min"]) / 2), | ||
| "y_min": int((all_detected_boxes[0]["y_min"] + all_detected_boxes[1]["y_min"]) / 2), | ||
| "x_max": int((all_detected_boxes[0]["x_max"] + all_detected_boxes[1]["x_max"]) / 2), | ||
| "y_max": int((all_detected_boxes[0]["y_max"] + all_detected_boxes[1]["y_max"]) / 2), | ||
| } | ||
| return [merged_box], False |
| self.processor = AutoProcessor.from_pretrained(model_id) | ||
| self.model = AutoModelForZeroShotObjectDetection.from_pretrained(model_id).to(self.device) | ||
|
|
||
| self.llava_processor, self.llava_model = self.setup_llava_model() |
| image = Image.open(image_path) | ||
| image.verify() | ||
| image = Image.open(image_path).convert("RGB") |
Co-authored-by: Elizabeth Campolongo <38985481+egrace479@users.noreply.github.com>
Co-authored-by: Elizabeth Campolongo <38985481+egrace479@users.noreply.github.com>
|
@egrace479 based on the remarks of the Copilot, I revisited the codebase and found the issues for the detection_beetles.py script and fixed. Also, updated the csv-logging part for colorpicker and scalebar as suggested. |
There was a problem hiding this comment.
🟡 Changes recommended
Detection and resume logic can produce duplicate or stale results, misclassify outputs, and lose processing progress.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
Suppressed comments (7)
Previously missed (7) — in code that hasn't changed since the last review.
detection-pipeline/detection_beetles.py:215
- Containment is only tested when the lower-scored current box is smaller than the kept box. If the higher-scored box is the smaller nested one, the later enclosing box is retained and the same beetle is counted twice. Determine the smaller box independently of score before applying the containment test.
detection-pipeline/detection_beetles.py:329 - Input discovery is recursive, but output filenames use only the basename. Two source subdirectories containing the same filename will share a crop directory and plotted filename, overwrite each other's artifacts, and produce indistinguishable CSV records. Preserve an encoded relative path or pass the input root into
Detectionto derive a unique name.
detection-pipeline/detection_beetles.py:331 - For a
-and-image, this same image-level ground-truth count is assigned to bothtray1andtray2, so both per-tray CSV records have an incorrectactualvalue. Either provide per-half metadata or emit one aggregate record whose detected count sums both halves.
detection-pipeline/detection_beetles.py:359 - This reuses an existing crop directory without removing crops from an earlier run. If a rerun finds fewer beetles, higher-numbered old PNGs remain and downstream consumers see stale specimens that are absent from the new CSV. Clear generated crops for this tray before writing the new set.
detection-pipeline/detection_beetles.py:412 - Because image discovery includes every recursive image, placing
--output-dirunder--image-dirmakes a rerun ingest previously generated crops and plotted trays as new inputs, causing output growth and incorrect records. Reject nested output directories or explicitly prune the output subtree.
detection-pipeline/detection_colorpicker.py:125 - If
--output_diris inside--image_dir, the recursive walk includes generatedPlotted_Good/Plotted_Recheckimages on subsequent runs. Those images receive new flattened names and trigger additional API calls and outputs each rerun. Reject this layout or prune the output subtree during discovery.
detection-pipeline/detection_scalebar.py:130 - If
--output_diris inside--image_dir, the recursive walk includes generatedPlotted_Good/Plotted_Recheckimages on subsequent runs. Those images receive new flattened names and trigger additional API calls and outputs each rerun. Reject this layout or prune the output subtree during discovery.
- Files reviewed: 5/5 changed files
- Comments generated: 8
- Review effort level: Balanced
| if self.compute_containment_ratio(cand['box'], kept['box']) > 0.6: | ||
| duplicate = True | ||
| break |
| for detection in all_kept_boxes: | ||
| draw.rectangle(detection['box'], outline="red", width=4) | ||
|
|
||
| target_dir = recheck_dir if llava_flag else good_dir |
| count_df = pd.DataFrame(count_records) | ||
| count_df.to_csv(csv_path, index=False) |
| target_dir = recheck_dir if recheck_flag else good_dir | ||
| plotted_image_path = os.path.join(target_dir, base_name) | ||
| image.save(plotted_image_path) |
| target_dir = recheck_dir if recheck_flag else good_dir | ||
| plotted_image_path = os.path.join(target_dir, base_name) | ||
| image.save(plotted_image_path) |
| - **Zero-shot specimen detection** with `IDEA-Research/grounding-dino-base` and an | ||
| **adaptive confidence sweep** (0.30 → 0.10) that stops at the first threshold | ||
| yielding valid boxes — maximizing recall on faint specimens without flooding | ||
| dense trays with noise. |
| > ℹ️ A LLaVA-Next model (`llava-v1.6-mistral-7b-hf`) is loaded for optional | ||
| > conditional-generation use but is **not invoked in the current detection loop**. | ||
| > If you don't need it, commenting out `setup_llava_model()` saves considerable | ||
| > GPU memory. |
| └── plotted_trays/ | ||
| └── <tray_name>.png # full tray with red bounding boxes |
I have added the updated scripts for detecting individual beetles, colorpickers, and scalebars.