Вот один из способов использования OpenCV, Numpy и Skimage.Я предполагаю, что на самом деле у вас есть изображение с прозрачным фоном, а не просто шахматный рисунок.
Ввод:
import cv2
import numpy as np
import skimage.exposure
# load image with alpha channel
img = cv2.imread('lena_circle.png', cv2.IMREAD_UNCHANGED)
# extract only bgr channels
bgr = img[:, :, 0:3]
# extract alpha channel
a = img[:, :, 3]
# blur alpha channel
ab = cv2.GaussianBlur(a, (0,0), sigmaX=2, sigmaY=2, borderType = cv2.BORDER_DEFAULT)
# stretch so that 255 -> 255 and 127.5 -> 0
aa = skimage.exposure.rescale_intensity(ab, in_range=(127.5,255), out_range=(0,255))
# replace alpha channel in input with new alpha channel
out = img.copy()
out[:, :, 3] = aa
# save output
cv2.imwrite('lena_circle_antialias.png', out)
# Display various images to see the steps
# NOTE: In and Out show heavy aliasing. This seems to be an artifact of imshow(), which did not display transparency for me. However, the saved image looks fine
cv2.imshow('In',img)
cv2.imshow('BGR', bgr)
cv2.imshow('A', a)
cv2.imshow('AB', ab)
cv2.imshow('AA', aa)
cv2.imshow('Out', out)
cv2.waitKey(0)
cv2.destroyAllWindows()
Я ни в коем случае не эксперт в OpenCV.Я посмотрел на cv2.normalize (), но это не выглядело так, как будто я мог предоставить свои собственные наборы входных и выходных значений.Поэтому я также попытался использовать следующее добавление отсечения, чтобы убедиться, что нет переполнений или недопотоков:
aa = a*2.0 - 255.0
aa[aa<0] = 0
aa[aa>0] = 255
, где я вычислил это из решения одновременных уравнений таким образом, что в = 255 становитсяout = 255 и in = 127.5 становится out = 0 и выполняет линейное растяжение между:
C = A*X+B
255 = A*255+B
0 = A*127.5+B
Thus A=2 and B=-127.5
Но это работает не так хорошо, как лыжный маг rescale_intensity.