Próbuję użyć matplotlib
do odczytania obrazu RGB i przekonwertowania go na skalę szarości.
W Matlabie używam tego:
img = rgb2gray(imread('image.png'));
W samouczku matplotlib nie obejmują tego. Po prostu czytają na obrazku
import matplotlib.image as mpimg
img = mpimg.imread('image.png')
a następnie wycinają tablicę, ale to nie to samo, co konwersja RGB na skalę szarości z tego, co rozumiem.
lum_img = img[:,:,0]
Trudno mi uwierzyć, że numpy lub matplotlib nie ma wbudowanej funkcji do konwersji z rgb na grey. Czy to nie jest powszechna operacja przetwarzania obrazu?
Napisałem bardzo prostą funkcję, która działa z obrazem zaimportowanym za imread
5 minut. Jest to okropnie nieefektywne, ale dlatego liczyłem na wbudowane profesjonalne wdrożenie.
Sebastian poprawił moją funkcję, ale nadal mam nadzieję znaleźć wbudowaną.
Implementacja matlaba (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
python
matplotlib
waspinator
źródło
źródło
gray = np.mean(rgb, -1)
. Możergb[...,:3]
tam, jeśli to rzeczywiście rgba.gray = np.mean(rgb, -1)
działa dobrze. dzięki. Czy jest jakiś powód, aby tego nie używać? Dlaczego miałbym zamiast tego korzystać z rozwiązań zawartych w poniższych odpowiedziach?np.mean(rgb, -1)
.0.2989 * R + 0.5870 * G + 0.1140 * B
Zakładam, że to standardowy sposób na zrobienie tego.Odpowiedzi:
Co powiesz na robienie tego z Pillow :
Korzystanie z matplotlib i formuły
mógłbyś:
źródło
matplotlib
z innego powodu, powinien móc użyć wbudowanegocolorsys.rgb_to_yiq()
do transformacji oraz plastra, aby uzyskać tylko kanał luma..convert('LA')
? dlaczego nie.convert('gray')
? Wydaje się niepotrzebnie tajemniczy. Dokumentacja PIL nie wspomina nic o „LA” dla funkcji konwersji.cannot write mode LA as JPEG
musiałem używać trybu L, a nie LAimg = Image.open('image.png').convert('LA')
musi byćimg = Image.open('image.png').convert('L')
LA
tryb ma jasność (jasność) i alfa. Jeśli użyjeszLA
trybu,greyscale.png
będzie to obraz RGBA z zachowanym kanałem alfaimage.png
. Jeśli użyjeszL
trybu,greyscale.png
będzie to obraz RGB (bez alfa).Możesz także użyć scikit-image , który udostępnia niektóre funkcje do konwersji obrazu
ndarray
, na przykładrgb2gray
.Uwagi : Odważniki zastosowane w tej konwersji są kalibrowane dla współczesnych luminoforów CRT: Y = 0,2125 R + 0,7154 G + 0,0721 B
Alternatywnie możesz odczytać obraz w skali szarości poprzez:
źródło
cmap
jakogray' then only the image is shown as gray in
pyplot.imshow () `? Jakieś pomysły ? Gdzie się mylę?Trzy z sugerowanych metod przetestowano pod kątem prędkości przy 1000 obrazów PNG RGBA (224 x 256 pikseli) działających z Pythonem 3.5 na Ubuntu 16.04 LTS (Xeon E5 2670 z dyskiem SSD).
Średni czas pracy
pil :
1.037 sekundscipy:
1.040 sekundsk :
2.120 sekundPIL i SciPy dały identyczne
numpy
tablice (od 0 do 255). SkImage podaje tablice od 0 do 1. Ponadto kolory są konwertowane nieco inaczej, patrz przykład z zestawu danych CUB-200.SkImage:
PIL :
SciPy :
Original:
Diff :
Kod
Występ
źródło
Zawsze możesz odczytać plik obrazu w skali szarości od samego początku, używając
imread
OpenCV:Ponadto, jeśli chcesz odczytać obraz jako RGB, przeprowadź przetwarzanie, a następnie przekonwertuj na skalę szarą, której możesz użyć
cvtcolor
z OpenCV:źródło
0
Flaga jestcv2.CV_LOAD_IMAGE_GRAYSCALE
.Najszybszym i aktualnym sposobem jest użycie poduszki , zainstalowanej za pośrednictwem
pip install Pillow
.Kod jest wtedy:
źródło
convert
zwraca przekonwertowaną kopię obrazuSamouczek oszukuje, ponieważ zaczyna się od obrazu w skali szarości zakodowanego w RGB, więc wycinają tylko jeden kanał koloru i traktują go jako skalę szarości. Podstawowe kroki, które musisz zrobić, to przekształcić z przestrzeni kolorów RGB w przestrzeń kolorów, która koduje się z czymś zbliżonym do modelu luma / chroma, takim jak YUV / YIQ lub HSL / HSV, a następnie odciąć kanał podobny do luma i użyć tego jako twój obraz w skali szarości.
matplotlib
nie wydaje się zapewniać mechanizmu konwersji do YUV / YIQ, ale umożliwia konwersję do HSV.Spróbuj użyć,
matplotlib.colors.rgb_to_hsv(img)
a następnie wyciąć ostatnią wartość (V) z tablicy dla skali szarości. Nie jest to dokładnie to samo co wartość luma, ale oznacza, że możesz to wszystko zrobićmatplotlib
.Tło:
Alternatywnie możesz użyć PIL lub wbudowanego
colorsys.rgb_to_yiq()
do konwersji do przestrzeni kolorów z prawdziwą wartością luma. Możesz także zagrać za wszystko i rzucić własny konwerter tylko dla lumy, choć to prawdopodobnie przesada.źródło
Za pomocą tej formuły
Możemy zrobić
Jednak oprogramowanie GIMP do konwersji kolorów na obrazy w skali szarości ma trzy algorytmy do wykonania tego zadania.
źródło
Jeśli używasz już NumPy / SciPy, równie dobrze możesz użyć :
scipy.ndimage.imread(file_name, mode='L')
źródło
scipy.ndimage.imread()
iscipy.misc.imread()
są formalnie niezalecane w scipy 1.0.0 i zostaną trwale usunięte w scipy 1.2.0. Podczas gdy dokumentacja SciPy zalecaimageio.imread()
jako odpowiedni zamiennik, API tej funkcji jest gołe aż do absurdu. Zapewnia on żadnego wsparcia dla skali szarości nawrócenia i pozostaje zatem nadają się do wielu zastosowań - w tym nasze.</sigh>
mógłbyś:
źródło
Użyj img.Convert (), obsługuje „L”, „RGB” i „CMYK”. tryb
Wynik:
źródło
img = img.convert('L')
?Przyszedłem do tego pytania za pośrednictwem Google, szukając sposobu na konwersję już załadowanego obrazu na skalę szarości.
Oto sposób, aby to zrobić za pomocą SciPy:
źródło
img_gray = numpy.average(img, weights=[0.299, 0.587, 0.114], axis=2)
numpy.average
nieco szybsze, ale praktycznie inne. Twoje rozwiązanie jest jasne i zawiera istotne informacje na temat R, G, B, więc chciałbym je zachować. Mój komentarz był raczej dodatkową opcją, a nie zamiennikiem.scipy.ndimage.imread()
iscipy.misc.imread()
są formalnie niezalecane w scipy 1.0.0 i zostaną trwale usunięte w scipy 1.2.0. Prawdopodobnie po prostu chcesz użyć skali szarości wbudowane wsparcie konwersji na poduszce (ala unutbu „s odpowiedź ), zamiast.Możesz użyć
greyscale()
bezpośrednio do transformacji.źródło