2013-07-12 16 views
7

Ich versuche, einen Konverter-Algorithmus zu schreiben, der ein JPEG-Bild aufnimmt und seine PGM-Version (Portable Gray Map) zurückgibt. Das Problem ist, dass ich nicht verstehen kann, wie die "offiziellen" JPG-> PGM-Converter in Bezug auf welchen Wert zu dem endgültigen Pixel (ich denke, 0-> 255) ausgehend vom klassischen RGB-Format arbeiten."Standard" RGB zu Graustufen-Konvertierung

Am Anfang habe ich diese Formel (es ist das gleiche von OpenCV der CV_RGB2GRAY Umwandlung verwendet wird):

0,30 * R + 0,59 * G + 0,11 * B = val

Ich schrieb ein einfacher Code zu Testen Sie meine Ergebnisse: Es dauert ein Farbbild und seine PGM-Version (bereits mit GIMP konvertiert). Dann konvertiert es das Farbbild mit der vorherigen Formel. Das Ziel ist ein Graustufenbild, das Pixel zu Pixel gleich der PGM-Eingabe ist.

An diesem Punkt werden nicht die gleichen Werte zurückgegeben. Kannst du mir helfen?

+0

Haben Sie sich schon einmal [wikipedia: Graustufen] (https://en.wikipedia.org/wiki/Grayscale) angesehen? – MrSmith42

+0

Sind Sie sicher, dass es das ist? Was, wenn es nur die Y-Ebene decodiert und die Farbkoeffizienten ignoriert? Sie würden unterschiedliche Geräusche haben, und die Faktoren können unterschiedlich sein. – harold

+0

Entschuldigung, ich verstehe Ihren Post nicht – TheUnexpected

Antwort

5

Das Problem ist, dass ich nicht verstehen kann, wie die "offiziellen" JPG-> PGM Converter in Bezug auf welchen Wert zu den endgültigen Pixel (ich denke, 0 → 255) ausgehend vom Klassiker arbeiten RGB-Format

Es gibt wahrscheinlich eine Gamma-Anpassung bei der Konvertierung, die diese "offiziellen" Tools verwenden.
Das ist es ist nicht nur eine lineare Transformation.

Sehen Sie diese Wikipedia Abschnitt für die Details: Converting color to grayscale

Ich glaube, Sie die Formel für Csrgb verwenden möchten.
Probieren Sie es aus und sehen Sie, ob es mit den Ergebnissen übereinstimmt, die Sie erwarten.

Grundsätzlich werden Sie dies tun:

  1. Nehmen R, G, B Farbe (jeweils in [0,1] Bereich)
    • Wenn sie im Bereich 0..255 sind stattdessen einfach zu teilen, indem er 255.0
  2. Berechnen Clinear = 0.2126 R + 0.7152 G + 0.0722 B
    • Dies ist wahrscheinlich die lineare verwandeln Sie wurden genommen werden, bevor
  3. Compute Csrgb nach ihm Formel ist, basierend auf Clinear
    • Dies ist das Stück nichtlinearen Gamma-Korrektur ist, dass Sie
    • Check out this WolframAlpha plot
    • Csrgb = 12.92 Clinear fehlten, wenn Clinear <= 0.0031308
    • Csrgb = 1.055 Clinear1/2.4 - 0.055 wenn Clinear > 0.0031308
+0

@ alessandro.francesconi Ich habe die Antwort ein wenig auf den neuesten Stand gebracht, um die genauen Schritte zu formulieren, da die Wikipedia-Seite ein bisschen kryptisch sein könnte, wenn Sie mit einigen grundlegenden Farbwissenschaften nicht vertraut sind. –

+1

@ alessandro.francesconi Ich habe auch einen WolframAlpha-Plot hinzugefügt, damit Sie die nichtlineare Form der Gammakorrektur sehen können. –

+0

Timothy, bitte korrigieren Sie mich, wenn ich falsch liege, aber ich denke, nach Schritt (1) müssen Sie die Werte in lineare Intensität umwandeln, denn wenn Sie RGB-Werte aus Datei nehmen, sind sie bereits Gamma-codiert mit der Potenz 1/2.4. Zuerst müssen Sie diese Kodierung entfernen, indem Sie transform mit power 2.4 anwenden und erst dann die Schritte (2) und (3) Ihrer Antwort ausführen. Ist das richtig? –

1

In der Theorie, mit ein paar Pixel (3, in diesem Fall), können Sie bestimmen, was ihr Algorithmus tut. Juste wählen Sie Ihre drei Pixel (P1, P2, P3), deren RGB-Wert und ihre PGM Grauwert, und Sie haben:

RedConstant * p1.redValue + GreenConstant * p1.greenValue + BlueConstant * p1.blueValue = p1 .grayValue

RedConstant p2.redValue * + * GreenConstant p2.greenValue + BlueConstant * p2.blueValue = p2.grayValue

RedConstant p3.redValue * + * GreenConstant p3.greenValue + BlueConstant * p3.blueValue = p3 .grayValue.

Dann lösen Sie dieses Problem (siehe "Gleichungslöser" oder etwas) und sehen Sie, welche Konstanten sie verwenden.

+0

Danke aber, nein, es funktioniert nicht. Ich habe 3 Pixelwerte eingegeben und ein Dreigleichsystem gelöst. Daraus ergeben sich drei Konstanten, die für diese Gleichungen gut sind und nicht für ein viertes Pixel. – TheUnexpected

+0

1) Sind Sie sicher, dass Sie die gleichen Pixel für RGB und Grauwert ausgewählt haben? 2) von diesem Artikel: http: //www.tannerhelland.com/3643/grayscale-image-algorithm-vb6/Ich habe gesehen, dass es sich um verschiedene RGB-zu-PGM-Algorithmen handelt. Probieren Sie sie alle aus und versuchen Sie herauszufinden, welches verwendet wird. Viel Glück! – Fabinout

+0

Was ist, wenn ich Ihnen sage, dass ich keine gültige Methode gefunden habe? – TheUnexpected

1

SIMPLE Algorithmus Bekehrtbild RGB IN OpenCV PYTHON in Graustufen!

Ich verwendete Kommentare so Code ist selbsterklärend.Aber es funktioniert schnell.

import cv2 
import numpy as np 
img1 = cv2.imread('opencvlogo.png') 
row,col,ch = img1.shape 
g = [ ] #the list in which we will stuff single grayscale pixel value inplace of 3 RBG values 
#this function converts each RGB pixel value into single Grayscale pixel value and appends that value to list 'g' 
def rgb2gray(Img): 
    global g 
    row,col,CHANNEL = Img.shape 
    for i in range(row) : 
     for j in range(col): 
     a =  ( Img[i,j,0]*0.07 + Img[i,j,1]*0.72 + Img[i,j,2] *0.21 ) #the algorithm i used id , G = B*0.07 + G*0.72 + R* 0.21 
                        #I found it online 
     g.append(a) 
rgb2gray(img1) #convert the img1 into grayscale 
gr = np.array(g) #convert the list 'g' containing grayscale pixel values into numpy array 
cv2.imwrite("test1.png" , gr.reshape(row,col)) #save the image file as test1.jpg 

SO habe ich diese Image-Datei ... enter image description here

Mein Programm erzeugt folgende Graustufen Datei ..

enter image description here

0

Um Harolds Punkt über die "Y-Ebene": Standardfarbe JPEGs werden unter Verwendung des YCbCr Farbraums codiert, wobei Y die Luminanzkomponente (dh die Helligkeit) und Cb und Cr die Blau-Differenz- und Rot-Differenz-Chrominanzkomponenten sind. Eine Möglichkeit, ein Farb-JPEG in ein Graustufenbild zu verwandeln, besteht darin, die Cb- und Cr-Komponenten einfach fallen zu lassen.

Es gibt ein Dienstprogramm namens jpegtran, als dies verlustfrei tun kann, mit der Option -grayscale. (Der verlustfreie Teil wäre wirklich nur wichtig, wenn Sie mit einem JPEG und nicht mit PGM enden wollten, um generation loss zu vermeiden.) In jedem Fall wäre dies wahrscheinlich der schnellste Weg, um diese Transformation durchzuführen, weil er nicht einmal den Bild in Pixel, viel weniger Mathe auf jedem einzelnen.