【问题标题】:Sepia filter inverting棕褐色过滤器反转
【发布时间】:2021-03-28 09:25:41
【问题描述】:

我堆叠了反相棕褐色滤镜。 反相过滤的结果与预期不符。

我的逻辑如下: processes_pixel = np.dot(sepia_filter, original_pixel)

这意味着: original_pixel = np.dot(np.inverse(sepia_filter), processes_pixel)

这是我尝试过的代码 - 我还尝试了其他几种方法,例如单独反转颜色,然后求解线性方程组,但得到相同的结果,所以我假设我不明白某些东西至关重要。

要求:

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)  

原图

过滤后的图像

Image_after_filter_reversing


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

【问题讨论】:

  • 有什么问题?
  • 问题是mysepia反转算法不能正常工作
  • 你能说得更具体点吗?因为我们无法运行您的代码。您是否收到错误消息或结果不是您所期望的?
  • 抱歉 - 结果与预期不符。
  • 如果将filtered_image 输入inverse_sepia 函数会发生什么?

标签: python algorithm numpy opencv image-processing


【解决方案1】:

一个有趣的问题。
答案可能有点令人失望:棕褐色滤镜在理论上或实际上是可逆的。

理论

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

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)。

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

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

【讨论】:

    【解决方案2】:

    现在您已经修复了代码,小羊已经可以辨认出来了,但是还有很多剪裁。我认为问题在于棕褐色过滤器虽然是可逆的,但几乎是单一的。您可以在SVD 中看到一个奇异值如何比其他奇异值大得多。因此,小的变化,如截断以获得整数值(您可以尝试四舍五入,可能会更好一点)被逆运算放大很多,从而导致看起来不准确的重建。

    【讨论】:

    • 这听起来是一个很好的解释。我已经用更简单的数据尝试了代码并且它有效。所以真正的问题是,你如何让它发挥作用?
    • @mapf 问题是棕褐色过滤器加上舍入是有损的,所以你不能,真的。您可以做的最好的事情可能是在棕褐色滤镜中添加仔细的抖动,然后在逆滤镜之后添加模糊,但我们离我的驾驶室很远。
    • 嗯,很有趣。这给了我一个想法。
    • 好的,所以我太累了,无法自己尝试,但基本上你要做的是,在你将棕褐色滤镜应用到像素后,你将像素与旧像素进行比较以获得应用到它的“实际”矩阵,如在不裁剪的情况下生成新像素的矩阵。然后你将这些信息存储在某个地方。到最后,所有这些“实际”转换的逆应该给你棕褐色过滤器的真正逆。
    • 无论如何,我现在也明白为什么这当然不是微不足道的了。因为要么您不知道棕褐色过滤器并且必须手动对其进行返工,也就是像超级专业工作(或使用 AI)一样的图像恢复,或者您自己应用了过滤器。在这种情况下,您也有原件,因此您不需要反向过滤器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-19
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多