【问题标题】:How do I do the equivalent of Gimp's Colors, Auto, White Balance in Python-Fu?如何在 Python-Fu 中做相当于 Gimp 的颜色、自动、白平衡?
【发布时间】:2018-06-24 09:12:35
【问题描述】:

我能找到的唯一函数是:gimp-color-balance,它采用适用的参数:preserve-lum(osity)、青色-红色、洋红色-绿色和黄色-蓝色。

我不确定为这些参数传递什么值以复制标题中的菜单选项。

【问题讨论】:

标签: python scripting gimp


【解决方案1】:

根据我在快速查看源代码后的理解(并且或多或少地通过测试图像确认),这些是无关的并且在幕后,Colors>Auto>White Balance

  • 获取每个通道的直方图
  • 获取确定底部和顶部 0.6% 的值
  • 使用与“级别”非常相似的内部调用,使用这两个值作为黑点和白点来扩展该通道的值范围。

用合成图像证明:

之前:

之后:

这一切在 Python 中并不难做到。

【讨论】:

  • 既然你发布了一张测试图片,你一定是自己用某种语言写过代码。您能否将其发布为我基于 python 代码的指南?我对 python 的经验有限。
  • 我发布的图片只是展示了Auto>White balance在测试图片上的效果。如果你想要 Python 中的示例 Gimp 脚本,请参阅 hereofn-average-fill 使用 gimp_histogram())。如果您想要一个完整的实现,请参阅 DoyourSketch2 的答案。如果您想要一个能够正确执行所有操作的真正白平衡脚本,请参阅this,但您必须在图像中指定一种颜色,该颜色应为中性灰色(即 R==G==B)。
【解决方案2】:

K,酷。想出了如何编写脚本。
如果您喜欢,请使用它。我没问题。

https://github.com/doyousketch2/eAWB

【讨论】:

  • 我想通了,你写的:)
  • 你的“答案”没有告诉我任何我不知道的事情。这更像是一个没有答案的答案,真的。仅仅因为你放了图片并没有解释任何新的东西。我知道 GIMP 是如何实现这些价值的。我的问题是:是否有调用它的函数。显然没有。你基本上说自己写。所以我做到了。
  • 你只是在证明我的观点。我的问题是:“什么功能叫自动白平衡??”我想你是把我和这个问题的海报混淆了。
【解决方案3】:

根据GIMP doc,我们需要丢弃红色、绿色和蓝色直方图两端的像素颜色,这些直方图仅被图像中0.05%的像素使用,并尽可能拉伸剩余范围(Python 代码):

import numpy as np
import cv2  # opencv-python
import matplotlib.pyplot as plt


img = cv2.imread('test.jpg')
x = []
# get histogram for each channel
for i in cv2.split(img):
    hist, bins = np.histogram(i, 256, (0, 256))
    # discard colors at each end of the histogram which are used by only 0.05% 
    tmp = np.where(hist > hist.sum() * 0.0005)[0]
    i_min = tmp.min()
    i_max = tmp.max()
    # stretch hist
    tmp = (i.astype(np.int32) - i_min) / (i_max - i_min) * 255
    tmp = np.clip(tmp, 0, 255)
    x.append(tmp.astype(np.uint8))

# combine image back and show it
s = np.dstack(x)
plt.imshow(s[::,::,::-1])

结果与 GIMP 的“颜色 -> 自动 -> 白平衡”之后的结果非常相似

UPD:我们需要np.clip(),因为OpenCVnumpy 不同地将int32 转换为uint8:

# Numpy
np.array([-10, 260]).astype(np.uint8)
>>> array([246,   4], dtype=uint8)
# but we need just [0, 255]

【讨论】:

    【解决方案4】:

    为了完成@banderlog013的答案,我认为Gimp Doc指定首先丢弃每个通道的结束像素,然后拉伸剩余的范围。我相信正确的代码是:

    img = cv2.imread('test.jpg')
    balanced_img = np.zeros_like(img) #Initialize final image
    
    for i in range(3): #i stands for the channel index 
        hist, bins = np.histogram(img[..., i].ravel(), 256, (0, 256))
        bmin = np.min(np.where(hist>(hist.sum()*0.0005)))
        bmax = np.max(np.where(hist>(hist.sum()*0.0005)))
        balanced_img[...,i] = np.clip(img[...,i], bmin, bmax)
        balanced_img[...,i] = (balanced_img[...,i]-bmin) / (bmax - bmin) * 255
    

    我用它取得了很好的效果,试试吧!

    【讨论】:

    • 别忘了安装opencv并先致电import cv2!有关安装说明,请参见此处:stackoverflow.com/questions/51853018/….
    • 也许我很久以前就编辑了我的答案,但我的代码完全按照你所说的工作
    【解决方案5】:

    如何从本质上获得相当于 GIMP 的 Colors --> Auto --> White Balance 功能:

    在 Ubuntu 20.04 上测试。

    从我的eRCaGuy_hello_world repo 下载以下代码:python/auto_white_balance_img.py

    安装依赖:

    pip3 install opencv-python  # for cv2
    pip3 install numpy
    

    现在这里有一些功能齐全的代码,不像这里的其他一些答案是 sn-ps 并且缺少诸如 import 语句之类的东西。我向@Canette Ouverture's answer here@banderlog013's answer here借钱。

    创建文件auto_white_balance_img.py

    #!/usr/bin/python3
    
    import cv2
    import numpy as np
    
    file_in = 'test.jpg'
    
    file_in_base = file_in[:-4] # strip file extension
    file_in_extension = file_in[-4:]
    
    img = cv2.imread(file_in)
    
    # From @banderlog013's answer: https://stackoverflow.com/a/54864315/4561887
    x = []
    # get histogram for each channel
    for i in cv2.split(img):
        hist, bins = np.histogram(i, 256, (0, 256))
        # discard colors at each end of the histogram which are used by only 0.05%
        img_out1 = np.where(hist > hist.sum() * 0.0005)[0]
        i_min = img_out1.min()
        i_max = img_out1.max()
        # stretch hist
        img_out1 = (i.astype(np.int32) - i_min) / (i_max - i_min) * 255
        img_out1 = np.clip(img_out1, 0, 255)
        x.append(img_out1.astype(np.uint8))
    
    # From @Canette Ouverture's answer: https://stackoverflow.com/a/56365560/4561887
    img_out2 = np.zeros_like(img) # Initialize final image
    for channel_index in range(3):
        hist, bins = np.histogram(img[..., channel_index].ravel(), 256, (0, 256))
        bmin = np.min(np.where(hist>(hist.sum()*0.0005)))
        bmax = np.max(np.where(hist>(hist.sum()*0.0005)))
        img_out2[...,channel_index] = np.clip(img[...,channel_index], bmin, bmax)
        img_out2[...,channel_index] = ((img_out2[...,channel_index]-bmin) / 
            (bmax - bmin) * 255)
    
    # Write new files
    cv2.imwrite(file_in_base + '_out1' + file_in_extension, img_out1)
    cv2.imwrite(file_in_base + '_out2' + file_in_extension, img_out2)
    

    使 auto_white_balance_img.py 可执行:

    chmod +x auto_white_balance_img.py
    

    现在将上面文件中的file_in 变量设置为您想要的输入图像路径,然后运行它:

    python3 auto_white_balance_img.py
    # OR
    ./auto_white_balance_img.py
    

    假设你设置了file_in = 'test.jpg',它会产生这两个文件:

    1. test_out1.jpg # 来自@banderlog013's answer here 的结果
    2. test_out2.jpg # 来自@Canette Ouverture's answer here 的结果

    【讨论】:

      猜你喜欢
      • 2019-09-12
      • 1970-01-01
      • 1970-01-01
      • 2014-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多