Overlapped contours of moments

asked 2019-07-16 04:37:25 -0600

chibo gravatar image

I want to know why Contour[0] and Contour[1] are overlapped ?


  • Contour[0] - Area (M_00) = 18060.00 - Area OpenCV: 18060.00 - Length: 835.76
  • Contour[1] - Area (M_00) = 18051.00 - Area OpenCV: 18051.00 - Length: 833.42

bin

moments


import cv2 as cv
import numpy as np
import random as rng

def thresh_callback(val):
    threshold = val
    canny_output = cv.Canny(src_gray, threshold, threshold * 2)
    contours, _ = cv.findContours(
        canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

    # Get the moments
    mu = [None] * len(contours)
    for i, _ in enumerate(contours):
        mu[i] = cv.moments(contours[i])

    # Get the mass centers
    mc = [None]*len(contours)
    for i, _ in enumerate(contours):
        # add 1e-5 to avoid division by zero
        mc[i] = (mu[i]['m10'] / (mu[i]['m00'] + 1e-5),
                 mu[i]['m01'] / (mu[i]['m00'] + 1e-5))

    # Draw contours
    drawing = np.zeros(
        (canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)

    for i, _ in enumerate(contours):
        color = (rng.randint(0, 256), rng.randint(0, 256), rng.randint(0, 256))
        cv.drawContours(drawing, contours, i, color, 2)
        cv.circle(drawing, (int(mc[i][0]), int(mc[i][1])), 4, color, -1)

        font = cv.FONT_HERSHEY_SIMPLEX
        cv.putText(drawing, ' #' + str(i), (int(mc[i][0]), int(mc[i][1])), font,
                   1, (64, 64, 64), 2, cv.LINE_AA)

    cv.imshow('Contours', drawing)

    # Calculate the area with the moments 00 and compare with the result of the OpenCV function
    for i in range(len(contours)):
        print(' * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f' %
              (i, mu[i]['m00'], cv.contourArea(contours[i]), cv.arcLength(contours[i], True)))

    cv.imwrite(path[:4] + '_moments.png', drawing)


path = 'test.jpg'

src = cv.imread(path)
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
src_gray = cv.blur(src_gray, (3, 3))
source_window = 'Source'
cv.namedWindow(source_window)
cv.imshow(source_window, src)

max_thresh = 255
thresh = 100  # initial threshold
cv.createTrackbar('Canny Thresh:', source_window,
                  thresh, max_thresh, thresh_callback)
thresh_callback(thresh)
cv.waitKey()

It's not always like that, more complex examples are overlapped about 90% of the all contours.

edit retag flag offensive close merge delete