【问题标题】:rgb values and pixelsRGB 值和像素
【发布时间】:2020-03-30 07:13:34
【问题描述】:

def normalize_brightness(img: Image) -> Image: """

 Normalize the brightness of the given Image img by:
  1. 计算图片的平均亮度: - 这可以通过计算每个像素的平均亮度来完成 在 img 中(每个像素的平均亮度是值的总和 像素的红色、蓝色和绿色,除以 3 作为浮点除法) - 图片的平均亮度是所有亮度的总和 像素平均值,除以img的宽度和高度的乘积

  2. 找到因子,我们称它为 x,我们可以乘以 平均亮度为 128。

  3. 将每个像素中的颜色乘以这个因子 x """

    img_width, img_height = img.size
    pixels = img.load()  # create the pixel map
    h = 0
    for i in range(img_width):
        for j in range(img_height):
            r, g, b = pixels[i, j]
            avg = sum(pixels[i, j]) / 3
            h += avg
    total_avg = int(h / (img_width * img_height))
    x = 128 // total_avg
    r, g, b = pixels[i, j]
    pixels[i, j] = (r * x, g * x, b * x)
    return img
    

    我对自己做错了什么感到有些迷茫,有人可以帮忙吗?

【问题讨论】:

标签: python python-imaging-library


【解决方案1】:

在使用 Python 进行图像处理时,您确实应该尽可能避免 for 循环,因为它非常缓慢、冗长、难以阅读并且更可能包含错误。尝试使用向量化的 Numpy 函数,或 OpenCV 或 PIL 内置函数。

#!/usr/bin/env python3

from PIL import Image
import numpy as np

def normalize(im):
   """Normalise brightness of image"""

   # Convert to Numpy array
   na = np.array(im, dtype=np.float32)

   # Calculate average brightness
   avg = na.mean()

   # Calculate factor x
   x = 128 / avg

   # Scale whole array as float since likely fractional
   na *= x

   # Convert back to PIL Image and return
   return Image.fromarray(na.astype(np.uint8))

# Load image and normalize
im = Image.open('start.png').convert('RGB')
result = normalize(im)
result.save('result.png')

这段代码在我的机器上运行大约 800 微秒,而任何带有 for 循环的版本都需要大约 70 倍的时间。

输入图片:

结果:

【讨论】:

    【解决方案2】:

    您获取因子的计算代码似乎没问题,处理每个像素以获得平均值总和的平均值。

    但是,您用于调整亮度的 修改 代码不是在类似的循环中完成的,因此它将在 一个 像素上运行,我什至不确定该像素甚至在图像中。您也应该在循环中执行此操作:

    for i in range(img_width):
        for j in range(img_height):
            (r, g, b) = pixels[i, j]
            pixels[i, j] = (r * x, g * x, b * x)
    

    这应该替换您目前拥有的内容的倒数第三行和倒数第二行(在x = ...return ... 之间)。所以你最终会得到的是:

    img_width, img_height = img.size
    pixels = img.load()  # create the pixel map
    h = 0
    for i in range(img_width):
        for j in range(img_height):
            r, g, b = pixels[i, j]
            avg = sum(pixels[i, j]) / 3
            h += avg
    total_avg = int(h / (img_width * img_height))
    x = 128 // total_avg
    
    # == New stuff below
    for i in range(img_width):
        for j in range(img_height):
            (r, g, b) = pixels[i, j]
            pixels[i, j] = (r * x, g * x, b * x)
    # == New stuff above
    
    return img
    

    需要注意的其他一些事项:

    首先,我不确定在这里返回img 是否正确,除非pixels 是对图像中像素的引用(而不是副本)。您可能也想检查一下。

    此外,对于某些输入数据集,[rgb] * x 的值可能为您提供超过 255 的值。如果是这种情况,您可能希望将它们限制在0..255 范围内,以确保不会发生这种情况。类似的东西(替换上面代码中的“新东西”):

    for i in range(img_width):
        for j in range(img_height):
            # Get original pixel.
    
            (r, g, b) = pixels[i, j]
    
            # Scale with upper limit.
    
            r = min(255, r * x)
            g = min(255, g * x)
            b = min(255, b * x)
    
            # Replace pixel with scaled one.
    
            pixels[i, j] = (r, g, b)
    

    【讨论】:

    • 是的,因为由于某种原因,当我将修改放在嵌套的 for 循环中时,我得到一个零除法错误
    • @Jack,你不能把它放在 current 循环集中,因为你会除以尚未设置的total_avg。你需要另一个循环集。
    • 所以基本上当我进行修改时,我只是修改(total_avg)一个像素的平均值,而不是所有像素的总平均值?如果是这样,for 循环将如何解决这个问题?
    • @Jack,for 循环和 whree 已添加到答案中。
    • 在哪里?我仍然只看到它之前的版本
    【解决方案3】:

    首先感谢paxdiablo 分享他的答案。

    我只想改进答案。

    可以使用列表理解来优化平均值的计算,例如:

    x = 128 // (sum([sum(pixels[i, j]) / 3 for i in range(img_width) for j in range(img_height)]) / (img_width * img_height))

    所以我的完整答案是:

    标准化给定图像的亮度

    img_width, img_height = img.size
    pixels = img.load()  # create the pixel map
    
    x = 128 // (sum([sum(pixels[i, j]) / 3 for i in range(img_width) for j in range(img_height)]) / (img_width * img_height))
    
    for i in range(img_width):
        for j in range(img_height):
            r, g, b = pixels[i, j]
            pixels[i, j] = [min(255, r * x), min(255, g * x), min(255, b * x)]
    
    return img
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-14
      • 2015-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多