How to convert black parts of an RGBA image to transparent in opencv

I have an image in rgba format with (0,0,0) blacks in it, and I want to covert each of these (0,0,0) pixels to transparent. The image already has an alpha channel, and I don't know how to activate the alpha channel for a pixel. I tried setting the alpha channel value to 0, but it hasn't worked so far:

        for y in range(len(blur)):
            for x in range(len(blur[0])):
                if blur[y][x][0] == 0 and blur[y][x][1] == 0 and blur[y][x][2] == 0:
                    blur[y][x][3] = 0

Also how can I optimize this nested for loop using numpy instead?

Upvotes: 2

Views: 4381

Answers (1)

Rotem
Rotem

Reputation: 32084

It could be just displaying issue, but it hard to tell from your code sample.

cv2.imshow doesn't support transparency.
Store the result to PNG image file, and view the image using a viewer that shows transparency. (using GIMP or paint.net, it's easy to view the transparent pixels).

The code sample below does the following:

  • Loads RGB image and draws black text on the image (load image as BGR).
  • Converts image to BGRA.
  • Sets value of alpha channel of all back pixels to zero (zero is transparent and 255 is opaque).
    The code uses logical indexing instead of using a for loop.
  • Stores the BGRA image to PNG image file.

Here is the code:

import cv2
import numpy as np

# Read image in BGR format
img = cv2.imread('chelsea.png')

# Write cat in in black color
cv2.putText(img, 'cat', (img.shape[1]//2-85*len('cat'), img.shape[0]//2+100), cv2.FONT_HERSHEY_DUPLEX, 10, (0, 0, 0), 20)

# Convert from BGR to BGRA
bgra = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)

# Slice of alpha channel
alpha = bgra[:, :, 3]

# Use logical indexing to set alpha channel to 0 where BGR=0
alpha[np.all(bgra[:, :, 0:3] == (0, 0, 0), 2)] = 0

# Save bgra to PNG file
cv2.imwrite('bgra.png', bgra)

# Show image for testing
cv2.imshow('img', img)
cv2.imshow('bgra', bgra) # The letters are black, because cv2.imshow does not support transparency.
cv2.imshow('bgra[:,:,3]', bgra[:,:,3])
cv2.waitKey(0)
cv2.destroyAllWindows()

Result:

bgra.png file:
enter image description here

The site background is white, so the transparent pixels are white...

Upvotes: 6

Related Questions