简体   繁体   English

使用 numpy 将图像转换为灰度

[英]Converting an image to grayscale using numpy

I have an image represented by a numpy.array matrix nxm of triples (r,g,b) and I want to convert it into grayscale, , using my own function.我有一个由三元组(r,g,b)numpy.array矩阵nxm表示的图像,我想使用我自己的函数将其转换为灰度。

My attempts fail converting the matrix nxmx3 to a matrix of single values nxm , meaning that starting from an array [r,g,b] I get [gray, gray, gray] but I need gray .我的尝试无法将矩阵nxmx3转换为单值矩阵nxm ,这意味着从数组[r,g,b]我得到[gray, gray, gray]但我需要gray

ie Initial colour channel : [150 246 98] .即初始颜色通道: [150 246 98] After converting to gray : [134 134 134] .转换为灰色后: [134 134 134] What I need : 134我需要什么: 134

How can I achieve that?我怎样才能做到这一点?

My code:我的代码:

def grayConversion(image):
    height, width, channel = image.shape
    for i in range(0, height):
        for j in range(0, width):
            blueComponent = image[i][j][0]
            greenComponent = image[i][j][1]
            redComponent = image[i][j][2]
            grayValue = 0.07 * blueComponent + 0.72 * greenComponent + 0.21 * redComponent
            image[i][j] = grayValue
    cv2.imshow("GrayScale",image)
    return image

Here is a working code:这是一个工作代码:

def grayConversion(image):
    grayValue = 0.07 * image[:,:,2] + 0.72 * image[:,:,1] + 0.21 * image[:,:,0]
    gray_img = grayValue.astype(np.uint8)
    return gray_img

orig = cv2.imread(r'C:\Users\Jackson\Desktop\drum.png', 1)
g = grayConversion(orig)

cv2.imshow("Original", orig)
cv2.imshow("GrayScale", g)
cv2.waitKey(0)
cv2.destroyAllWindows()

You can use a dot product:您可以使用点积:

gray_image = image.dot([0.07, 0.72, 0.21])

Or even just do the whole operation manually:或者甚至只是手动完成整个操作:

b = image[..., 0]
g = image[..., 1]
r = image[..., 2]
gray_image = 0.21 * r + 0.72 * g + 0.07 * b

Don't forget to convert back to 0-255:不要忘记转换回 0-255:

gray_image = np.min(gray_image, 255).astype(np.uint8)

Solution using apply_along_axis使用apply_along_axis解决方案

A solution can be achieved by using apply_along_axis :一个解决方案可以通过使用apply_along_axis来实现:

import numpy as np
def grayscale(colors):
    """Return grayscale of given color."""
    r, g, b = colors
    return 0.07 * r + 0.72 * g + 0.21 * b

image = np.random.uniform(255, size=(10,10,3))
result = np.apply_along_axis(grayscale, 2, image)

Examples例子

10x10 image 10x10 图像

We can now proceed to visualise the results:我们现在可以继续可视化结果:

from matplotlib import pyplot as plt
plt.subplot(1,2,1)
plt.imshow(image)
plt.subplot(1,2,2)
plt.imshow(result, cmap='gray')

示例结果

Textual example (2x2 image)文本示例(2x2 图像)

To visualise the actual results in text I will use a smaller array, just a 2x2 image:为了在文本中可视化实际结果,我将使用一个较小的数组,只是一个2x2 的图像:

image = np.random.uniform(250, size=(2,2,3))

The content is:内容是:

array([[[205.02229826, 109.56089703, 163.74868594],
    [ 11.13557763, 160.98463727, 195.0294515 ]],

   [[218.15273335,  84.94373737, 197.70228018],
    [ 75.8992683 , 224.49258788, 146.74468294]]])

Let's convert it to grayscale, using our custom function:让我们使用我们的自定义函数将其转换为灰度:

result = np.apply_along_axis(grayscale, 2, image)

And the output of the conversion is:转换的输出是:

array([[127.62263079, 157.64461409],
   [117.94766108, 197.76399547]])

We can visualise this simple example too, using the same code as above:我们也可以使用与上面相同的代码来可视化这个简单的例子:

较小的例子

Further suggestions进一步的建议

If you want to apply your own custom function, then apply_along_axis is the way to go, but you should consider using purer numpy approaches such as the one suggested by Eric or, if possible, just load the black and white image using cv2 option:如果您想应用自己的自定义函数,那么apply_along_axisapply_along_axis的方法,但您应该考虑使用更纯的 numpy 方法,例如Eric建议的方法,或者如果可能,只需使用cv2选项加​​载黑白图像:

cv2.imread('smalltext.jpg',0)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM