web-dev-qa-db-de.com

Wie kann ich ein RGB-Bild in Python in Graustufen konvertieren?

Ich versuche, mit matplotlib ein RGB-Bild einzulesen und in Graustufen umzuwandeln.

In Matlab verwende ich dies:

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

Im Matplotlib-Tutorial decken sie es nicht ab. Sie lesen gerade im Bild

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

und dann schneiden sie das Array, aber das ist nicht das Gleiche wie das Konvertieren von RGB in Graustufen von dem, was ich verstehe.

lum_img = img[:,:,0]

Es fällt mir schwer zu glauben, dass Numpy oder Matplotlib keine eingebaute Funktion haben, um von RGB nach Grau zu konvertieren. Ist das nicht eine übliche Operation in der Bildverarbeitung?

Ich habe eine sehr einfache Funktion geschrieben, die mit dem mit imread importierten Bild in 5 Minuten funktioniert. Es ist schrecklich ineffizient, aber deshalb habe ich auf eine professionelle Implementierung gehofft.

Sebastian hat meine Funktion verbessert, aber ich hoffe immer noch, die eingebaute zu finden.

implementierung von 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
153
waspinator

Wie wäre es mit Kissen :

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

Mit matplotlib und die Formel

Y' = 0.2989 R + 0.5870 G + 0.1140 B 

du könntest es tun:

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()
235
unutbu

Sie können auch scikit-image verwenden, das einige Funktionen bietet, um ein Bild in ndarray zu konvertieren, wie rgb2gray.

from skimage import color
from skimage import io

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

Hinweise : Die bei dieser Umrechnung verwendeten Gewichte sind für zeitgenössische CRT-Leuchtstoffe kalibriert: Y = 0,2125 R + 0,7154 G + 0,0721 B

Alternativ können Sie das Bild in Graustufen lesen, indem Sie:

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

Drei der vorgeschlagenen Methoden wurden mit 1000 RGBA PNG-Bildern (224 x 256 Pixel) auf Geschwindigkeit getestet, die mit Python 3.5 auf Ubuntu 16.04 LTS (Xeon E5 2670 mit SSD) ausgeführt wurden.

Durchschnittliche Laufzeiten

pil : 1,037 Sekunden

scipy: 1,040 Sekunden

sk : 2,120 Sekunden

PIL und SciPy ergaben identische numpy Arrays (von 0 bis 255). SkImage gibt Arrays von 0 bis 1 aus. Außerdem werden die Farben geringfügig anders konvertiert, siehe Beispiel aus dem CUB-200-Datensatz.

SkImage:SkImage

PIL :PIL

SciPy :SciPy

Original:Original

Diff :enter image description here

Code

  1. Performance

    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)

    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)
    </ code>

    für k, v in run_times.items (): print ('{: 5}: {: 0.3f} seconds'.format (k, sum (v)/len (v)))
  2. Ausgabe
    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. Vergleich
    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. Importe
    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. Versionen
    skimage.version
    0.13.0
    scipy.version
    0.19.1
    np.version
    1.13.1
    
42

Mit imread von OpenCV können Sie die Bilddatei immer von Anfang an in Graustufen lesen:

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

Wenn Sie das Bild als RGB lesen möchten, führen Sie eine Verarbeitung durch und konvertieren Sie es dann in Graustufen. Verwenden Sie dazu cvtcolor von OpenCV:

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

Die schnellste und aktuellste Möglichkeit ist die Verwendung von Pillow , installiert über pip install Pillow.

Der Code lautet dann:

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

Das Tutorial schummelt, weil es mit einem in RGB codierten Graustufenbild beginnt. Sie schneiden also nur einen einzelnen Farbkanal und behandeln ihn als Graustufen. Die grundlegenden Schritte, die Sie ausführen müssen, sind, den RGB-Farbraum in einen Farbraum umzuwandeln, der in etwa mit dem Luma/Chroma-Modell codiert, z Ihr Graustufenbild. matplotlib bietet anscheinend keinen Mechanismus für die Konvertierung in YUV/YIQ, ermöglicht jedoch die Konvertierung in HSV.

Versuchen Sie es mit matplotlib.colors.rgb_to_hsv(img) und schneiden Sie dann den letzten Wert (V) aus dem Array für Ihre Graustufen. Es ist nicht ganz dasselbe wie ein Luma-Wert, aber es bedeutet, dass Sie alles in matplotlib tun können.

Hintergrund:

Alternativ können Sie PIL oder die integrierte Funktion colorsys.rgb_to_yiq() verwenden, um einen Farbraum mit einem echten Luma-Wert zu konvertieren. Sie könnten auch all-in gehen und Ihren eigenen Luma-only-Konverter rollen, obwohl das wahrscheinlich übertrieben ist.

11
Silas Ray

Wenn Sie NumPy/SciPy bereits verwenden, können Sie auch verwenden :

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

6
dtk

Mit diese Formel

Y' = 0.299 R + 0.587 G + 0.114 B 

Wir können es tun

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'))

Die GIMP Konvertierung von Farbe in Graustufen-Bildsoftware verfügt jedoch über drei Algorithmen, um diese Aufgabe zu erledigen.

6
iNet

Verwenden Sie img.Convert (). Unterstützt die Modi "L", "RGB" und "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)

Ausgabe:

[[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]]
4
naren

du könntest es tun:

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

        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()
4
am.mansour

Ich bin über Google auf diese Frage gekommen und habe nach einer Möglichkeit gesucht, ein bereits geladenes Bild in Graustufen umzuwandeln.

Hier ist eine Möglichkeit, dies mit SciPy zu tun:

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)
3
Martin Thoma