Transparent overlays with OpenCV


One of my favorite aspects of running the PyImageSearch blog is sharing little bitesize OpenCV tips and tricks that I’ve learned after nearly 7 years of using the OpenCV library.

Today’s tip comes from my bag of experiences: constructing transparent overlays with OpenCV.

In order to construct a transparent overlay, you need two images:

  1. Your original image.
  2. An image containing what you want to “overlay” on top of the first using some level of alpha transparency.

The results of applying such a transparent overlay can see seen at the top of this blog post.

So, you might be wondering: “When/where will I use a transparent overlay in my computer vision application? And why are you sharing this tip?”

Great question.

For starters, if your OpenCV app requires a Heads-up Display (HUD) of any kind, you should consider using transparent overlays. Instead of displaying runtime critical information in separate window or in the terminal, you can directly overlay the information on your output image. Using transparent overlays alleviates the need to obfuscate the contents of the output image!

A second, more obvious example is alpha transparency where you need to “blend” two images together.

The use cases for transparent overlays are nearly endless — my goal in today’s blog post is simply to show you how you can incorporate them into your own applications.

Looking for the source code to this post?
Jump right to the downloads section.

Transparent overlays with OpenCV

In the remainder of this lesson, I’ll demonstrate how to construct transparent overlays using Python and OpenCV.

We’ll start with the following image:

Figure 1: Our initial image that we are going to construct an overlay for.

Figure 1: Our initial image that we are going to construct an overlay for.

Our goal will be to:

  • Use the cv2.rectangle  function to draw a red bounding box surrounding myself in the bottom-right corner of the image.
  • Apply the cv2.putText  method to draw the text PyImageSearch  (along with the transparency factor) in the top-left corner of the image.

The results of drawing the rectangle and text can be seen below:

Figure 2: Drawing a rectangle and text on the original image. However, both the text and bounding box are entirely opaque -- no transparency has been applied.

Figure 2: Drawing a rectangle and text on the original image. However, both the text and bounding box are entirely opaque — no transparency has been applied.

However, notice that both the rectangle and text are fully opaque!

You cannot see myself through the rectangle, nor does the “PyImageSearch” text contain any level of transparency.

To remedy this, we can leverage the cv2.addWeighted  function to “blend” images together and construct the transparent overlay.

Let’s go ahead and dive into some source code to create a transparent overlay with Python and OpenCV. Open up a new file, name it , and insert the following code:

Lines 2-4 handle importing our required Python packages.

Line 7 loads our image from disk using the cv2.imread  function.

The next step is to loop over various values of alpha transparency between the range [0, 1.0], allowing us to visualize and understand how the alpha  value can influence our output image:

In order to apply the transparent overlay, we need to make two copies of the input image:

  1. One for the final output  image.
  2. And another for the overlay  we are about to construct.

Using the cv2.rectangle  function, we draw a rectangle surrounding myself in the bottom-right corner of the image. We then apply cv2.putText  to draw the text PyImageSearch  in the top-left corner.

We are now ready to apply the transparent overlay using the cv2.addWeighted  function:

The cv2.addWeighted  method requires six arguments.

The first is our overlay , the image that we want to “overlay” on top of the original image using a supplied level of alpha transparency.

The second parameter is the actual alpha transparency of the overlay. The closer alpha  is to 1.0, the more opaque the overlay will be. Similarly, the closer alpha  is to 0.0, the more transparent the overlay will appear.

The third argument to cv2.addWeighted  is the source image — in this case, the original image loaded from disk.

We supply the beta value as the fourth argument. Beta is defined as 1 - alpha . We need to define both alpha and beta such that alpha + beta = 1.0 .

The fifth parameter is the gamma value — a scalar added to the weighted sum. You can think of gamma as a constant added to the output image after applying the weighted addition. In this case, we set it to zero since we do not need to apply an addition of a constant value.

Finally, we have the last argument, output , which is the output destination after applying the weighted sum operation — this value is our final output image.

Our last code block handles displaying the final output image to our screen, as well as displaying the relevant alpha and beta values:

To execute our Python script, download the source code + example image to this post (using the “Downloads” form found at the bottom of this lesson) and execute the following command:

You should see the following image displayed to your screen:

Figure 3: Notice how for alpha=1.0, the text and rectangle are entirely opaque (i.e., not transparent).

Figure 3: Notice how for alpha=1.0, the text and rectangle are entirely opaque (i.e., not transparent).

However, once we reach alpha=0.5 , both the “PyImageSearch” text and rectangle are substantially more transparent:

Figure 4: Constructing transparent overlays with Python and OpenCV.

Figure 4: Constructing transparent overlays with Python and OpenCV.

At alpha=0.1 , the text and rectangle are barely visible:

Figure 5: The smaller alpha gets, the more transparent the overlay will be.

Figure 5: The smaller alpha gets, the more transparent the overlay will be.

Below you can see a GIF animation that visualizes each of the transparency levels:



In this blog post, we learned how to construct transparent overlays using Python, OpenCV, and the cv2.addWeighted  function.

Future blog posts will use this transparent overlay functionality to draw Heads-up Displays (HUDs) on output images, and to make outputs more aesthetically appealing.


If you would like to download the code and images used in this post, please enter your email address in the form below. Not only will you get a .zip of the code, I’ll also send you 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! Sound good? If so, enter your email address and I’ll send you the code immediately!

, ,

27 Responses to Transparent overlays with OpenCV

  1. "C.W." March 9, 2016 at 5:06 am #

    Thanks for your consistent generosity!

  2. Ivan March 11, 2016 at 11:35 am #

    Hi Adrian, first of all, thanks for all your contributions they’re just great.

    At a first glance this might not look useful for somebody, but it is actually quite useful for several applications. One comment I have, would be, is there a way to apply transparent overlays of images that are different in size, and probably, in format? I.e. I have my pictures folder and I want to apply my watermark signature to all of them, but my watermark file is a .PNG with alpha channel enablled and no background (different size and format than JPEGS), you see what I mean? Seems the library requires that both of the images are equal in size and format.

    Thank you very much

    Kind regards

    • Adrian Rosebrock March 13, 2016 at 10:26 am #

      Both images do have to be the same size, but that’s easily accomplishable. The actual file format of the image doesn’t matter. Once the image is loaded via cv2.imread, an image is represented as a NumPy array, regardless of original image file type.

      In this case, I’m assuming your watermark is smaller than the original image? In that case, just clone the original image, place the watermark in image (using array slicing), and then apply the cv2.addWeighted method.

  3. linus April 13, 2016 at 12:29 pm #

    Hey Adrian,
    Thanks for sharing that! I looked for something like this for a long time, because I wanted my text displayed on the image to be more readable on every color…

    • Adrian Rosebrock April 13, 2016 at 6:50 pm #

      I’m happy the code helped Linus! In a few short weeks I’ll be doing a post on using this same technique for creating watermarks with OpenCV. Be sure to take a look!

  4. David April 17, 2016 at 6:36 pm #

    Hey Adrian,

    Great post! Is there a way to overlay another image instead of a shape?

    • Adrian Rosebrock April 18, 2016 at 4:47 pm #

      Absolutely. I’ll be covering that in next week’s blog post, so be sure to keep an eye out!

      • kuldeep May 1, 2019 at 6:28 am #

        hi i want to overlay two images.

        • Adrian Rosebrock May 1, 2019 at 11:18 am #

          Could you give an example of what you’re trying to accomplish/build?

  5. Ashwin February 9, 2017 at 5:26 am #

    What would you do if you had to merge two images based on a varying alpha channel? Here, each pixel would have different alpha values. As far as I know, addweighted can only take alpha parameters for the whole image, not an alpha matrix, which is what I require.

    • Adrian Rosebrock February 10, 2017 at 2:04 pm #

      I would instead do the weighted calculation using NumPy directly rather than cv2.addWeighted.

      • Haydon Berrow March 12, 2018 at 4:59 am #

        There is a tutorial on how to do this at

  6. slvgry June 10, 2017 at 4:55 am #

    Thanks for your blogs, the way to deliver the topic was so smooth and understandable. Thanks again

    • Adrian Rosebrock June 13, 2017 at 11:10 am #

      Thanks Slvgry, I appreciate that 🙂

  7. Michael June 18, 2017 at 1:08 pm #

    Is there possible to draw multiple rectangles with the different opacity of each?
    If I addWeighted multiple times than transparency of previous instances are lost because of multiple added picture… is there any workaround?

    • Sangeeth September 12, 2018 at 2:21 am #

      I have exactly the same requirement.. if you could find any workaround please do let me know.

      Thanks in Advance

  8. Venkatesh April 16, 2018 at 1:29 pm #

    How can we do the similar thing but no overlay or blending, just making the image transparent with decrease in alpha and increase in beta same as in this code but on the image?

    • Adrian Rosebrock April 16, 2018 at 1:57 pm #

      You’re referring to the image itself? You need to add an alpha channel to the image. This can be done by adding a new axis to the end of the image array.

  9. Ran October 2, 2018 at 10:12 pm #

    Thank you for this awesome tutorial 🙂 May I ask, is it possible to save the transparent overlay as a separate mask image AFTER drawing? Like I’m trying to let the user sketch (by drawing continuous circles) on the original coloured image and the when the user is done, save only the drawings as a separate image mask. Please advise…Thank you!!

    • Adrian Rosebrock October 8, 2018 at 10:30 am #

      The cv2.imwrite function will allow you to write an output image to disk.

  10. Waqar Nawab October 11, 2018 at 10:19 am #

    It was a very helpful tutorial, Thanks to you for this. I am stuck in one point can you please help me out that is it possible that I draw a custom/external image over detected ball/color in this video? I mean to say that I want to detect a ball of green color and instead of masking it with the circle I want to draw an image over it and let it move as the ball move. Is there any code that could help me out? …. Thank you!

    • Adrian Rosebrock October 12, 2018 at 9:00 am #

      Hi Waqar — I’m not sure what you mean by “let it move as the ball moves”. Do you have an example of what you’re trying to achieve? That would be helpful in providing further suggestions.

  11. Robin October 25, 2018 at 10:08 am #

    Hi Adrian.

    Thanks again for the article.

    I have a problem with alpha channel images. While calculating the histogram of alpha channel image,OpenCV counts alpha channel as 0 (black) in all channels. We get a huge peak at zero. Is there any way to avoid reading alpha channel as zero value?

    Thanks in advance

  12. CJ September 6, 2019 at 6:17 pm #

    Hi Adrian, great article.

    How would you handle overlaying more than 2 images over each other?

    We know the cv2.addWeighted() function works well, but it only works for pairs of images (n=2).
    What if you’re trying to superimpose 3 or 4 or more images together?

    It doesn’t appear that cv2 has a function for this action.

    Let’s say you have a list of 4 JPEG files that you want to overlay all onto a new single image file.

    I was thinking you could iterate through the list and create an intermediate image that overlays the first two.
    Then you could call addWeighted() again to add that intermediate and the 3rd image.
    Then you could call that 2nd intermediate image to the 4th image using addWeighted() once again, and so on.

    This seems like it would work, but there has to be a more elegant way of solving it.

    How would one do this? Thanks

  13. Rinku Monani October 31, 2019 at 1:29 pm #

    can you elaborate more on how to add an alpha channel to a three channel image?

  14. Thanks November 9, 2019 at 3:10 am #

    Thank you so muuuuuuuuuuchhhhh !!!!!!!!!!!!!!!!!!!!!!!


  1. Watermarking images with OpenCV and Python - PyImageSearch - April 25, 2016

    […] few weeks ago, I wrote a blog post on creating transparent overlays with OpenCV. This post was meant to be a gentle introduction to a neat little trick you can use to improve the […]

Before you leave a comment...

Hey, Adrian here, author of the PyImageSearch blog. I'd love to hear from you, but before you submit a comment, please follow these guidelines:

  1. If you have a question, read the comments first. You should also search this page (i.e., ctrl + f) for keywords related to your question. It's likely that I have already addressed your question in the comments.
  2. If you are copying and pasting code/terminal output, please don't. Reviewing another programmers’ code is a very time consuming and tedious task, and due to the volume of emails and contact requests I receive, I simply cannot do it.
  3. Be respectful of the space. I put a lot of my own personal time into creating these free weekly tutorials. On average, each tutorial takes me 15-20 hours to put together. I love offering these guides to you and I take pride in the content I create. Therefore, I will not approve comments that include large code blocks/terminal output as it destroys the formatting of the page. Kindly be respectful of this space.
  4. Be patient. I receive 200+ comments and emails per day. Due to spam, and my desire to personally answer as many questions as I can, I hand moderate all new comments (typically once per week). I try to answer as many questions as I can, but I'm only one person. Please don't be offended if I cannot get to your question
  5. Do you need priority support? Consider purchasing one of my books and courses. I place customer questions and emails in a separate, special priority queue and answer them first. If you are a customer of mine you will receive a guaranteed response from me. If there's any time left over, I focus on the community at large and attempt to answer as many of those questions as I possibly can.

Thank you for keeping these guidelines in mind before submitting your comment.

Leave a Reply