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
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()
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)
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.
Code
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)))
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))
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'))
import skimage.color
import skimage.io
import random
import time
from PIL import Image
import numpy as np
import scipy.ndimage
import IPython.display
skimage.version
0.13.0
scipy.version
0.19.1
np.version
1.13.1
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')
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.
Wenn Sie NumPy/SciPy bereits verwenden, können Sie auch verwenden :
scipy.ndimage.imread(file_name, mode='L')
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.
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]]
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()
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)