Open CV - Python RGB 转换为灰度

3 投票
2 回答
2028 浏览
提问于 2025-04-17 13:16

我想自己写一个把RGB颜色转换成灰度图的程序,不想用Open-CV里面的现成函数。我的代码是这样的:

import cv2 , numpy
def GrayConvertor(img):


    rows , cols , layers = img.shape

    matrix = numpy.zeros((rows , cols))

    for i in range(rows):
        for j in range(cols):
            val = 0.114 * (img[i][j][0]) + 0.587 * (img[i][j][1]) + 0.299 * (img[i][j][2])
            fraction = val - int(val)
            if fraction >= 0.5:
                matrix[i][j] = (int(val) + 1) 

            else: 
                matrix[i][j] = int(val) 
    cv2.imshow("gray" , matrix)
    cv2.waitKey(0)

但是运行后却显示了一张空白的图片,有什么建议吗?

2 个回答

0

尝试一下:

import cv2 , numpy
def GrayConvertor(img):


    rows , cols , layers = img.shape

    matrix = numpy.zeros((rows , cols))

    for i in range(rows):
        for j in range(cols):
            val = 0.114 * (img[i][j][0]) + 0.587 * (img[i][j][1]) + 0.299 * (img[i][j][2])
                matrix[i][j] = round(val) 
    cv2.imshow("gray" , matrix)
    cv2.waitKey(0)
5

当你用 np.zeros 创建你的 matrix 数组时,默认情况下它的类型是 dtype=float。这意味着即使你把数值四舍五入并转换成 int,当你把它们写入 matrix 时,它们仍然会以 float 的形式存储。如果你查看 关于 cv.imshow 的文档,你会发现以下内容:

  • 如果图像是32位浮点数,像素值会被乘以255。也就是说,值的范围 [0,1] 会被映射到 [0,255]。

所以你图像中的所有内容都被乘以了255,这样就搞乱了你的最终结果。

你可以做两件事:

  1. 保持 matrix 为浮点数,跳过所有的四舍五入,并把你的值除以255。
  2. 明确地用 dtype='uint8' 创建你的 matrix,这样一切都保持不变。

另外,你的代码使用了numpy的能力却很不高效。上面给你的两个选项,你可以在没有循环或矩阵赋值的情况下来实现,像这样:

rgb2k = np.array([0.114, 0.587, 0.299])
matrix_int = np.round(np.sum(img * rgb2k, axis=-1)).astype('uint8')
matrix_float = np.sum(img * rgb2k, axis=-1) / 255

撰写回答