2

I am trying to add a transaprent logo to an existing image array. It works fine except that I lose the transparency and it is replaced in black. I think this happens when the image is resized. Here is my code:

import cv2
import numpy as np

def add_logo(array):

    logo = cv2.imread("resources/logo/logo.png", 0)
    logo = np.array(logo, dtype=np.uint16)
    logo *= 256
    scale_percent = 
    width = int(logo.shape[1] * scale_percent / 100)
    height = int(logo.shape[0] * scale_percent / 100)
    dim = (width, height)
    logo = cv2.resize(logo, dim, interpolation = cv2.INTER_AREA)
    #cv2.imwrite('02.png',logo)
    print(array.shape, logo.shape)
    x_offset = y_offset = 50
    array[y_offset:y_offset+logo.shape[0],
                x_offset:x_offset+logo.shape[1]] = logo

    return array


imgs = get_images_from_xxxx()
edited = add_logo(imgs[0])
cv2.imwrite('01.png',edited)

I also tried this solution, but i does not apply to my context, as it it very important that the original array shape or data is not changed except for adding the logo.

This is part of the image i'm getting: but I don't need the black background as the original logo is transparent. Sorry had to crop out the logo!

output

And if it helps, here is a print of the array passed to add_logo, it's a numpy array:

[[3505 3514 3606 ... 4622 4781    0]
 [3566 3507 3503 ... 4587 4386    0]
 [3522 3503 3453 ... 4584 4434    0]
 ...
 [3435 3428 3428 ... 3721 3779    0]
 [3451 3418 3455 ... 3829 3877    0]
 [   0    0    0 ...    0    0    0]]

And the outputs of print(array.shape, logo.shape):

(1721, 912) (378, 304)

Any ideas are greaaaatly appreciated. :)

toing_toing
  • 1,789
  • 1
  • 29
  • 63
  • 2
    you are not loading the logo with alpha.... You are loading it as greyscale, which does not have an alpha channel... you probably want is too add the logo as greyscale (plus the conversions done in your function) using the transparency as a mask right? – api55 Feb 19 '19 at 14:43
  • @api55, I want it done, that the logo is grayscale(with conversions), but in a way that I don not have to change `array` apart from this line `array[y_offset:y_offset+logo.shape[0], x_offset:x_offset+logo.shape[1]] = logo` . – toing_toing Feb 19 '19 at 14:47
  • 1
    I see, but you want the transparent part to not be copied when you do the `...=logo` part, right? you only want to have the solid part (white in your example image) copied? This can be done quite easily, I am about to go out, so I can write the answer in like 3 hours, unless someone answers first :) – api55 Feb 19 '19 at 15:28
  • exactly. that would be great! – toing_toing Feb 19 '19 at 15:57

1 Answers1

1

Your question is a little bit tricky because you need to load the transparency as well and you want it in greyscale, but it is not difficult.

First load the image as colored one with alpha

logo = cv2.imread("resources/logo/logo.png", cv2.IMREAD_UNCHANGED)

then convert to grey and use the alpha as mask (anything transparent is 0 else 255)

logoGrey = cv2.cvtColor(logo[:,:,0:3], cv2.COLOR_BGR2GRAY)
mask = logo[:,:,3]
# here goes your changes to logoGrey which is equivalent logo in your code

Now that you have both things comes the copy:

maskIdx = (mask != 0)
array[y_offset:y_offset+logo.shape[0],
            x_offset:x_offset+logo.shape[1]][maskIdx] = logoGrey[maskIdx] 

And this should only copy the pixels which are solid in the mask (or basically anything not 0)

I couldn't test it, since I am in another computer, so I hope I did not miss anything. If you have any doubt just leave me a comment

api55
  • 9,870
  • 4
  • 35
  • 52