使用 cv2 混合 2 个图像时如何去除光影边界?
How to remove light shadow border when blending 2 images using cv2?
我尝试使用 cv2 将 2 个图像混合在一起,但得到了一个颜色不同的奇怪边框。
结果图像在亮区和暗区之间有奇怪的黄色边界。我怎样才能删除它?
这是我用来将它们混合在一起的代码:
land = cv2.imread(land_path)
land = cv2.cvtColor(land, cv2.COLOR_BGR2RGB)
land = land.astype(float)
h, w, c = land.shape
sky = cv2.imread(sky_path)
sky = cv2.cvtColor(sky, cv2.COLOR_BGR2RGB)
sky = cv2.resize(sky, (w, h))
sky = sky.astype(float)
mask = cv2.imread(mask_path)
mask = cv2.resize(mask, (w, h))
mask = mask.astype(float)/255
sky = cv2.multiply(mask, sky)
land = cv2.multiply(1.0 - mask, land)
result = cv2.add(sky, land)
cv2.imwrite(result_path, result[:, :, ::-1])
原图:
我得到的结果:
也许可以尝试移除月球周围的黑暗区域。添加 mask[mask<20] = 0
之类的内容可能会对您有所帮助。
编辑:或者您可以使用 opencv 的 alpha blending
或者也许一种叫做毒药混合的东西可以帮助你。通过快速 google 搜索,我找到了这个 repo。
这是 Python/OpenCV 中的一种方法。你的问题是你使用的面具。它应该来自天空图像,以避免来自 horizon 正上方区域的衰减。蒙版中 horizon 正上方的明亮区域被否定时,会导致日落衰减,从而给您带来黑暗区域。
- Read the land and sky images
- Make a version of the sky image as gray
- Convert both the float
- Threshold the gray sky image and antialias by blurring and making black anything below 128.
- Convert mask to float in range 0 to 1 and make it 3 channels.
- Do the blending
- Save the result
陆地图像:
天空图像:
import cv2
import numpy as np
# read land image and convert to float
land = cv2.imread("land.jpg")
land = land.astype(np.float32)
h, w, c = land.shape
# read sky image, crop to same size as previous image, convert copy to gray, convert sky image to float
sky = cv2.imread("sky.jpg")
sky = sky[0:h, 0:w]
gray_sky = cv2.cvtColor(sky, cv2.COLOR_BGR2GRAY)
sky = sky.astype(np.float32)
# make mask by thresholding sky image, antialias, convert to float in range 0 to 1 and make 3 channels
mask = cv2.threshold(gray_sky, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
mask = cv2.GaussianBlur(mask, (0,0), 3, 3)
mask[mask<128] = 0
mask = mask.astype(np.float32)/255
mask = cv2.merge([mask,mask,mask])
# blend and convert back to 8-bit result
result = land * (1 - mask) + sky * mask
result = result.clip(0,255).astype(np.uint8)
# save result
cv2.imwrite("land_sky.jpg", result)
# show results
cv2.imshow("mask", mask)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果:
我尝试使用 cv2 将 2 个图像混合在一起,但得到了一个颜色不同的奇怪边框。 结果图像在亮区和暗区之间有奇怪的黄色边界。我怎样才能删除它? 这是我用来将它们混合在一起的代码:
land = cv2.imread(land_path)
land = cv2.cvtColor(land, cv2.COLOR_BGR2RGB)
land = land.astype(float)
h, w, c = land.shape
sky = cv2.imread(sky_path)
sky = cv2.cvtColor(sky, cv2.COLOR_BGR2RGB)
sky = cv2.resize(sky, (w, h))
sky = sky.astype(float)
mask = cv2.imread(mask_path)
mask = cv2.resize(mask, (w, h))
mask = mask.astype(float)/255
sky = cv2.multiply(mask, sky)
land = cv2.multiply(1.0 - mask, land)
result = cv2.add(sky, land)
cv2.imwrite(result_path, result[:, :, ::-1])
原图:
我得到的结果:
也许可以尝试移除月球周围的黑暗区域。添加 mask[mask<20] = 0
之类的内容可能会对您有所帮助。
编辑:或者您可以使用 opencv 的 alpha blending
或者也许一种叫做毒药混合的东西可以帮助你。通过快速 google 搜索,我找到了这个 repo。
这是 Python/OpenCV 中的一种方法。你的问题是你使用的面具。它应该来自天空图像,以避免来自 horizon 正上方区域的衰减。蒙版中 horizon 正上方的明亮区域被否定时,会导致日落衰减,从而给您带来黑暗区域。
- Read the land and sky images
- Make a version of the sky image as gray
- Convert both the float
- Threshold the gray sky image and antialias by blurring and making black anything below 128.
- Convert mask to float in range 0 to 1 and make it 3 channels.
- Do the blending
- Save the result
陆地图像:
天空图像:
import cv2
import numpy as np
# read land image and convert to float
land = cv2.imread("land.jpg")
land = land.astype(np.float32)
h, w, c = land.shape
# read sky image, crop to same size as previous image, convert copy to gray, convert sky image to float
sky = cv2.imread("sky.jpg")
sky = sky[0:h, 0:w]
gray_sky = cv2.cvtColor(sky, cv2.COLOR_BGR2GRAY)
sky = sky.astype(np.float32)
# make mask by thresholding sky image, antialias, convert to float in range 0 to 1 and make 3 channels
mask = cv2.threshold(gray_sky, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
mask = cv2.GaussianBlur(mask, (0,0), 3, 3)
mask[mask<128] = 0
mask = mask.astype(np.float32)/255
mask = cv2.merge([mask,mask,mask])
# blend and convert back to 8-bit result
result = land * (1 - mask) + sky * mask
result = result.clip(0,255).astype(np.uint8)
# save result
cv2.imwrite("land_sky.jpg", result)
# show results
cv2.imshow("mask", mask)
cv2.imshow("result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果: