Group or select contours based on location in the image

asked 2018-01-25 18:39:03 -0600

dkeidel gravatar image

I have an input image that looks like the following:


I then detect contours and draw them on the image using the following code:

def computeImageGradient(gray_image):

    scale = 1
    delta = 0
    ddepth = cv2.CV_16S

    # compute Sobel
    grad_x = cv2.Sobel(gray_image, ddepth, 1, 0, ksize=-1, scale=scale, delta=delta, borderType=cv2.BORDER_DEFAULT)
    grad_y = cv2.Sobel(gray_image, ddepth, 0, 1, ksize=-1, scale=scale, delta=delta, borderType=cv2.BORDER_DEFAULT)

    abs_grad_x = cv2.convertScaleAbs(grad_x)
    abs_grad_y = cv2.convertScaleAbs(grad_y)

    # try to approximate the gradient by adding both directional gradients (note that this is not an
    # exact calculation at all! but it is good for our purposes)
    # dst = cv2.addWeighted(sobelx_8u, 0.5, sobely_8u, 0.5, 0)
    dst_weighted = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)

    return dst_weighted

# compute image gradient
image_gradient = computeImageGradient(template_result)
# apply threshold before detecting contours
ret_cropped_gray_image, thresh_cropped_gray_image = cv2.threshold(image_gradient, 127, 255, 0)
image_cropped_contoured, contours_cropped, hierarchy_cropped = \
cv2.findContours(thresh_cropped_gray_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# draw on contours
image_cropped_contoured_drawn = cv2.drawContours(template_result_color, contours_cropped, -1, (0, 255, 0), 3)
# write out cropped coutour image
writeImage(imagePath, image_cropped_contoured_drawn, "_template_masked_contoured", args["output"])

The output image looks like this:


My question and what I need some guidance on, is how do I select contours based on region in the image. Let me explain my request a little more. I am not interested in the contours that are found all around the outside of the image. These are not useful in my analysis. I am interested in the contours detect inside that noisy area. Another example would be the glare from the light on the right hand side of the image that is being detected as a large contour. Is there a way to separate them out in a programmatic way? You can see that I am detecting edges using Sobel image gradients. Also, I do not want to blur or preprocess the image too much since I still want to detect the details in the interior of the image.

Thank you very much for any and all suggestions.

edit retag flag offensive close merge delete