Вот один из способов сделать это, размывая маску в Python / OpenCV.
- Чтение ввода
- Преобразование в серый
- Порог для создания mask
- Размыть маску и растянуть так, чтобы 127,5 перешел на 0, а 255 остался на 255
- Преобразовать маску для плавания в диапазоне от 0 до 1
- Умножить входное значение на замаскировать и преобразовать обратно в 8-битное целое число и обрезать в диапазоне от 0 до 255
- Сохранить результаты
Ввод:
import cv2
import numpy as np
import skimage.exposure
# load image
img = cv2.imread('man.jpg')
# convert to gray
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# threshold
thresh = cv2.threshold(gray, 16, 255, cv2.THRESH_BINARY)[1]
# blur threshold image
blur = cv2.GaussianBlur(thresh, (0,0), sigmaX=5, sigmaY=5, borderType = cv2.BORDER_DEFAULT)
# stretch so that 255 -> 255 and 127.5 -> 0
mask = skimage.exposure.rescale_intensity(blur, in_range=(127.5,255), out_range=(0,255)).astype(np.float32) / 255
mask = cv2.merge([mask,mask,mask])
# replace alpha channel in input with new alpha channel
result = (mask * img).clip(0,255).astype(np.uint8)
# save output
cv2.imwrite('man_thresh.png', thresh)
cv2.imwrite('man_mask.png', mask)
cv2.imwrite('man_antialiased.png', result)
# Display various images to see the steps
cv2.imshow('gray',gray)
cv2.imshow('thresh', thresh)
cv2.imshow('mask', mask)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Пороговое изображение:
Изображение маски:
Результат: