I have been trying for a few days now to change this into a numpy array. This is being used to make a transparent image and putting it on the current frame.
Here is the code as a for loop:
alpha_frame = frame[:,:,3] / 255.0
alpha_foreground = foreground[:,:,3] / 255.0
for color in range(0, 3):
frame[:,:,color] = alpha_foreground * foreground[:,:,color] \
alpha_frame * frame[:,:,color] * (1 - alpha_foreground)
Here is what I've tried so far:
alpha_frame = frame[:,:,3] / 255.0
alpha_foreground = foreground[:,:,3] / 255.0
color = np.arange(0,3)
frame[:,:,color] = alpha_foreground * foreground[:,:,color] \
alpha_frame * frame[:,:,color] * (1 - alpha_foreground)
return frame
Here is the error:
frame = alpha_foreground * foreground \
ValueError: operands could not be broadcast together with shapes (480,640) (480,640,4)
CodePudding user response:
what's wrong with
frame = alpha_foreground * foreground
alpha_frame * frame * (1 - alpha_foreground)
?
CodePudding user response:
So first, if what you are looking for is a performance gain, instead of
alpha_frame = frame[:,:,3] / 255.0
alpha_foreground = foreground[:,:,3] / 255.0
for color in range(0, 3):
frame[:,:,color] = alpha_foreground * foreground[:,:,color] \
alpha_frame * frame[:,:,color] * (1 - alpha_foreground)
I would recommend
alpha_foreground = foreground[:,:,3] / 255.0
alpha_frame = (1 - alpha_foreground) * (frame[:,:,3] / 255.0)
for color in range(0, 3):
frame[:,:,color] = alpha_foreground * foreground[:,:,color] \
alpha_frame * frame[:,:,color]
Which saves a element-wise multiplication in the loop. And then, if you want to avoid the loop, it'd try:
alpha_foreground = np.zeros((4, foreground.shape[0], foreground.shape[1]))
alpha_foreground[:, :, :] = foreground[:,:,3] / 255.0
alpha_foreground = alpha_foreground.transpose((1, 2, 0))
alpha_frame = np.zeros((4, frame.shape[0], frame.shape[1]))
alpha_frame[:, :, :] = frame[:,:,3] / 255.0
alpha_frame = alpha_frame.transpose((1, 2, 0)) * (1 - alpha_foreground)
frame = alpha_foreground * foreground alpha_frame * frame
The numpy broadcasting rules makes it so that if you want to broadcast a 2D array in a 3D array, the dimensions that should match are the last two.
This is correct: n*m broadcasted to k*n*m
This is not: n*m broadcasted to n*m*k
Thus, the fastest solution for broadcasting n*m to n*m*k is to create a k*n*m empty array, broadcast the n*m array and transpose the dimensions.
Careful, a simple .transpose() will turn k*n*m into m*n*k, which isn't what we want, so we have to pass a transposition to .transpose()