# Detect the outer boundary of gray color inside an image and draw contour

**URL:** <https://forum.opencv.org/t/detect-the-outer-boundary-of-gray-color-inside-an-image-and-draw-contour/18679>\
**Category:** Python\
**Tags:** opencv-50\
**Created:** [September 5, 2024, 11:01am UTC](https://forum.opencv.org/t/detect-the-outer-boundary-of-gray-color-inside-an-image-and-draw-contour/18679 "2024-09-05T11:01:37Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![zeeshanbabar112](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/zeeshanbabar112/32/9854_2.png) [@zeeshanbabar112](https://forum.opencv.org/u/zeeshanbabar112)\
**Post date:** [September 5, 2024, 11:01am UTC](https://forum.opencv.org/t/detect-the-outer-boundary-of-gray-color-inside-an-image-and-draw-contour/18679/1 "2024-09-05T11:01:37Z")

</div>

![test_pillar](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/2/27813c6ab5b380b31ca1e8d58d37cb2dffaed85a.jpeg)  
i have attached my original image and then i attached way I want to detect the contour. I have tried many ways (canny edge, sobel filter, shape recognition) but nothing worked for me. I have tried to make tracker bars to set the value of thresholding and canny edge detection but no combination works.  
‘’’

```auto
import cv2 as cv
import numpy as np

# load the image
def load_image():
    """load the image in rgb format"""
    img = cv.imread("images/test_pillar.png", cv.IMREAD_COLOR)
    return img

# resize the image to 100 microns for marker length
def reshape_image(frame):
    """resize the image to 100 microns for marker length"""
    scale_percent = 80 # percent of original size
    width = int(frame.shape[1] * scale_percent / 100)
    height = int(frame.shape[0] * scale_percent / 100)

    dim = (width, height)

    # resize image
    frame = cv.resize(frame, dim, interpolation=cv.INTER_AREA)
    return frame

def image_processing(img, lower_gray, upper_gray, lower_canny, upper_canny):
    """take an rgb image and returns a canny image"""

    # convert image to rgb
    img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

    gray_image = cv.cvtColor(img, cv.COLOR_RGB2GRAY) # gray image

    blur_image = cv.GaussianBlur(gray_image, (5, 5), 0)

    # canny edge detection
    canny_image = cv.Canny(blur_image, lower_canny, upper_canny)

    # # setting threshold of gray image

    # _, threshold = cv.threshold(canny_image, lower_gray, upper_gray, cv.THRESH_BINARY)

    eroded = cv.erode(canny_image, (5, 5), iterations=1) # type: ignore
    dilated = cv.dilate(eroded, (5, 5), iterations=1) # type: ignore

    thresh = cv.adaptiveThreshold(dilated, 255,
                                  cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, 11, 11)

    return thresh

def nothing(x):
    pass

def add_tracker_bars(window_name):
    """add four tracker bars to the window, two for thresholding and two for canny edge detection"""

    cv.namedWindow(window_name)
    cv.createTrackbar("lower_gray", window_name, 0, 255, nothing)
    cv.createTrackbar("upper_gray", window_name, 0, 255, nothing)
    cv.createTrackbar("lower_canny", window_name, 0, 255, nothing)
    cv.createTrackbar("upper_canny", window_name, 0, 255, nothing)

    # set initial values for tracker bar
    cv.setTrackbarPos("lower_gray", window_name, 1)
    cv.setTrackbarPos("upper_gray", window_name, 10)
    cv.setTrackbarPos("lower_canny", window_name, 10)
    cv.setTrackbarPos("upper_canny", window_name, 30)

# find contours and properties of contours like area, perimeter and approx
def find_contours_and_its_properties(canny_image):
    # using a findContours() function
    contours, _ = cv.findContours(
        canny_image, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

    return contours

# main function
def main():
    # load the image
    img = load_image()

    # reshape the image
    img = reshape_image(img)

    # add tracker bars
    window_name = "image"
    add_tracker_bars(window_name)

    while True:
        lower_gray = cv.getTrackbarPos("lower_gray", window_name)
        upper_gray = cv.getTrackbarPos("upper_gray", window_name)
        lower_canny = cv.getTrackbarPos("lower_canny", window_name)
        upper_canny = cv.getTrackbarPos("upper_canny", window_name)

        # apply image processing
        canny_image = image_processing(img, lower_gray, upper_gray, lower_canny, upper_canny)

        # find contours and its properties
        contours = find_contours_and_its_properties(canny_image)

        # # draw the contours
        img_copy = img.copy()
        cv.drawContours(img_copy, contours, -1, (255, 0, 255), 5)

        # display the image
        cv.imshow(window_name, img_copy)
        # cv.imshow("canny", canny_image)

        if cv.waitKey(1) & 0xFF == ord("q"):
            break

if __name__ == " __main__":
    main()

```

---

<div class="post-metadata">

**Author:** ![zeeshanbabar112](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/zeeshanbabar112/32/9854_2.png) [@zeeshanbabar112](https://forum.opencv.org/u/zeeshanbabar112)\
**Post date:** [September 5, 2024, 11:03am UTC](https://forum.opencv.org/t/detect-the-outer-boundary-of-gray-color-inside-an-image-and-draw-contour/18679/2 "2024-09-05T11:03:45Z")

</div>

![test_pillar_image](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/1/151eb8fbc32993096f20ca3a6dae9aa15df45551.jpeg)  
here is the way I want to detect the boundary of the inside shape.
