[Python] More robust image processing for finding parts in camera view using OpenCV? [closed]

Discussão em 'Python' iniciado por Stack, Abril 5, 2025.

  1. Stack

    Stack Membro Participativo

    I'm trying to count parts in a tray. They are distinctly black against a cardboard colored box, so what I've done so far is look at the histogram and computed a binary image based on a percentage from the darkest pixel value, and then used morphology and blob analysis to count the number of parts.

    It works pretty well, even in changing lighting conditions, but the problem I have is if the parts are on the edge of the camera view, they are overlapping which messes up the blob analysis.

    The image below shows the 2 scenarios:

    • Left is the binary and morph image when the parts are directly underneath the camera
    • Right is the binary and morph image when the parts are at the edge of the camera view

    2 image scenarios

    Any smart way that I could fix this? I am open for all kinds of suggestions, even if I have to shy away from classical opencv image processing and perhaps take on neural network classification.

    def preprocess_inspection(img):
    if len(img.shape) == 3:
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    else:
    gray = img

    hist = cv2.calcHist([gray], [0], None, [256], [0, 256])

    cdf = hist.cumsum()

    cdf_normalized = cdf / cdf[-1]

    median_intensity = np.argmax(cdf_normalized >= 0.5) # intensity where 50% of pixels are below

    contrast = np.std(gray)

    if contrast < 30:
    percentage = 0.2
    elif contrast < 60:
    percentage = 0.15
    else:
    percentage = 0.1

    if median_intensity < 128:
    percentage = max(percentage, 0.1)

    min_val, max_val, _, _ = cv2.minMaxLoc(gray)
    _, thresh = cv2.threshold(gray, min_val + (max_val - min_val) * percentage, 255, 0) # % from min

    return thresh

    def apply_morphology(img):
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
    # NOTE: Image is inverted, so the operations are reversed, i.e. erode instead of dilate, etc.
    img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations=8)
    img = cv2.dilate(img, kernel, iterations=2)
    return img

    Continue reading...

Compartilhe esta Página