Home > OS >  How set white color background when concatenating images via python?
How set white color background when concatenating images via python?

Time:02-06

import numpy as np
from imageio import imread, imwrite

im1 = imread('https://api.sofascore.app/api/v1/team/2697/image')[...,:3]
im2 = imread('https://api.sofascore.app/api/v1/team/2692/image')[...,:3]

result = np.hstack((im1,im2))

imwrite('result.jpg', result)

Original images opening directly from the url's (I'm trying to concatenate the two images into one and keep the background white):

enter image description hereenter image description here

As can be seen both have no background, but when joining the two via Python, the defined background becomes this moss green:

enter image description here

I tried modifying the color reception:

im1 = imread('https://api.sofascore.app/api/v1/team/2697/image')[...,:1]
im2 = imread('https://api.sofascore.app/api/v1/team/2692/image')[...,:1]

But the result is a Black & White with the background still looking like it was converted from the previous green, even though the PNG's don't have such a background color.

enter image description here

How should I proceed to solve my need?

CodePudding user response:

There is a 4th channel in your images - transparency. You are discarding that channel with [...,:1]. This is a mistake.

If you retain the alpha channel this will work fine:

import numpy as np
from imageio import imread, imwrite

im1 = imread('https://api.sofascore.app/api/v1/team/2697/image')
im2 = imread('https://api.sofascore.app/api/v1/team/2692/image')

result = np.hstack((im1,im2))

imwrite('result.png', result)

However, if you try to make a jpg, you will have a problem:

>>> imwrite('test.jpg', result)

OSError: JPEG does not support alpha channel.

This is correct, as JPGs do not do transparency. If you would like to use transparency and also have your output be a JPG, I suggest a priest.

You can replace the transparent pixels by using np.where and looking for places that the alpha channel is 0:

result = np.hstack((im1,im2))
result[np.where(result[...,3] == 0)] = [255, 255, 255, 255]

imwrite('result.png', result)

CodePudding user response:

If you want to improve image quality, here is a solution. @Brondy

# External libraries used for
# Image IO
from PIL import Image

# Morphological filtering
from skimage.morphology import opening
from skimage.morphology import disk

# Data handling
import numpy as np

# Connected component filtering
import cv2

black = 0
white = 255
threshold = 160

# Open input image in grayscale mode and get its pixels.
img = Image.open("image.jpg").convert("LA")
pixels = np.array(img)[:,:,0]

# Remove pixels above threshold
pixels[pixels > threshold] = white
pixels[pixels < threshold] = black


# Morphological opening
blobSize = 1 # Select the maximum radius of the blobs you would like to remove
structureElement = disk(blobSize)  # you can define different shapes, here we take a disk shape
# We need to invert the image such that black is background and white foreground to perform the opening
pixels = np.invert(opening(np.invert(pixels), structureElement))


# Create and save new image.
newImg = Image.fromarray(pixels).convert('RGB')
newImg.save("newImage1.PNG")

# Find the connected components (black objects in your image)
# Because the function searches for white connected components on a black background, we need to invert the image
nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(np.invert(pixels), connectivity=8)

# For every connected component in your image, you can obtain the number of pixels from the stats variable in the last
# column. We remove the first entry from sizes, because this is the entry of the background connected component
sizes = stats[1:,-1]
nb_components -= 1

# Define the minimum size (number of pixels) a component should consist of
minimum_size = 100

# Create a new image
newPixels = np.ones(pixels.shape)*255

# Iterate over all components in the image, only keep the components larger than minimum size
for i in range(1, nb_components):
    if sizes[i] > minimum_size:
        newPixels[output == i 1] = 0

# Create and save new image.
newImg = Image.fromarray(newPixels).convert('RGB')
newImg.save("new_img.PNG")

CodePudding user response:

If you want to change the background of a Image, pixellib is the best solution because it seemed the most reasonable and easy library to use.

import pixellib
from pixellib.tune_bg import alter_bg

change_bg = alter_bg()
change_bg.load_pascalvoc_model("deeplabv3_xception_tf_dim_ordering_tf_kernels.h5")
change_bg.color_bg("sample.png", colors=(255,255,255), output_image_name="colored_bg.png")

This code requires pixellib to be higher or the same as 0.6.1

  •  Tags:  
  • Related