Title: Implementing the Max RGB filter in OpenCV - PyImageSearch

URL Source: https://pyimagesearch.com/2015/09/28/implementing-the-max-rgb-filter-in-opencv/

Published Time: 2015-09-28T14:00:49+00:00

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

Today’s blog post comes straight out of the [PyImageSearch Gurus course](https://pyimagesearch.com/pyimagesearch-gurus/). Inside PyImageSearch Gurus we have a community page (much like a combination of forums + Q&A + StackOverflow) where we discuss a variety of computer vision topics, ask questions, and hold each other accountable to learning computer vision and image processing.

This post was inspired by PyImageSearch Gurus member Christian Smith who asked if it was possible to implement GIMP’s Maximum RGB filter using OpenCV and Python:

[![Image 2: Figure 1: Christian, a member of PyImageSearch Gurus, asked if it was possible to replicate GIMP's Max RGB filter using Python and OpenCV.](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20380'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2015/09/max_filter_community.png)

**Figure 1:** Christian, a member of [PyImageSearch Gurus](https://pyimagesearch.com/pyimagesearch-gurus/), asked if it was possible to replicate GIMP’s Max RGB filter using Python and OpenCV.

This thread sparked a great discussion on the topic and even led to an implementation (which I’ll share with you today).

The Max RGB filter isn’t used in many image processing pipelines; however, it’s a very useful tool to use when visualizing the Red, Green, and Blue channels of an image — _and which channel contributes most to a given area of an image._ It’s also a great filter to use for simple color-based segmentation.

In the remainder of this post I’ll demonstrate how you can implement the Max RGB filter in surprisingly few lines of Python and OpenCV code.

![Image 3](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)

What is the Max RGB filter?
---------------------------

The Max RGB filter is an extremely simple and straight forward image processing filter. The algorithm goes something like this.

*   For each pixel in the image _I_:
    *   Grab the _r_, _g_, and _b_ pixel intensities located at _I\[x, y\]_
    *   Determine the maximum value of _r_, _g_, and _b_: _m = max(r, g, b)_
    *   If _r < m: r = 0_
    *   If _g < m: g = 0_
    *   If _b < m: b = 0_
    *   Store the _r_, _g_, and _b_ values back in image: _I\[x, y\] = (r, g, b)_

The only caveat to mention is if _two channels_ have the same intensity, such as: _(155, 98, 155)_. In this case, _both_ _values_ are kept and the smallest is reduced to zero: _(155, 0, 155)_.

The output image should look something like this:

[![Image 4: Figure 2: An example of applying the Max RGB filter.](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20275'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2015/09/max_filter_grand_canyon.png)

**Figure 2:** An example of applying the Max RGB filter.

Where we can see the original image on the _left_ and the output filtered image on the _right_.

Now that we have a good grasp on the Max RGB filter algorithm (and what the intended output is supposed to look like), let’s go ahead and implement it in Python and OpenCV. Open up a new file, name it `max_filter.py` , and insert the following code:

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

def max\_rgb\_filter(image):
	# split the image into its BGR components
	(B, G, R) = cv2.split(image)

	# find the maximum pixel intensity values for each
	# (x, y)-coordinate,, then set all pixel values less
	# than M to zero
	M = np.maximum(np.maximum(R, G), B)
	R\[R < M\] = 0
	G\[G < M\] = 0
	B\[B < M\] = 0

	# merge the channels back together and return the image
	return cv2.merge(\[B, G, R\])

**Lines 2-4** simply import our necessary packages.

**Line 6** defines our `max_rgb_filter` function. This method requires only a single argument, the `image` we want to filter.

Given our input `image` , we then use the `cv2.split` function to split the `image` into its respective, Blue, Green, and Red components (**Line 8**)

**_Note:_** _It’s important to remember that OpenCV stores images in BGR order rather than RGB. This can cause a bit of a confusion and some hard to track down bugs if you’re just getting started with OpenCV_.

Given our `R` , `G` , and `B` channels, we then use NumPy’s `maximum` method (**Line 13**) to find the maximum intensity value at **_each_** _(x, y)_\-coordinate across **_all three_** `R` , `G` , and `B` channels

It’s **_very important_** that you use [np.maximum](http://docs.scipy.org/doc/numpy/reference/generated/numpy.maximum.html) and not [np.max](http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.max.html)! The `np.max` method will only find the maximum value across the _**entire array**_ as opposed to `np.maximum` which find the max value **_at each (x, y)-coordinate_**.

From there, **Lines 14-16** suppress the Red, Green, and Blue pixel intensities that fall below the maximum value _M_.

Finally, **Line 19** merges the channels back together (again, in BGR order since that is what OpenCV expects) and returns the Max RGB filtered image to the calling function.

Now that the `max_rgb_filter` method is defined, all we need to do is write some code to load our image off disk, apply the Max RGB filter, and display the results to our screen:

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

def max\_rgb\_filter(image):
	# split the image into its BGR components
	(B, G, R) = cv2.split(image)

	# find the maximum pixel intensity values for each
	# (x, y)-coordinate,, then set all pixel values less
	# than M to zero
	M = np.maximum(np.maximum(R, G), B)
	R\[R < M\] = 0
	G\[G < M\] = 0
	B\[B < M\] = 0

	# merge the channels back together and return the image
	return cv2.merge(\[B, G, R\])

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add\_argument("-i", "--image", required=True,
	help="path to input image")
args = vars(ap.parse\_args())

# load the image, apply the max RGB filter, and show the
# output images
image = cv2.imread(args\["image"\])
filtered = max\_rgb\_filter(image)
cv2.imshow("Images", np.hstack(\[image, filtered\]))
cv2.waitKey(0)

This code should be fairly self-explanatory. **Lines 22-25** handle parsing our command line arguments. The only switch we need is `--image` , the path to where the image we want to process resides on disk.

From there, **Lines 29-32** handle loading our `image` , applying the Max RGB filter, and finally displaying both the original and filtered image to our screen.

To see our script in action, just open up your terminal and execute the following command:

$ python max\_filter.py --image images/horseshoe\_bend\_02.jpg

[![Image 5: Figure 3: Our original image (left) and the Max RGB filtered image (right).](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20441'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2015/09/max_filter_horseshoebend_02.png)

**Figure 3:** Our original image (left) and the Max RGB filtered image (right).

On the _left_ we have the original image — a photo of myself in the desert near Horseshoe Bend, AZ. Then, on the _right_ we have the image after our Max RGB filter has been applied. At the top of the image we can see the sky is a rich blue, indicating that the blue channel has larger pixel intensity values in that region. Opposite the blue sky, the bottom of the image is more red (they don’t call it redstone for nothin’) — here the red channel has large pixel intensity values and the green and blue channel are suppressed.

Let’s give another image a try:

$ python max\_filter.py --image images/max\_filter\_horseshoe\_bend\_01.png

[![Image 6: Figure 4: Another example of applying the Max RGB filter using Python and OpenCV.](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20275'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2015/09/max_filter_horseshoe_bend_01.png)

**Figure 4:** Another example of applying the Max RGB filter using Python and OpenCV.

I especially like this image since it highlights how water is not always a “clear blue” like we think it is. Not surprisingly, the redstone is highlighted in red and the sky is very much blue. However, the water itself is a mixture of _both_ blue and green. Furthermore, both these regions of water are clearly segmented from each other.

Let’s do one final example:

$ python max\_filter.py --image images/max\_filter\_antelope\_canyon.png

[![Image 7: Figure 5: Applying the Max RGB filter to a photo taken in Antelope Canyon. Are you surprised by the results?](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20441'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2015/09/max_filter_antelope_canyon.png)

**Figure 5:** Applying the Max RGB filter to a photo taken in Antelope Canyon. Are you surprised by the results?

This image is from Antelope Canyon in Page, AZ (probably one of the most beautiful areas in the world). At the bottom of the slot canyon there is very little light so we don’t see much color at all (although if we you look closely you can see patches of deep blue/purple which the caverns are known for). Then, as we move our way up the canyon walls more light is let in, revealing the wonderful red glow. Finally, at the top of the cavern is the sky which is so bright in this photo it’s washed out.

Like I said, it’s rare that we use the Max RGB filter in image processing pipelines; however, since the filter allows you to investigate which channels of an image contribute most to a given region, it’s a valuable tool to have when performing basic segmentation and debugging.

### 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
-------

Today’s blog post was inspired by a question asked by Christian Smith, a member of [PyImageSearch Gurus](https://pyimagesearch.com/pyimagesearch-gurus/) (thanks Christian!). Christian asked if it was possible to implement GIMP’s Max RGB filter using nothing but Python and OpenCV — obviously, the answer is yes. But what may be surprisingly is how few lines of code it can be done in!

Go ahead and download the code to this post and apply the Max RGB filter to your own images. See if you can guess which Red, Green, or Blue channel contributes most to a specific region of an image — you might be surprised how your intuition and perception of color is wrong in certain circumstances!

Finally, if you’re interested in joining the PyImageSearch Gurus course, [please be sure to click here and claim your spot in line](https://pyimagesearch.com/pyimagesearch-gurus/). Spots inside the course are limited (only small batches of readers are let in at a time), so it’s _very important_ that your claim your spot if you’re interested in the course!

![Image 8](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!