问题
I have an image of a boat and I need to fulfill with colour individual zones according to the value of the sensor. Up to this moment I have created two separated zones in .png format and I want to show them at the same time, putting them on a basic boat image.
My code:
import cv2
import numpy as np
from PIL import Image
import time
bg = cv2.imread("boat.png")
#RGB = np.zeros((2178, 2904, 3), dtype=np.uint8)
#zone11
zone11 = cv2.imread(r'C:\Users\Lenovo\Anaconda3\Programy\Obszary\11.png')
#zone12
zone12 = cv2.imread(r'C:\Users\Lenovo\Anaconda3\Programy\Obszary\12.png')
combined = np.maximum.reduce([zone11, zone12])
cv2.imwrite('combined.png',combined)
cv2.imshow('combined',combined)
#cv2.imshow('bg',bg)
cv2.waitKey(5)
time.sleep(5)
cv2.destroyAllWindows();
The problem is that np.maximum.reduce gives me both zones on one image, but with black background and it gives me kernell error...
How to save them without black background? And how to put them on a basic boat image? In future zones will show once in 1 sec and they will be different in every sequence, how can I paste the zones in one sequence and unpaste them before the next one?
I will appreciate every help, I'm very new to the graphics and python.
Imgur images: 1. Boat https://imgur.com/cA9slkZ 2. Combined https://imgur.com/lKxLxgN 3. Zone 12 https://imgur.com/zIVgoZh 4. Zone 11 https://imgur.com/PMUGWW6
回答1:
In order to combine the zones, you want to take the brightest pixel at each point, which will give you the combined zones on a black background:
# "zones" will contain all the zones combined together by choosing the brightest pixel at each point
zones = np.maximum.reduce([zone11, zone12])
Now we want to find all locations where any of the colour channels are non-zero, i.e. all the non-black areas.
# "alpha" will be True where the zones are activated
alpha = np.any(zones>0, axis=2)
Then, for the final result you want to choose the combined zones where they are active, and the boat elsewhere:
# For the final result, pick the zones at locations where they contain stuff, and the boat anywhere else
res = np.where(alpha[...,np.newaxis], zones, boat)
# Save result to disk
cv2.imwrite('result.png', res)
As regards doing it all every second, you just make a copy of the boat image that you loaded outside the loop at the start of the program, create the zones and lay them onto the copy:
# Load boat once at startup
boat_orig = cv2.imread("boat.png")
# Main loop
while not sunk:
boat = boat_orig.copy()
zones = np.maximum.reduce([zone11, zone12])
alpha = np.any(zones>0, axis=2)
res = np.where(alpha[...,np.newaxis], zones, boat)
Those 4 lines in the inner loop run in around 400ms on my machine, and 200ms of that is the line:
alpha = np.any(zones>0, axis=2)
which you may find you can change to:
alpha = zones[...,2]
because there will always be something in the red channel (assuming your zones are orangey red) and that reduces the 200ms to under 1ms.
来源:https://stackoverflow.com/questions/61139701/python-cv2-numpy-combining-two-images