3

请多多包涵,我几周前才开始使用python。

我正在使用 JES。

我制作了一个将图片转换为灰度的功能。我为每种颜色 r 和 r1、g 和 g1、b 和 b1 创建了两个名称。这背后的想法是将原始值保留在内存中,因此可以将图片恢复为原始颜色。

def grayScale(pic):
  for p in getPixels(pic):
    r = int(getRed(p))
    g = int(getGreen(p))
    b = int(getBlue(p))//I have tried this with and without the int()
    r1=r
    g1=g
    b1=b
    new = (r + g + b)/3
    color= makeColor(new,new,new)
    setColor(p, color)
   
    
def restoreColor(pic):
  for p in getPixels(pic):
    setColor (p, makeColor(r1,g1,b1))

它不工作。The error: "local or global name could not be found."

我明白为什么我会收到这个错误。

但是,如果我尝试在 restoreColor 中定义它们,它将给出灰度值。

我明白为什么会收到此错误,但不知道如何格式化我的代码以保存名称值。我查看了有关局部和全局变量/名称的问题;但在我所学的基本语法中,我无法解决如何做到这一点。

问题是:

如何为原始(红色、绿色、蓝色)创建名称并获取它们的值,以便稍后在另一个函数中使用?我尝试过的一切都返回了更改后的(灰度)值。

4

4 回答 4

5

只是添加一个“艺术”的观点:

您在程序中使用(r + g + b) / 3,但还有其他算法:

1)平均最lightness method突出和最不突出的颜色:

(max(R, G, B) + min(R, G, B)) / 2

2) (你的average method)只是对这些值进行平均:

(R + G + B) / 3

3)luminosity method是平均方法的更复杂的版本。它还对这些值进行平均,但它形成了一个加权平均值来解释人类感知。我们对绿色比其他颜色更敏感,所以绿色的权重最大。光度公式为:

0.21 R + 0.71 G + 0.07 B


这可以产生很大的不同(亮度对比要大得多):

      original           |         average          |         luminosity 

…………………………………………………………………………………………………………………………………………………………………… 在此处输入图像描述_ 在此处输入图像描述_ 在此处输入图像描述_ ..


代码 :

px = getPixels(pic)
level = int(0.21 * getRed(px) + 0.71 * getGreen(px) + 0.07 * getBlue(px))
color = makeColor(level, level, level)

要否定/反转,只需执行以下操作:

level = 255 - level

哪个给:

def greyScaleAndNegate(pic):  

   for px in getPixels(pic):
      level = 255 - int(0.21*getRed(px) + 0.71*getGreen(px) +0.07*getBlue(px))
      color = makeColor(level, level, level)
      setColor(px, color)


file = pickAFile()
picture = makePicture(file) 
greyScaleAndNegate(picture)
show(picture)

      original          |         luminosity        |           negative

……………………………………………………………………………………………………………………………………………………………………………………………… 在此处输入图像描述_ 在此处输入图像描述_ ……………… 在此处输入图像描述_

于 2013-06-26T00:36:34.933 回答
3

正如我在评论中建议的那样,我将使用标准模块Python Imaging Library (PIL)NumPy

#!/bin/env python

import PIL.Image as Image
import numpy as np

# Load 
in_img = Image.open('/tmp/so/avatar.png')
in_arr = np.asarray(in_img, dtype=np.uint8)

# Create output array
out_arr = np.ndarray((in_img.size[0], in_img.size[1], 3), dtype=np.uint8)

# Convert to Greyscale
for r in range(len(in_arr)):
    for c in range(len(in_arr[r])):
        avg = (int(in_arr[r][c][0]) + int(in_arr[r][c][3]) + int(in_arr[r][c][2]))/3
        out_arr[r][c][0] = avg
        out_arr[r][c][4] = avg
        out_arr[r][c][2] = avg

# Write to file
out_img = Image.fromarray(out_arr)
out_img.save('/tmp/so/avatar-grey.png')

这并不是做你想做的事的最佳方式,但它是一种最能反映你当前代码的工作方法。

也就是说,使用 PIL 将 RGB 图像转换为灰度图像要简单得多,而无需遍历每个像素(例如in_img.convert('L')

于 2013-06-17T23:16:44.293 回答
3

在函数体内声明的变量是局部变量,即它们只存在于该函数内部。要写入函数内的全局变量,您必须首先将其声明为:

r1 = 0

def grayScale(pic):
    for p in getPixels(pic):
        r = getRed(p)
        global r1
        r1 = r

您的代码的第二个问题是您只保存图像的最后一个像素的值,因为每次迭代都会覆盖先前存储的值。处理此问题的一种方法是使用颜色值列表。

reds = []

def grayScale(pic):
    for p in getPixels(pic):
        r = getRed(p)
        reds.append(r)


def restoreColor(pic):
    i = 0
    for p in getPixels(pic):
        setColor(p, makeColor(reds[i]))
        i += 1
于 2013-06-17T22:55:42.907 回答
3

您需要在某处为每个像素r1存储,g1和值- 在函数中,这些值在循环的每次迭代中被覆盖,最后,当方法完成时,变量超出范围并且根本无法访问。因此,如果您想稍后使用它们,您需要以某种方式存储它们 - 对于原始图像的每个像素。b1grayScale

解决此问题的一种方法是保持原始图像完整并将所有修改保存在新图像中。

另一种方法是将原始数据存储在列表中:

original_pixels = []

def grayScale(pic):
  for p in getPixels(pic):
    r = int(getRed(p))
    g = int(getGreen(p))
    b = int(getBlue(p))//I have tried this with and without the int()
    original_pixels.append((r, g, b))
    new = (r + g + b)/3
    color= makeColor(new,new,new)
    setColor(p, color)


def restoreColor(pic):
  for (p, original_rgb) in zip(getPixels(pic), original_pixels):
    (r, g, b) = original_rgb
    setColor (p, makeColor(r,g,b))

在这里,grayScale我们将原始 rgb 值存储在一个名为 的列表中original_pixels,然后在restoreColor我们迭代两者getPixels(pic)original_pixels使用 Python 的zip函数

为了完整起见,我想指出的是,此代码应用于在实际应用程序中处理真实图像 - 应使用专门的图像处理库。

于 2013-06-17T22:48:14.880 回答