Title: Removing contours from an image using Python and OpenCV - PyImageSearch

URL Source: https://pyimagesearch.com/2015/02/09/removing-contours-image-using-python-opencv/

Published Time: 2015-02-09T15:00:18+00:00

Markdown Content:
[![Image 1: remove_contours_header](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20228'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2015/01/remove_contours_header.png)

Awhile back I was going through [/r/computervision](http://www.reddit.com/r/computervision/) when I stumbled across a question asking [how to remove contours from an image using OpenCV](http://www.reddit.com/r/computervision/comments/2rhg3h/opencv_how_to_remove_contours_from_image/).

Intrigued, I posted a reply. The basic algorithm for removing contours from an image goes something like this:

*   **Step 1:** Detect and find contours in your image.
*   **Step 2:** Loop over contours individually.
*   **Step 3:** Determine if the contour is “bad” and should be removed according to some criterion.
*   **Step 4:** Accumulate a mask of “bad” contours to be removed.
*   **Step 5:** Apply the accumulated mask of bad contours to the original image using a bitwise ‘and’.

And that’s it!

The algorithm itself is very straightforward, the main step that you need to pay attention to and consider is **Step 3**, determining if a contour should be removed.

This step could be very simple — or it also could be quite hard, it really depends on your application. And while it’s impossible for me to guess the criterion as to why you want to remove a contoured region from an image, the remainder of this blog post will demonstrate a toy example that you can use to remove contours from an image. From here, you’ll be able to take this code and modify the contour removal criterion according to your own needs.

![Image 2](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20128%20128'%3E%3C/svg%3E)

#### Looking for the source code to this post?

[Jump Right To The Downloads Section](#download-the-code)

**OpenCV and Python versions:**  
This example will run on **Python 2.7/Python 3.4+** and **OpenCV 2.4.X**.

[![Image 3: shapes](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20400'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2015/01/shapes.png)

**Figure 1:** Our example toy image. Our goal is to **remove all circles/ellipses** while **retaining the rectangles.**

In this toy example our goal is to **remove the circles/ellipses** from the image above **while retaining the rectangles**. We’ll accomplish this by applying a test to every contour to determine if it should be removed or not.

Anyway, let’s go ahead and get this example started. Open up a new file, name it `remove_contours.py` , and let’s get coding:

\# import the necessary packages
import numpy as np
import imutils
import cv2

def is\_contour\_bad(c):
	# approximate the contour
	peri = cv2.arcLength(c, True)
	approx = cv2.approxPolyDP(c, 0.02 \* peri, True)

	# the contour is 'bad' if it is not a rectangle
	return not len(approx) == 4

The first thing we’ll do is import our necessary packages. We’ll use NumPy for numerical processing and `cv2` for our OpenCV bindings.

We then define our `is_contour_bad` function on **Line 6**. This function handles the implementation of **Step 3** above and defines the criterion under which a contour should be marked as “bad” and removed from an image.

The `is_contour_bad` function requires a single argument, `c` , which is the contour we are going to test to determine if it should be removed or not.

Remember, in our toy example image above, our goal is to remove the circles/ellipses, while keeping the rectangles intact.

_So let’s take a second to consider if we can exploit the geometry of this problem._

A rectangle has 4 sides. And a circle has no sides.

So if we **_approximate the contour_** and then **_examine the number of points within the approximated contour_**, we’ll be able to determine if the contour is a square or not!

And that’s exactly what **Lines 7-11** do. We first approximate the contour on **Lines 8 and 9**, while **Line 12** returns a boolean, indicating whether the contour should be removed or not. In this case, the contour will be kept if the approximation has 4 points (vertices), indicating that the contour is a rectangle.

Let’s finish implementing the other steps to solve this problem:

\# load the shapes image, convert it to grayscale, and edge edges in
# the image
image = cv2.imread("shapes.png")
gray = cv2.cvtColor(image, cv2.COLOR\_BGR2GRAY)
edged = cv2.Canny(gray, 50, 100)
cv2.imshow("Original", image)

# find contours in the image and initialize the mask that will be
# used to remove the bad contours
cnts = cv2.findContours(edged.copy(), cv2.RETR\_LIST, cv2.CHAIN\_APPROX\_SIMPLE)
cnts = imutils.grab\_contours(cnts)
mask = np.ones(image.shape\[:2\], dtype="uint8") \* 255

# loop over the contours
for c in cnts:
	# if the contour is bad, draw it on the mask
	if is\_contour\_bad(c):
		cv2.drawContours(mask, \[c\], -1, 0, -1)

# remove the contours from the image and show the resulting images
image = cv2.bitwise\_and(image, image, mask=mask)
cv2.imshow("Mask", mask)
cv2.imshow("After", image)
cv2.waitKey(0)

In order to find and detect the contours in our image (**Step 1**), we preprocess our image on **Lines 16-19** by loading it from disk, converting it to grayscale and detecting edges.

Finding the actual contours happens on **Line 23** by making a call to `cv2.findContours` . Subsequently we handle grabbing contours with different versions of OpenCV (**Line 24**).

We then initialize a `mask` on **Line 25** to store our accumulated “bad” contours. We’ll be using this mask along with bitwise operations later on in the code to perform the actual removal of the contour.

Now we can move on to **Step 2**, looping over the individual contours which happens on **Line 28**.

For each of the contours we make a call to `is_contour_bad` on **Line 30**, and if the contour is indeed “bad”, then we accumulate our contours to be removed on **Line 31** by drawing the contour on our mask.

Finally, all we have to do is apply a bitwise ‘and’ to the image using the accumulated mask to remove the contours on **Line 34**. **Lines 35-37** then display our results.

Results
-------

To execute our script, just issue the following command:

$ python remove\_contours.py

First, you’ll see our mask of accumulated contours that will be removed:

[![Image 4: Figure 2: Our accumulated mask of contours to be removed. Shapes to be removed appear as black whereas the regions of the image to be retained are white.](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20422'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2015/01/remove_contours_mask.png)

**Figure 2:** Our accumulated mask of contours to be removed. Shapes to be removed appear as **black** whereas the regions of the image to be retained are **white**.

Notice how the contours appear as _black shapes_ on a _white background_. This is because the black shapes will be removed from the original image while the white regions will be retained once we apply the `cv2.bitwise_and`  function.

And here is the output after applying the accumulated mask:

[![Image 5: Figure 3: We have successfully removed the circles/ellipses while retaining the rectangles.](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20422'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2015/01/remove_contours_output.png)

**Figure 3:** We have successfully removed the circles/ellipses while retaining the rectangles.

Clearly we have removed the circles/ellipses from the image while retaining the rectangles!

### What's next? We recommend [PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend).

**Course information:**  
84 total classes • 114+ hours of on-demand code walkthrough videos • Last updated: February 2024  
★★★★★ 4.84 (128 Ratings) • 16,000+ Students Enrolled

**I strongly believe that if you had the right teacher you could _master_ computer vision and deep learning.**

Do you think learning computer vision and deep learning has to be time-consuming, overwhelming, and complicated? Or has to involve complex mathematics and equations? Or requires a degree in computer science?

That’s _not_ the case.

All you need to master computer vision and deep learning is for someone to explain things to you in _simple, intuitive_ terms. _And that’s exactly what I do_. My mission is to change education and how complex Artificial Intelligence topics are taught.

If you're serious about learning computer vision, your next stop should be PyImageSearch University, the most comprehensive computer vision, deep learning, and OpenCV course online today. Here you’ll learn how to _successfully_ and _confidently_ apply computer vision to your work, research, and projects. Join me in computer vision mastery.

**Inside PyImageSearch University you'll find:**

*   ✓ **84 courses** on essential computer vision, deep learning, and OpenCV topics
*   ✓ **84 Certificates** of Completion
*   ✓ **114+ hours** of on-demand video
*   ✓ **Brand new courses released _regularly_**, ensuring you can keep up with state-of-the-art techniques
*   ✓ **Pre-configured Jupyter Notebooks in Google Colab**
*   ✓ Run all code examples in your web browser — works on Windows, macOS, and Linux (no dev environment configuration required!)
*   ✓ Access to **centralized code repos for _all_ 536+ tutorials** on PyImageSearch
*   ✓ **Easy one-click downloads** for code, datasets, pre-trained models, etc.
*   ✓ **Access** on mobile, laptop, desktop, etc.

[Click here to join PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend)

Summary
-------

In this blog post I showed you how to remove contoured regions from an image using Python and OpenCV. Removing contours from an image is extremely straightforward and can be accomplished using the following 5 steps:

1.  Detecting and finding the contours in an image.
2.  Looping over each of the contours individually.
3.  Applying a “test” of some sort to determine if the contour should be removed.
4.  Accumulating a mask of contours to be removed.
5.  Applying the mask to the original image.

To apply this algorithm to your own images you’ll need to take a second and consider **Step 3** and determine the criterion you are using to remove contours. From there, you can apply the rest of the algorithm as-is.

![Image 6](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20410%20567'%3E%3C/svg%3E)

#### Download the Source Code and FREE 17-page Resource Guide

Enter your email address below to get a .zip of the code and a **FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning.** Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL!