簡體   English   中英

與參考相比,為什么我的圖像過濾器的結果看起來太強了?

[英]Why does the result of my image filter look too strong, compared to reference?

在我的計算機視覺 class 中,我被要求從 scatch 編寫我的卷積代碼,並使用 Pillow 來測試我的結果。 我用 Scipy 驗證了我的卷積結果,除了在邊界處它們是一致的,此時我不太在意。 然后我將一些圖像轉換為 numpy arrays,應用卷積,並使用 Image.fromarray 將其轉換回圖像,我發現我的結果與直接使用 Image.filter 確實不同。 這是我正在使用的圖像之一: 在此處輸入圖像描述

Image.filter 給我在此處輸入圖像描述 我認為這很好。 當我自己做卷積並使用 Image.fromarray 時,它給了我在此處輸入圖像描述

我不確定哪里出了問題。 有人可以幫我嗎? 任何提示表示贊賞!

from PIL import Image
from PIL import ImageFilter
import sys
import numpy as np
from scipy.signal import convolve2d
from PIL import ImageCms


def convolve2d_color(A,B):
    # A is the convolution kernel
    # B is matrix representing RGB. B.shape = (n,m,3)
    result = np.zeros(B.shape)
    for i in range(3):
        result[:, :, i] = convolve2d( B[:,:, i], A, 'same', 'fill' )
    return result

im = Image.open(sys.argv[1])


C = np.zeros((3,3))
C[1][0] = -1
C[1][-1] = 1

# doing convolution to images

im_arr = np.asarray(im)/255.0
# print(im_arr[:,:,0])
im_conv = convolve2d_color(C, im_arr)
# print(im_conv[:,:,0])
print(np.uint8(im_conv[1:-1,1:-1,1]*255))
im_output = Image.fromarray(np.uint8(im_conv*255), mode="RGB")
profile = ImageCms.createProfile("sRGB")
im_output.save("save1.png", icc_profile=ImageCms.ImageCmsProfile(profile).tobytes())

profile = ImageCms.createProfile("sRGB")
im_pillow = im.filter(ImageFilter.Kernel((3,3), list(C.reshape(9,)), 1))
print(np.array(im_pillow)[1:-1,1:-1,1])
im_pillow.save("save2.png", icc_profile=ImageCms.ImageCmsProfile(profile).tobytes())

運行python3 pyfile.py image.jpg查看結果。 我還打印了一些矩陣:

# My convolution
[[246 246 236 ...   0 254 253]
 [247 247 238 ... 255 254 255]
 [248 249 236 ...   0 254 254]
 ...
 [252 252 252 ...   0  14   4]
 [  2   0 254 ...   8  20   2]
 [  2   1 255 ...  12  14 253]]
# Image.filter
[[10 10 20 ...  1  2  3]
 [ 9  9 19 ...  2  2  1]
 [ 8  7 20 ...  1  2  2]
 ...
 [ 5  5  4 ...  0  0  0]
 [ 0  0  2 ...  0  0  0]
 [ 0  0  1 ...  0  0  3]]

許多條目加起來是 256,但有些不是。

主要問題涉及im_convuint8的轉換。
如果不將像素值限制在[0, 255]范圍內,負值在轉換為uint8時會溢出為高正值。

正確的轉換應用按 255 縮放、舍入、裁剪到 [0, 255] 並轉換為uint8

im_conv_as_uint8 = np.uint8(np.round(im_conv*255).clip(0, 255))

為了使用 Pillow 獲得相同的結果,我們必須左右翻轉 kernel 矩陣。
我在文檔中找不到它,但根據過濾后的 output,在將其轉換為列表之前應將其左右翻轉:

C = C[:, ::-1]  # Flip left/right
im_pillow = im.filter(ImageFilter.Kernel((3, 3), list(C.reshape(9,)), 1))

以下代碼示例顯示 SciPy 和 Pillow 的輸出相等(邊距除外):

from PIL import Image
from PIL import ImageFilter
import sys
import numpy as np
from scipy.signal import convolve2d
from PIL import ImageCms


def convolve2d_color(A, B):
    # A is the convolution kernel
    # B is matrix representing RGB. B.shape = (n,m,3)
    result = np.zeros(B.shape)
    for i in range(3):
        result[:, :, i] = convolve2d(B[:, :, i], A, 'same', 'fill')
    return result

im = Image.open('parrot.jpg')


C = np.zeros((3,3))
C[1][0] = -1
C[1][-1] = 1

# doing convolution to images

im_arr = np.asarray(im)/255.0
# print(im_arr[:,:,0])
im_conv = convolve2d_color(C, im_arr)
# print(im_conv[:,:,0])
im_conv_as_uint8 = np.uint8(np.round(im_conv*255).clip(0, 255))
print(im_conv_as_uint8[1:-1,1:-1,1])
im_output = Image.fromarray(im_conv_as_uint8, mode="RGB")
profile = ImageCms.createProfile("sRGB")
im_output.save("save1.png", icc_profile=ImageCms.ImageCmsProfile(profile).tobytes())


C = C[:, ::-1]  # Flip left/right (required for getting correct result of im.filter)

profile = ImageCms.createProfile("sRGB")
im_pillow = im.filter(ImageFilter.Kernel((3, 3), list(C.reshape(9,)), 1))
print(np.array(im_pillow)[1:-1,1:-1,1])
im_pillow.save("save2.png", icc_profile=ImageCms.ImageCmsProfile(profile).tobytes())


# Check for equality (ignore the margins)
is_equal = np.array_equal(np.array(im_pillow)[1:-1,1:-1,1], im_conv_as_uint8[1:-1,1:-1,1])
print(is_equal) # True

im_conv_as_uint8
在此處輸入圖像描述


筆記:
將負值剪裁為零會得到與 Pillow 相同的 output,但這可能不是最佳解決方案(因為我們正在丟失數據)。

我們可以應用從范圍 [-1, 1] 到 [0, 255] 的線性變換:

im_conv_as_uint8 = np.uint8(np.round((im_conv+1)/2*255).clip(0, 255))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM