簡體   English   中英

如何在 Python 中將 RGB 圖像轉換為灰度?

[英]How can I convert an RGB image into grayscale in Python?

我正在嘗試使用matplotlib讀取 RGB 圖像並將其轉換為灰度。

在matlab中我使用這個:

img = rgb2gray(imread('image.png'));

matplotlib 教程中,他們沒有涵蓋它。 他們只是在圖像中閱讀

import matplotlib.image as mpimg
img = mpimg.imread('image.png')

然后他們對數組進行切片,但這與根據我的理解將 RGB 轉換為灰度不同。

lum_img = img[:,:,0]

我發現很難相信 numpy 或 matplotlib 沒有內置函數來從 rgb 轉換為灰色。 這不是圖像處理中的常見操作嗎?

我編寫了一個非常簡單的函數,可以在 5 分鍾內處理使用imread導入的圖像。 這是非常低效的,但這就是我希望內置專業實現的原因。

Sebastian 改進了我的功能,但我仍然希望找到內置功能。

matlab (NTSC/PAL) 的實現:

import numpy as np

def rgb2gray(rgb):

    r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
    gray = 0.2989 * r + 0.5870 * g + 0.1140 * b

    return gray

Pillow做這個怎么樣:

from PIL import Image
img = Image.open('image.png').convert('L')
img.save('greyscale.png')

如果輸入圖像中存在 alpha(透明)通道並應保留,請使用模式LA

img = Image.open('image.png').convert('LA')

使用 matplotlib 和公式

Y' = 0.2989 R + 0.5870 G + 0.1140 B 

你可以這樣做:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

def rgb2gray(rgb):
    return np.dot(rgb[...,:3], [0.2989, 0.5870, 0.1140])

img = mpimg.imread('image.png')     
gray = rgb2gray(img)    
plt.imshow(gray, cmap=plt.get_cmap('gray'), vmin=0, vmax=1)
plt.show()

您還可以使用scikit-image ,它提供了一些函數來轉換ndarray的圖像,例如rgb2gray

from skimage import color
from skimage import io

img = color.rgb2gray(io.imread('image.png'))

注意:此轉換中使用的權重針對當代 CRT 熒光粉進行校准:Y = 0.2125 R + 0.7154 G + 0.0721 B

或者,您可以通過以下方式讀取灰度圖像:

from skimage import io
img = io.imread('image.png', as_gray=True)

在 Ubuntu 16.04 LTS(帶 SSD 的 Xeon E5 2670)上使用 Python 3.5 運行 1000 張 RGBA PNG 圖像(224 x 256 像素),對三種建議的方法進行了速度測試。

平均運行時間

pil : 1.037 秒

scipy: 1.040 秒

sk : 2.120 秒

PIL 和 SciPy 給出了相同的numpy數組(范圍從 0 到 255)。 SkImage 給出了從 0 到 1 的數組。此外,顏色轉換略有不同,參見CUB-200 數據集的示例

SkImage: 圖像

PIL : PIL

SciPy : SciPy

Original: 原來的

Diff : 在此處輸入圖片說明

代碼

  1. 表現

    run_times = dict(sk=list(), pil=list(), scipy=list()) for t in range(100): start_time = time.time() for i in range(1000): z = random.choice(filenames_png) img = skimage.color.rgb2gray(skimage.io.imread(z)) run_times['sk'].append(time.time() - start_time)

    \n\n
    start_time = time.time() for i in range(1000): z = random.choice(filenames_png) img = np.array(Image.open(z).convert('L')) run_times['pil'].append(time.time() - start_time) start_time = time.time() for i in range(1000): z = random.choice(filenames_png) img = scipy.ndimage.imread(z, mode='L') run_times['scipy'].append(time.time() - start_time)
    \n\n

    對於 k, v in run_times.items(): print('{:5}: {:0.3f} seconds'.format(k, sum(v) / len(v)))

  2. 輸出
    z = 'Cardinal_0007_3025810472.jpg' img1 = skimage.color.rgb2gray(skimage.io.imread(z)) * 255 IPython.display.display(PIL.Image.fromarray(img1).convert('RGB')) img2 = np.array(Image.open(z).convert('L')) IPython.display.display(PIL.Image.fromarray(img2)) img3 = scipy.ndimage.imread(z, mode='L') IPython.display.display(PIL.Image.fromarray(img3))
  3. 比較
    img_diff = np.ndarray(shape=img1.shape, dtype='float32') img_diff.fill(128) img_diff += (img1 - img3) img_diff -= img_diff.min() img_diff *= (255/img_diff.max()) IPython.display.display(PIL.Image.fromarray(img_diff).convert('RGB'))
  4. 進口
    import skimage.color import skimage.io import random import time from PIL import Image import numpy as np import scipy.ndimage import IPython.display
  5. 版本
    skimage. version 0.13.0 scipy. version 0.19.1 np. version 1.13.1

您始終可以使用 OpenCV 中的imread從一開始imread圖像文件讀取為灰度:

img = cv2.imread('messi5.jpg', 0)

此外,如果您想將圖像讀取為 RGB,請進行一些處理然后轉換為灰度,您可以使用 OpenCV 中的cvtcolor

gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

最快和當前的方法是使用Pillow ,通過pip install Pillow

然后代碼是:

from PIL import Image
img = Image.open('input_file.jpg').convert('L')
img.save('output_file.jpg')

該教程是作弊的,因為它從以 RGB 編碼的灰度圖像開始,因此他們只是將單個顏色通道切片並將其視為灰度。 您需要做的基本步驟是從 RGB 顏色空間轉換為使用近似亮度/色度模型(例如 YUV/YIQ 或 HSL/HSV)進行編碼的顏色空間,然后切掉類似亮度的通道並將其用作你的灰度圖像。 matplotlib似乎沒有提供轉換為 YUV/YIQ 的機制,但它確實可以讓您轉換為 HSV。

嘗試使用matplotlib.colors.rgb_to_hsv(img)然后從數組中切出最后一個值 (V) 以獲得灰度。 它與亮度值並不完全相同,但這意味着您可以在matplotlib完成所有操作。

背景:

或者,您可以使用 PIL 或內置colorsys.rgb_to_yiq()轉換為具有真實亮度值的色彩空間。 您也可以全力以赴並推出自己的僅亮度轉換器,盡管這可能有點矯枉過正。

使用這個公式

Y' = 0.299 R + 0.587 G + 0.114 B 

我們可以做的

import imageio
import numpy as np
import matplotlib.pyplot as plt

pic = imageio.imread('(image)')
gray = lambda rgb : np.dot(rgb[... , :3] , [0.299 , 0.587, 0.114]) 
gray = gray(pic)  
plt.imshow(gray, cmap = plt.get_cmap(name = 'gray'))

但是, GIMP將顏色轉換為灰度圖像軟件具有三種算法來完成任務。

如果您已經在使用 NumPy/SciPy,您也可以使用

scipy.ndimage.imread(file_name, mode='L')

你可以這樣做:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

def rgb_to_gray(img):
        grayImage = np.zeros(img.shape)
        R = np.array(img[:, :, 0])
        G = np.array(img[:, :, 1])
        B = np.array(img[:, :, 2])

        R = (R *.299)
        G = (G *.587)
        B = (B *.114)

        Avg = (R+G+B)
        grayImage = img.copy()

        for i in range(3):
           grayImage[:,:,i] = Avg
           
        return grayImage       

image = mpimg.imread("your_image.png")   
grayImage = rgb_to_gray(image)  
plt.imshow(grayImage)
plt.show()

使用 img.Convert(),支持“L”、“RGB”和“CMYK”。 模式

import numpy as np
from PIL import Image

img = Image.open("IMG/center_2018_02_03_00_34_32_784.jpg")
img.convert('L')

print np.array(img)

輸出:

[[135 123 134 ...,  30   3  14]
 [137 130 137 ...,   9  20  13]
 [170 177 183 ...,  14  10 250]
 ..., 
 [112  99  91 ...,  90  88  80]
 [ 95 103 111 ..., 102  85 103]
 [112  96  86 ..., 182 148 114]]

我通過谷歌來到這個問題,尋找一種將已經加載的圖像轉換為灰度的方法。

這是使用 SciPy 執行此操作的一種方法:

import scipy.misc
import scipy.ndimage

# Load an example image
# Use scipy.ndimage.imread(file_name, mode='L') if you have your own
img = scipy.misc.face()

# Convert the image
R = img[:, :, 0]
G = img[:, :, 1]
B = img[:, :, 2]
img_gray = R * 299. / 1000 + G * 587. / 1000 + B * 114. / 1000

# Show the image
scipy.misc.imshow(img_gray)

使用 OpenCV 很簡單:

import cv2

im = cv2.imread("flower.jpg")

# To Grayscale
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
cv2.imwrite("grayscale.jpg", im)

# To Black & White
im = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY)[1]
cv2.imwrite("black-white.jpg", im)

在此處輸入圖片說明

當所有 3 個顏色通道 (RGB) 中的像素值都相同時,該像素將始終為灰度格式。

將 RGB 圖像轉換為灰度圖像的一種簡單直觀的方法是取每個像素中所有顏色通道的平均值並將值分配回該像素。

import numpy as np
from PIL import Image

img=np.array(Image.open('sample.jpg')) #Input - Color image
gray_img=img.copy()

for clr in range(img.shape[2]):
    gray_img[:,:,clr]=img.mean(axis=2) #Take mean of all 3 color channels of each pixel and assign it back to that pixel(in copied image)

#plt.imshow(gray_img) #Result - Grayscale image

輸入圖像: 輸入圖像

輸出圖像: 輸出圖像

image=myCamera.getImage().crop(xx,xx,xx,xx).scale(xx,xx).greyscale()

您可以直接使用greyscale()進行轉換。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM