Я пытаюсь создать фильтр Sepia с использованием OpenCV и filter2D с ядром, однако из того, что я вижу, результаты, которые я получаю таким образом, отличаются от ручной реализации с вложенным for-l oop. Мое понимание cv.filter2D кажется "выключенным", и я надеюсь, что кто-то сможет просветить меня, где мои мысли идут наперекосяк ...
Изображение представляет собой маленькое изображение размером 10 x 10 пикселей (легко проверить на content) с небольшим количеством синего и белого. Подход для OpenCV состоит в том, чтобы создать ядро с соответствующими весами для пикселя, однако, думаю, я понял это неправильно. Ядро имеет следующий формат:
kernel = np.array([[0.272, 0.534, 0.131],
[0.349, 0.686, 0.168],
[0.393, 0.769, 0.189]])
return cv2.filter2D(image, -1, kernel)
Прохождение изображения, которое приводит к яркому желтому цвету вместо ожидаемого коричневого тона. При ручном подходе с использованием упомянутых вложенных циклов for я делаю это следующим образом:
dimensions = image.shape
newR=np.zeros([dimensions[0],dimensions[1]])
newG=np.zeros([dimensions[0],dimensions[1]])
newB=np.zeros([dimensions[0],dimensions[1]])
for x in range(0, dimensions[0]):
for y in range(0, dimensions[1]):
newR[x,y] = int(0.272*r[x,y]+0.534*g[x,y]+0.131*b[x,y])
newG[x,y] = int(0.349*r[x,y]+0.686*g[x,y]+0.168*b[x,y])
newB[x,y] = int(0.393*r[x,y]+0.769*g[x,y]+0.189*b[x,y])
if newR[x,y]>255:
newR[x,y]=255
if newG[x,y]>255:
newG[x,y]=255
if newB[x,y]>255:
newB[x,y]=255
output_man = cv2.merge ( (newR, newG, newB) )
Затем создается изображение ожидаемых коричневых sh цветов.
Я ожидал, что filter2D для свертки пикселей исходного изображения так же, как и в моем ручном коде, но мне кажется, что я чего-то упускаю и надеюсь на некоторые указатели.
Первоначально я читал в * .png, но для работоспособный пример Я создаю изображение в отдельной функции. Вот полный python -скрипт, который показывает два разных результата:
import cv2
import numpy as np
import scipy
def create_image():
r_arr= np.array(
[[255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 0],
[255, 255, 255, 255, 255, 255, 255, 0, 0, 0],
[255, 255, 255, 255, 255, 0, 0, 0, 0, 0],
[255, 255, 255, 255, 0, 0, 0, 0, 0, 0],
[255, 255, 0, 0, 0, 0, 0, 0, 0, 0],
[255, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 255, 255],
[ 0, 0, 0, 0, 0, 0, 0, 255, 255, 255],
[ 0, 0, 0, 0, 0, 255, 255, 255, 255, 255]]
, dtype = np.uint8)
g_arr= np.array(
[[255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 162],
[255, 255, 255, 255, 255, 255, 255, 162, 162, 162],
[255, 255, 255, 255, 255, 162, 162, 162, 162, 162],
[255, 255, 255, 255, 162, 162, 162, 162, 162, 162],
[255, 255, 162, 162, 162, 162, 162, 162, 162, 162],
[255, 162, 162, 162, 162, 162, 162, 162, 162, 162],
[162, 162, 162, 162, 162, 162, 162, 162, 255, 255],
[162, 162, 162, 162, 162, 162, 162, 255, 255, 255],
[162, 162, 162, 162, 162, 255, 255, 255, 255, 255]]
,dtype = np.uint8)
b_arr= np.array(
[[255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
[255, 255, 255, 255, 255, 255, 255, 255, 255, 232],
[255, 255, 255, 255, 255, 255, 255, 232, 232, 232],
[255, 255, 255, 255, 255, 232, 232, 232, 232, 232],
[255, 255, 255, 255, 232, 232, 232, 232, 232, 232],
[255, 255, 232, 232, 232, 232, 232, 232, 232, 232],
[255, 232, 232, 232, 232, 232, 232, 232, 232, 232],
[232, 232, 232, 232, 232, 232, 232, 232, 255, 255],
[232, 232, 232, 232, 232, 232, 232, 255, 255, 255],
[232, 232, 232, 232, 232, 255, 255, 255, 255, 255]]
,dtype = np.uint8)
art_image=cv2.merge((r_arr, g_arr, b_arr))
return art_image
def sepia(image):
#Calculations for every pixel:
# new R-value = tr = int(0.393 * r + 0.769 * g + 0.189 * b) but maxed at 255
# new G-value = tg = int(0.349 * r + 0.686 * g + 0.168 * b) but maxed at 255
# new B-value = tb = int(0.272 * r + 0.534 * g + 0.131 * b) but maxed at 255
#This block is original for RGB
kernel = np.array([[0.272, 0.534, 0.131],
[0.349, 0.686, 0.168],
[0.393, 0.769, 0.189]])
return cv2.filter2D(image, -1, kernel)
######################################################################
######################################################################
######################################################################
#image = cv2.imread("10x10.png")
image = create_image()
dimensions = image.shape
b, g, r = cv2.split(image)
output_image=sepia(image)
dimensions = image.shape
newR=np.zeros([dimensions[0],dimensions[1]])
newG=np.zeros([dimensions[0],dimensions[1]])
newB=np.zeros([dimensions[0],dimensions[1]])
for x in range(0, dimensions[0]):
for y in range(0, dimensions[1]):
newR[x,y] = int(0.272*r[x,y]+0.534*g[x,y]+0.131*b[x,y])
newG[x,y] = int(0.349*r[x,y]+0.686*g[x,y]+0.168*b[x,y])
newB[x,y] = int(0.393*r[x,y]+0.769*g[x,y]+0.189*b[x,y])
if newR[x,y]>255:
newR[x,y]=255
if newG[x,y]>255:
newG[x,y]=255
if newB[x,y]>255:
newB[x,y]=255
output_man = cv2.merge ( (newR, newG, newB) )
b2, g2, r2 = cv2.split(output_image)
print(r)
print("--------")
print(g)
print("--------")
print(b)
print("--------")
print("--------")
print(r2)
print("--------")
print(g2)
print("--------")
print(b2)
print("--------")
print("--------")
print(newR)
print("--------")
print(newG)
print("--------")
print(newB)
print("--------")
cv2.imwrite("10x10_m.png", output_man)
cv2.imwrite("10x10_f.png", output_image)