findcontours opencv pythonfindcontours opencv python

In this tutorial we are going to learn the usage of findcontours and drawcontours functions in OpenCV Python. We will create code for doing this in real time using Webcam. This code will help you in further image processing and computer vision projects where finding contours or Objects be the first task before doing any further identification related task. Such as in Number Plate detection system or any similar OCR based projects. Where you need to extract each alphabet as separate object or contours. The findcontours functions have some calling variations in some of opencv versions. You can find the difference in this stack overflow question.

Learning Objectives:

Here is a quick learning Objective summary about today’s findcontours opencv python example as well as drawcontours opencv python example. So it makes clear that today we are specially focusing on two main functions from the OpenCV Library in Python which is cv2.findcontours and cv2.drawcontours. So here are the list of question we are going to answer in this tutorial

  • access webcam in OpenCV Python
  • show Image in OpenCV Python
  • Convert RGB Image into GrayScale in OpenCV Python
  • extract Objects in OpenCV Python
  • draw contours on RGB Image in OpenCV Python

VideoCapture OpenCV Python

VideoCapture function in OpenCV is used to access webcam attached to the system. This can also detect USB webcam in Raspberry Pi. So if you are using Raspberry PI and doing Image processing in Raspberry PI with external USB Webcam then this code will also work there. Here is the code which will initialize webcam and display stream on the display screen.

import cv2
cap = cv2.VideoCapture(1) #webcam number from 0->onwards
while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()
    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()Code language: PHP (php)

The code will open a window which will have the title ‘frame’ and that frame will show the stream from the webcam. Which is basically just a frame grabbed from webcam and displayed with cv2.imshow function. The next line containing cv2.waitKey(1) function is important after cv2.imshow function. This will help you to quite or to come out of Infinite While Loop by pressing the ‘q‘ key from keyboard.

Preprocessing to get Binary Image

Before extracting our desired objects we need to do propper segmentation and pre-processing. The reason behind this is to obtain binary Image which holds nothing but our desired objects so that we do not get unwanted noisy object but only our desired on. There are different pre-processing, noise removal and binarization techniques available but we used simplest one to find bright mostly white objects. We focus on dark background and bright objects on that background. So if you have some other lighting conditions and/or background and object properties you may have to change this step according to your needs. But if you are following along and using similar environmental conditions then you are good to go.

Code

Now our code will look like this.

import numpy as np
import cv2

cap = cv2.VideoCapture(1)
kernel = np.ones((2,2),np.uint8)
while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()  
    # Our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (7, 7), 0)
    gray= cv2.medianBlur(gray, 3)   #to remove salt and paper noise
    #to binary
    ret,thresh = cv2.threshold(gray,200,255,0)  #to detect white objects
    #to get outer boundery only     
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_GRADIENT, kernel)
    #to strength week pixels
    thresh = cv2.dilate(thresh,kernel,iterations = 5)
    
    # Display the resulting frame
    cv2.imshow('frame',thresh)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
Code language: PHP (php)

and result image will be something like this

Bright Objects outline Binary Image

Contour Detection

Now we are ready to extract these objects via contour analysis or contour detection method. As I have told you before that the OpenCV have findcontour function for this and the usage of that function is something as follows

im2,contours,hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

You provide a binary image to cv2.findContours function and it will return you 3 output variables according to openCV 3.4 version which currently I am using. If you get some error in this line of code. Just comfirm your OpenCV version and check the documentation to make sure how many returning parameters you have for that version. The most of the time the error which you may face could seem something as follows

ValueError: too many values to unpack

Draw Contours

Final step left, is to draw contours on the original color frame so that we can visualize in real time. So to draw them we have cv2.drawcontours function in opencv which could be used like this

if len(contours)>0:
   cv2.drawContours(frame, contours, -1, (0,255,0), 5)
Code language: CSS (css)

The last argument to this function is for line width and second last is for color of the contours boundary to draw with. Frist argument is image to draw on and second is the list of contours to draw.

Draw Rectangle around Biggest Object

Most of the time application is required to draw rectangle around the biggest object in the image. This will help us to detect the biggest object or biggest contour. We can apply max function to returns contours from cv2.findContours function and can draw rectangle like this

c = max(contours, key = cv2.contourArea)
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)

The final Image will now look like this

findcontours opencv python
findcontours opencv python

Final code for Contour Extraction

Here is complete code used in this tutorial

import numpy as np
import cv2

cap = cv2.VideoCapture(1)
kernel = np.ones((2,2),np.uint8)
while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()
   

    # Our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (7, 7), 0)
    gray= cv2.medianBlur(gray, 3)   #to remove salt and paper noise
    #to binary
    ret,thresh = cv2.threshold(gray,200,255,0)  #to detect white objects
    #to get outer boundery only     
    thresh = cv2.morphologyEx(thresh, cv2.MORPH_GRADIENT, kernel)
    #to strength week pixels
    thresh = cv2.dilate(thresh,kernel,iterations = 5)
    im2,contours,hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    if len(contours)>0:
        cv2.drawContours(frame, contours, -1, (0,255,0), 5)
        # find the biggest countour (c) by the area
        c = max(contours, key = cv2.contourArea)
        x,y,w,h = cv2.boundingRect(c)

        # draw the biggest contour (c) in green
        cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
    # Display the resulting frame
    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
Code language: PHP (php)

By Abdul Rehman

My name is Abdul Rehman and I love to do Reasearch in Embedded Systems, Artificial Intelligence, Computer Vision and Engineering related fields. With 10+ years of experience in Research and Development field in Embedded systems I touched lot of technologies including Web development, and Mobile Application development. Now with the help of Social Presence, I like to share my knowledge and to document everything I learned and still learning.

2 thoughts on “Real Time Contours Detection findcontours OpenCV Python”
  1. line 11, in
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    cv2.error: OpenCV(4.5.1) C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-6uw63ony\opencv\modules\imgproc\src\color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function ‘cv::cvtColor’

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.