RGB 转灰度(平均法)Python

RGB to Grayscale (Average Method) Python

我应该编写一种方法,通过使用“平均法”将 RGB 图像转换为灰度图像,我取 3 种颜色的平均值(不是 加权法或光度法)。然后我必须显示原始的 RGB 图像和灰度图像彼此相邻(连接)。我写的语言是Python。这是我的代码目前的样子。

import numpy as np
import cv2

def getRed(redVal):
    return '#%02x%02x%02x' % (redVal, 0, 0)

def getGreen(greenVal):
    return '#%02x%02x%02x' % (0, greenVal, 0)

def getBlue(blueVal):
    return '#%02x%02x%02x' % (0, 0, blueVal)

# Grayscale = (R + G + B / 3)
# For each pixel,
# 1- Get pixels red, green, and blue
# 2- Calculate the average value
# 3- Set each of red, green, and blue values to average value

def average_method(img):
    for p in img:
        red = p.getRed()
        green = p.getGreen()
        blue = p.getBlue()
        average = (red + green + blue) / 3
        p.setRed(average)
        p.setGreen(average)
        p.setBlue(average)

def main():
    img1 = cv2.imread('html/images/sun.jpeg')
    img1 = cv2.resize(img1, (0, 0), None, .50, .50)
    img2 = average_method(img1)
    img2 = np.stack(3 * [img2], axis=2)
    numpy_concat = np.concatenate((img1, img2), 1)
    cv2.imshow('Numpy Concat', numpy_concat)
    cv2.waitKey(0)
    cv2.destroyAllWindows

if __name__ =="__main__":
    main()

average_method 函数中注释的部分是我必须遵循的步骤。

当我尝试 运行 代码时,我得到

  File "test.py", line 38, in <module>
    main()
  File "test.py", line 30, in main
    img2 = average_method(img1)
  File "test.py", line 15, in average_method
    red = p.getRed()
AttributeError: 'numpy.ndarray' object has no attribute 'getRed' 

我认为在上面定义 getRed、getGreen 和 getBlue 的函数意味着它们在我的 average_method 函数中变得可识别(我从网上获得了这些函数,所以我希望它们是正确的) .我也不确定它与 numpy.ndarray 有什么关系。如果有人可以帮助我使用正确遵循注释步骤的代码填写此 average_method 函数,我将不胜感激。

编辑::: 新代码如下所示:

import cv2
import numpy as np

def average_method(img):
    for p in img:
        gray = sum(p)/3
        for i in range(3):
            p[i] = gray

def main():
    img1 = cv2.imread('html/images/sun.jpeg')
    img1 = cv2.resize(img1, (0, 0), None, .50, .50)
    img2 = average_method(img1)
    img2 = np.stack(3 * [img2], axis=2)
    numpy_concat = np.concatenate((img1, img2), 1)
    cv2.imshow('Numpy Concat', numpy_concat)
    cv2.waitKey(0)
    cv2.destroyAllWindows

if __name__ =="__main__":
    main()

我现在得到错误

  File "test.py", line 50, in <module>
    main()
  File "test.py", line 43, in main
    img2 = np.stack(3 * [img2], axis=2)
  File "<__array_function__ internals>", line 5, in stack
  File "C:\Users\myname\AppData\Local\Programs\Python\Python38-32\lib\site-packages\numpy\core\shape_base.py", line 430, in stack
    axis = normalize_axis_index(axis, result_ndim)
numpy.AxisError: axis 2 is out of bounds for array of dimension 1

我有那行“img2 = np.stack(3 * [img2], axis=2)”因为我之前在 Stack Overflow 上被告知我需要它因为我的 img2 现在是灰度(单-通道)图像,当 img1 仍然是彩色(三通道)时。这条线显然解决了这个问题。不过现在好像有点不对劲?

在Java中,您突出显示的for循环称为“增强的for循环”。 Python 没有这些因为 Python for loops pog(就简洁而言)。

相关行的 Python 等效项是:

for p in img:

无需声明对象 class 或类似内容。

编辑:OP 更改问题后

现在的问题是你没有正确调用函数。 p 是包含该像素的 RGB 值的数组。要调用上面定义的函数,请执行以下操作:

for p in img:
    red = getRed(p[0])
    green = getGreen(p[1])
    blue = getBlue(p[2])
    average = (red + green + blue) / 3
    p[0] = average
    p[1] = average
    p[2] = average

请记住,当您将代码移至 Python 时,您似乎不再从事面向对象编程! Pixels 不再提供可以这样调用的方法。

然而,正如 Guimoute 在评论中指出的那样,如果您摆脱 get[Color] 函数并执行以下操作,代码会简单得多:

for p in img:
    gray = sum(p)/3
    for i in range(3):
        p[i] = gray