Jython将图片转换为灰度,然后将其否定

时间:2013-06-17 22:40:05

标签: python jython grayscale invert jes

请耐心等待,我几周前才开始使用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中定义它们,它将给出灰度值。

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

问题是:

如何创建名称并获取原始(红色,绿色,蓝色)的值,然后我可以在另一个函数中使用它们?我尝试的所有东西都返回了改变的(灰度)值。日Thnx

4 个答案:

答案 0 :(得分:4)

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

您在程序中使用(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 

....... enter image description here {.................. {0}} ............ ....... enter image description here ........


代码:

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

........ enter image description here {....................... {0}} ...... ................... enter image description here ...........

答案 1 :(得分:3)

您需要在每个像素的某处存储r1g1b1值 - 在grayScale函数中,值将被写入循环的每次迭代,最后,当方法完成时,变量超出范围,根本无法访问。因此,如果您想稍后使用它们,您需要以某种方式存储它们 - 对于原始图像的每个像素。

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

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

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)和{{1}使用Python的original_pixels函数

为了完整起见,我想指出这个代码不应该用于在真实应用程序中操作真实图像 - 应该使用专门的图像处理库。

答案 2 :(得分: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

答案 3 :(得分: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')

更简单