乌贼墨滤纸倒置

2024-05-19 02:51:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我用倒置的乌贼墨滤纸叠起来。 反转滤波器的结果与预期不符

我的逻辑如下: 处理后的像素=np.点(深褐色过滤器,原始像素)

这意味着: 原始像素=np.点(np.逆(深褐色过滤器),处理像素)

这是我尝试过的代码——我也尝试过其他几种方法,比如分别反转颜色,然后解一个线性方程组,但得到了相同的结果,所以我假设我不理解一些关键的东西

要求:

import numpy as np
from PIL import Image, ImageDraw

乌贼墨过滤器代码:

def get_pixel_after_sepia(source, pixel, sepia_filter):
    colors = np.array(source.getpixel(pixel)) 
    colors_new = tuple(map(int, np.dot(sepia_filter,colors))) + (255,) #  apply filter, transform results to ints, cut to 255
    return colors_new
                       
def sepia(source, result_name):
    result = Image.new('RGB', source.size)
    sepia_filter = np.array([[0.393,0.769,0.189], [0.349,0.686,0.168], [0.272,0.534,0.131]])

    #  for every pixel                   
    for x in range(source.size[0]):
        for y in range(source.size[1]):
            new_pixel = get_pixel_after_sepia(source, (x,y), sepia_filter)
            result.putpixel((x, y),new_pixel)
            
    result.save(result_name, "JPEG")
    return result

倒乌贼墨代码:

def get_pixel_before_sepia(source, pixel, inversed_sepia_filter):
    colors = np.array(source.getpixel(pixel)) 
    colors_new = tuple(map(int, np.dot(inversed_sepia_filter, colors)))+ (255,)
    return colors_new

def inverse_sepia(image_with_sepia, result_file):
    result = Image.new('RGB', image_with_sepia.size) 
    sepia_filter = np.array([[0.393,0.769,0.189], [0.349,0.686,0.168], [0.272,0.534,0.131]])
    inverse_sepia_filter = np.linalg.inv(sepia_filter)
    
    for x in range(image_with_sepia.size[0]):
        for y in range(image_with_sepia.size[1]):
            new_pixel = get_pixel_before_sepia(image_with_sepia, (x,y), inverse_sepia_filter)
            result.putpixel((x, y),new_pixel)
            
    result.save(result_file, "JPEG")
    return result

功能执行:

image = Image.open("original_image.jpg")
filtered_image = sepia(image, "filtered.jpg") # result_pixel = dot_product(Filter, origin_pixel)  
image_after_filter_reversing = inverse_sepia(filtered_image,'restored.jpg' ) # result_pixel = dot_product(Filter^(-1), filtering_result_pixel)  

原始图像

enter image description here

滤波图像

enter image description here

图像\u在\u过滤器\u反转后

enter image description here


我知道不可能做出完美的反转,因为我们正在切割计算结果并将其四舍五入为int。但我希望反转后的图像与原始图像非常接近。 我是图像处理方面的新手,但数学上的问题对我来说似乎完全有效


Tags: 图像image过滤器sourcenewforsizewith
2条回答

一个有趣的问题。
答案可能有点令人失望:乌贼墨过滤器在理论上或实践中都是不可逆的

理论

代码中使用的数值矩阵为:

0.393   0.769   0.189
0.349   0.686   0.168
0.272   0.534   0.131

相应的符号矩阵为:

 x       y       z
mx      my      mz
nx      ny      nz

其中x=0.393 y=0.769 z=0.189 m=0.89 n=0.69.
当你计算符号矩阵的行列式时,它是零。因此,基质不可逆,乌贼墨过滤器也不可逆

数字矩阵具有非零行列式的事实仅仅是由于数字的精度有限(3位数)。计算数值矩阵的行列式得到0.000000121,本质上是0,加上/减去一些舍入误差

作为旁注,将像素值乘以数字矩阵相当于以下计算

R = 0.393*r + 0.769*g + 0.189*b
G = 0.89*R
B = 0.69*R

其中“rgb”是原始像素值,“rgb”是深褐色像素值

实践

新的《牛津美国词典》将乌贼墨定义为“一种红棕色,尤其与19世纪和20世纪初的单色照片有关”

关键词是单色。乌贼墨编码的是图像中每个像素的视亮度。它不保留原始图像中的颜色信息。这似乎有悖常理,因为深褐色图像中似乎有一些颜色

为了更好地理解,请在代码中尝试以下矩阵

0.291  0.569  0.140
0.291  0.569  0.140
0.291  0.569  0.140

这将把图像转换成灰度图像,也就是黑白图像。像乌贼墨一样,灰度图像只编码每个像素的外观亮度。它不保留任何颜色信息。不同之处在于灰度使用灰色色调作为基色,而乌贼墨使用棕色色调作为基色。你在深褐色图像中看到的其他颜色:橙色、桃色、黄色和黑色只是RGB颜色空间中棕色的不同亮度级别

灰度和乌贼墨的另一个区别是,乌贼墨能够编码更多的亮度。灰度有256个色调的调色板。乌贼墨有346个不同的像素值。原因是剪辑。给定(255, 255, 255)的输入像素,相应的乌贼墨像素在剪裁前为(345, 307, 239),剪裁后为(255, 255, 239)。乌贼墨像素的红色分量在剪切前有346个可能值。对于每个红色值,绿色和蓝色值是成比例的(G=0.89*RB=0.69*R

这是深褐色调色板(减去四个最深的色调):

enter image description here

因此,您面临的实际问题是,原始彩色图像的调色板有1600万种颜色,而乌贼墨图像的调色板只有346种颜色。无法重新创建原始图像,因为深褐色图像中的一个像素对应于原始图像中大约48000种可能颜色中的任何一种

现在您已经修复了代码,羔羊是可以识别的,但是有很多剪辑正在进行。我认为问题在于,虽然乌贼墨过滤器是可逆的,但它几乎是奇异的。你可以在SVD中看到一个奇异值是如何比其他值大得多的。因此,小的更改,如通过截断来获得整数值(您可以尝试取整,可能更好一点)会被反向操作放大很多,这会导致重建的外观不准确

相关问题 更多 >

    热门问题