Как удалить границу легкой тени при смешивании 2 изображений с использованием cv2?

#python #image #opencv #cv2 #alphablending

#python #изображение #opencv #cv2 #alphablending

Вопрос:

Я попытался смешать 2 изображения вместе с помощью cv2, но получил странную границу с другим цветом. Результирующее изображение имеет странную желтую границу между светлой и темной областями. Как я могу это удалить? Это код, который я использую для их смешивания:

 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])
  

Исходные изображения:

Пейзаж

Небо

Изображение маски

Результат, который я получил:

Результат смешивания

Комментарии:

1. маска не совсем черно-белая, поэтому желтоватое небо с исходного изображения смешивается с конечным изображением. Вы можете получить лучшие результаты, выполнив бинаризацию маски

Ответ №1:

Вот один из способов сделать это в Python / OpenCV. Ваша проблема — маска, которую вы используете. Это должно быть изображение неба, чтобы избежать затухания в области чуть выше горизонта. Светлые области в вашей маске чуть выше горизонта, когда они отрицаются, вызывают ослабление заката, создавая темные области.

  - 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()
  

Результат:

введите описание изображения здесь

Ответ №2:

Возможно, попробуйте удалить темную область вокруг Луны. Добавление чего-то вроде mask[mask<20] = 0 , возможно, поможет вам. редактировать: или вы можете использовать альфа-смешивание opencv или, может быть, вам поможет что-то, называемое poison blending. Выполнив быстрый поиск в Google, я нашел это репозиторий.