【问题标题】:RGB to Grayscale (Average Method) PythonRGB 转灰度(平均法)Python
【发布时间】:2020-10-27 08:43:30
【问题描述】:

我应该编写一个方法,通过使用“平均方法”将 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 仍然是颜色时(三通道)。这条线显然解决了这个问题。不过现在好像有什么问题?

【问题讨论】:

  • img 是一个矩阵(或np.ndarray)。 p 是该矩阵的一行(也是np.ndarray 类型)。矩阵行没有方法getRed()。相反,你需要做getRed(p)

标签: python rgb grayscale


【解决方案1】:

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

相关行的 Python 等效项是:

for p in img:

不需要声明对象类或类似的东西。

编辑:在 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 时,您似乎不再从事面向对象编程!像素不再带有您可以这样调用的方法。

但是,正如 Guimoute 在 cmets 中指出的那样,如果您摆脱 get[Color] 函数并执行以下操作,代码会更简单:

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

【讨论】:

  • 等一下。 OP 将问题编辑成一个完全不同的问题。
  • 哦,谢谢!我继续编辑了那部分代码。我还编辑了问题的底部,以表明我现在遇到了一个新错误。它说“AttributeError:'numpy.ndarray'对象没有属性'getRed'”。我在问题中写了更多关于它的想法。如果你碰巧知道如何纠正这个问题,请告诉我。
  • 哦,抱歉,我偏离了你所说的内容,并稍作改动以显示我的进度并完全显示新错误。
  • 不,一切都好。我只是害怕了一会儿,因为我以为我回复错了人!我编辑了我的答案以解决您现在遇到的问题。
  • 似乎这些函数甚至都不需要(它们返回字符串),grey = sum(p)/3; for n in range(3): p[n] = grey 应该可以工作。
猜你喜欢
  • 2014-11-29
  • 1970-01-01
  • 1970-01-01
  • 2019-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-29
  • 1970-01-01
相关资源
最近更新 更多