简体   繁体   中英

Blend Multiple Images using Python

I am trying to combine multiple images of the same height and width to see an overall pattern. Each image should have the same "weight" or "transparency", but I cannot figure out how to do this. After looking here and here the general consensus seems to be to do it like this:

blendedImage = weight_1 * image_1 + weight_2 * image_2 + ... + weight_n * image_n

I am trying to do that with the code below and it doesn't seem to be working because no matter what I do I get an image that blends the first and last image in the list. So either I have misinterpreted how to do this or I am doing something wrong. How can I blend all the images in the jpeg_list? I don't know if this has anything to do with it but my input images are 3 channel JPGs or 3 Channel PNGs.

My code so far:

import os
import cv2


def prepend(list, str): 
      
    # Using format() 
    str += '{0}'
    list = [str.format(i) for i in list] 
    return(list) 


path = "EvalImages/"
jpeg_list = os.listdir(path)
if '.DS_Store' in jpeg_list: jpeg_list.remove('.DS_Store')
jpeg_list = prepend(jpeg_list, path)
uniWeight = (1/len(jpeg_list))
print(uniWeight)
print(jpeg_list)
aggregate_file = cv2.imread(jpeg_list[0]) * uniWeight
del jpeg_list[0]

for i in range(len(jpeg_list)):
    print(i)
    next_img = cv2.imread(jpeg_list[i])
    dst = aggregate_file + (next_img*uniWeight)
    cv2.imshow('dst', dst)
    cv2.imwrite('TestContainer/evalimage3.png', dst)
    height, width, channels = next_img.shape
    print(jpeg_list[i] + " | Size: " + str(width) + "x" + str(height) + " | Channels:" +  str(channels))

you are adding weighted images to dst but you meant to add them to aggregate_file .

your imshow also has no effect since there isn't any waitKey . that's important to actually show the window and its contents and make it react to input.

here's what I would do:

import pathlib
import numpy as np
import cv2 as cv

path = pathlib.Path("EvalImages")
jpeg_list = [elem for elem in path.iterdir() if elem.name != '.DS_Store']

# initialized to size of first image
accumulator = None

for i, filepath in enumerate(jpeg_list):
    print(i, filepath)
    img = cv.imread(str(filepath))
    if accumulator is None:
        accumulator = np.zeros_like(img, dtype=np.uint32)
    accumulator += img

# divide once to avoid adding up errors from many divisions
# values are now back in an 8 bit range
accumulator /= len(jpeg_list)

# convert back to uint8 so imwrite() knows to save it as 8 bit, not 32 bit
cv.imwrite('TestContainer/evalimage3.png', accumulator.astype(np.uint8))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM