基于传统机器视觉的水螅与卤虾区分技术问询:无需机器学习的高密度同色大小目标框选方案
findContours to Distinguish Hydras from Brine Shrimp Absolutely, OpenCV's findContours is exactly the tool you need here—no machine learning required, and it fits perfectly with your existing pipeline. Since you only care about identifying plump, healthy hydras (and are okay with missing the slender ones), we can filter contours based on size (area or bounding box dimensions), which is a straightforward way to separate the larger hydras from tiny brine shrimp and residual artifacts.
Step-by-Step Adaptation to Your Code
First, let's optimize your mask-combining step (your nested loops work, but OpenCV's bitwise operations are way faster and cleaner). Then we'll add contour detection and filtering.
Modified Full Code
import cv2 import os import numpy as np path = os.getcwd() + "/hydra_sample_imgs/00054.jpg" img = cv2.imread(path) c_img = cv2.imread(path) #==============GEOMETRY MASKS=================== ww, hh = img.shape[:2] r = 173 xc = hh // 2 yc = ww // 2 # Create white circle on black background for mask cv2.circle(c_img, (xc - 10, yc + 2), r, (255, 255, 255), -1) hsv_cir = cv2.cvtColor(c_img, cv2.COLOR_BGR2HSV) l_w = np.array([0,0,0]) h_w = np.array([0,0,255]) result_mask = cv2.inRange(hsv_cir, l_w, h_w) #===============COLOR MASKS==================== hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # Orange HSV thresholds (adjusted slightly from your original) l_orange = np.array([7, 66, 125]) h_orange = np.array([19, 255, 240]) orange_mask = cv2.inRange(hsv_img, l_orange, h_orange) #===============COMBINE MASKS (OPTIMIZED)==================== # Replace nested loops with bitwise AND for efficiency result_mask = cv2.bitwise_and(result_mask, orange_mask) # Optional: Light morphological cleanup to remove tiny artifacts (adjust kernel size as needed) # kernel = np.ones((2,2), np.uint8) # result_mask = cv2.morphologyEx(result_mask, cv2.MORPH_OPEN, kernel) #===============DETECT AND MARK HYDRA==================== # Find contours in the combined mask contours, _ = cv2.findContours(result_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Create a copy of the original image to draw on output_img = img.copy() # Define a minimum area threshold (adjust this based on your images!) # Start with a value like 200, then tweak until you only get plump hydras MIN_HYDRA_AREA = 200 for contour in contours: # Calculate the area of each contour area = cv2.contourArea(contour) # Only keep contours above the minimum area if area > MIN_HYDRA_AREA: # Get the bounding rectangle for the contour x, y, w, h = cv2.boundingRect(contour) # Draw a green rectangle around the hydra cv2.rectangle(output_img, (x, y), (x + w, y + h), (0, 255, 0), 2) # Optional: Draw the contour itself # cv2.drawContours(output_img, [contour], -1, (0, 0, 255), 2) # Show the result cv2.imshow('Original Image', img) cv2.imshow('Masked Image', cv2.bitwise_and(img, img, mask=result_mask)) cv2.imshow('Hydras Detected', output_img) cv2.waitKey(0) cv2.destroyAllWindows()
Key Details to Adjust
- MIN_HYDRA_AREA: This is the most important parameter. Start with a value like 200, then test with your images—increase it if you still see brine shrimp, decrease it if you're missing too many plump hydras. Since you're okay with losing slender hydras, err on the side of a higher threshold.
- Morphological Cleanup: The optional
morphologyExstep uses an opening operation (erosion followed by dilation) to remove tiny white speckles (artifacts) without affecting larger contours. If your mask already has very few artifacts, you can skip this. If you do use it, adjust the kernel size (e.g.,(3,3)for stronger cleanup) based on your needs. - Contour Retrieval Mode: We use
cv2.RETR_EXTERNALto only get the outermost contours, which avoids detecting inner holes or nested structures (if any) in the hydras.cv2.CHAIN_APPROX_SIMPLEcompresses the contour points to save memory, which is fine for drawing bounding boxes.
Why This Works
Hydras are significantly larger than brine shrimp, so their contour areas will be much bigger. By filtering out all contours below a certain size, you can reliably isolate the plump, healthy hydras you care about—all without needing training data or ML models.
内容的提问来源于stack exchange,提问作者Johann Pally

