Ich habe gerade angefangen, OpneCV in Python zu verwenden Ich habe verschiedene Dinge ausprobiert und bin gestolpert Ich werde es schwer schreiben.
Wenn Sie es aufheben und sprechen
** LUT
ist unglaublich! **
ich dachte
** Ich habe versucht, LUT
zu verwenden! **
Es ist der Inhalt.
(Infolgedessen) habe ich auch die Leistung mit meiner eigenen Farbkonvertierungsfunktion verglichen.
Terminal: Windows 10
Konsole: cmd(Eingabeaufforderung)
python:3.6.8
Virtuelle Umgebung: venv
Wenn Sie cmd bequem machen möchten, klicken Sie hier >> [https://qiita.com/RoaaaA/items/694ae4ccfa4a69fc8286)
Ich habe in einer Universitätsklasse (Papierkram) etwas über Computer Vision (CV) gelernt. Zum ersten Mal stieß ich auf etwas namens "** Tonkurve **". Was ist eine Tonkurve?
Jedes Pixel des digitalen Bildes hat einen Wert (Pixelwert), der den Farbton darstellt. Um den Farbton des Bildes zu ändern, wird der Pixelwert des Ausgabebilds mit dem Pixelwert des Eingabebilds verknüpft. Die Funktion, die eine solche Entsprechung ergibt, wird als Graustufentransformationsfunktion bezeichnet, und die grafische Darstellung davon wird als Tonkurve bezeichnet.
Wenn man das Netz betrachtet, scheint es denen vertraut zu sein, die Kameras mögen.
Unter den Tonkurven, die im Lehrbuch erschienen, waren die folgenden zwei. (* Natürlich sind viele andere erschienen)
Die horizontale Achse ist ** Eingabepixelwert ** und die vertikale Achse ist ** Ausgabepixelwert **.
Abbildung 1 | Figur 2 |
Einfach ausgedrückt ** Umwandlung zur Erhöhung des Kontrasts ** und ** Konvertierung, die den Kontrast verringert **.
Dieser Teil der Klasse war bereits vor über einem halben Jahr. Ich wollte diese Tonkurve tatsächlich auf das Bild anwenden.
Als Funktion ausgedrückt ist es wie folgt (x ist der Eingangspixelwert 0 bis 255).
Funktion in Abbildung 1:
f(x) = \begin{cases} 2 \cdot x & (x < 128) \\ 255 & (otherwise)
\end{cases}
Funktion in Abbildung 2:
f(x) = \begin{cases} 0 & (x < 128) \\ 2 \cdot x - 255 & (otherwise)
\end{cases}
Es sieht so aus, als ob es verallgemeinert werden kann, aber lassen wir das jetzt.
Zunächst habe ich beschlossen, den in Abbildung 1 gezeigten Code zu schreiben. Aber ... es blieb sofort stecken.
Als ich auf die obige Funktion kam Ich dachte, ich könnte einfach die Elementwerte des ursprünglichen Arrays von Pixelwerten verdoppeln.
Konvertierungsfunktion
def toneCurve(frame):
return 2 * frame
frame = cv2.imread('.\\image\\castle.jpg')
cv2.imwrite('cas.jpg', toneCurve(frame))
frame
ist ein Array von Pixelwerten
Aber es hat nicht funktioniert. Das Ausgabebild ist wie folgt.
Das Originalbild | Konvertiertes Bild |
---|---|
Anscheinend, wenn Sie einfach den durch cv2.imread ()
erhaltenen Pixelwert verdoppeln
Alles, was größer als 255 (maximal) ist, wird 255 sein, anstatt ergänzt zu werden
Es schien den Wert zyklisch umzuwandeln und zurückzugeben.
(ex:256=0, 260=4)
Es ist sehr schrecklich und ich mag dieses Der Zweck ist nicht dieses Bild, also werde ich es verbessern.
Wenn Sie nachschlagen, können Sie cv2.add ()
verwenden
Es scheint, dass Werte über 255 als 255 behandelt werden.
Ich habe es versucht.
Addiere deinen eigenen Pixelwert zu dir selbst = konstante Zeiten Weil es bedeutet Die Konvertierungsfunktion ist wie folgt.
Konvertierungsfunktion
def toneCurve11(frame, n = 1):
tmp = frame
if n > 1:
for i in range(1,n):
tmp = cv2.add(tmp, frame)
return tmp
frame
ist ein Array von Pixelwerten
n
gibt an, wie oft der Pixelwert multipliziert wird, dh wie oft hinzugefügt werden soll.
Dann ist es das Ergebnis.
Das Originalbild | Konvertiertes Bild |
---|---|
Ja! Das habe ich gesucht! Es wird ein Bild mit erhöhtem Kontrast ausgegeben. (War das Graustufenbild besser?)
Wie können wir jedoch die in Abb. 2 gezeigte Konvertierung erreichen, indem wir nur diese Methode hinzufügen? Möchten Sie ein Bild ausgeben?
** Ich hatte einen schnellen Treffer **: Feuerwerk:
Was ich mir ausgedacht habe, ist dies.
** Negative / Positive Inversion
>cv2.add ()
> Negative / Positive Inversion
**
In der Abbildung sieht es so aus.
1.Keine Konvertierung | 2.Negative / positive Umkehrung |
3.cv2.add()Verdoppelt mit | 4.Negative / positive Umkehrung |
Die Änderungen liegen in der Größenordnung von 1, 2, 3, 4.
Der Konvertierungscode lautet wie folgt.
Konvertierungsfunktion
def negaPosi(frame):
return 255 - frame
def toneCurve21(frame, n = 1):
if n > 1:
return negaPoso(toneCurve11(negaPosi(frame), n))
return frame
Wie vorher
frame
ist ein Array von Pixelwerten
n
gibt an, wie oft der Pixelwert multipliziert wird, dh wie oft hinzugefügt werden soll.
Na dann das Ergebnis.
Das Originalbild | Konvertiertes Bild |
---|---|
Das Bild mit dem reduzierten Kontrast wurde sicher ausgegeben.
Selbst wenn ich das oben genannte mache, funktioniert es gut. Ich hatte das Gefühl, nach ** Bestellung ** gefragt zu werden, also beschloss ich, andere Methoden zu untersuchen.
Dann scheint cv2 eine praktische Sache namens ** LUT (Look Up Table)
** zu haben.
Darüber hinaus, wenn die Bestellung recht klein gemacht werden kann ...
LUT Ich habe oben einige Ansätze gewählt, aber am Ende Wenn Sie den erfassten Pixelwert durch einen anderen Pixelwert ersetzen, können Sie ihn konvertieren.
Hier sind die möglichen Werte von Pixelwerten ** höchstens 256 Wege ** von 0 bis 255. Wenn ja, haben Sie eine Entsprechungstabelle, in der der Konvertierungszielwert für einen bestimmten Pixelwert im Voraus registriert wird. Wenn Sie sich auf einen Pixelwert beziehen, anstatt den Pixelwert selbst zu berechnen Berechnungskosten können durch einfaches Ersetzen reduziert werden.
Hier ist eine kurze Beschreibung der LUT.
Beispielsweise kann die folgende Entsprechungstabelle betrachtet werden.
Referenzpixel | Verändere das Ziel | |
---|---|---|
0 | -> | 0 |
1 | -> | 2 |
... | ... | |
127 | -> | 254 |
128 | -> | 255 |
... | ... | |
255 | -> | 255 |
Ja, diese Tabelle ist die Entsprechungstabelle der Tonkurve in Abbildung 1.
Wenn der Pixelwert von Frame [90] [90] ist Wenn es "[12, 245, 98]" wäre Nach dem Auftragen der LUT Es wird "[24, 255, 196]".
Wir werden tatsächlich die LUT verwenden.
Konvertierungsfunktion
def toneCurve12(frame, n = 1):
look_up_table = np.zeros((256,1), dtype = 'uint8')
for i in range(256):
if i < 256 / n:
look_up_table[i][0] = i * n
else:
look_up_table[i][0] = 255
return cv2.LUT(frame, look_up_table)
frame
ist ein Array von Pixelwerten
n
gibt an, wie oft der Pixelwert multipliziert werden soll.
look_up_table = np.zeros((256,1), dtype = 'uint8')
Erstellen Sie für den Teil von eine Korrespondenztabelle (256 x 1) zur Konvertierung.
Zu diesem Zeitpunkt sind die folgenden Werte noch gespeichert.
>>> look_up_table = np.zeros((256,1), dtype = 'uint8')
>>> look_up_table
array([[0],
[0],
[0],
...,
[0],
[0]], dtype=uint8)
>>> len(look_up_table)
256
In der nächsten Zeile speichern wir die Werte, auf die verwiesen werden soll, in diesem Array.
for i in range(256):
if i < 256 / n:
look_up_table[i][0] = i * n
else:
look_up_table[i][0] = 255
Registrieren Sie in Bezug auf den Teil von den Pixelwert in der Korrespondenztabelle für die zuvor erstellte Konvertierung.
Ebenfalls
if i < 256 / n:
Der Teil von ist eine Verallgemeinerung des bedingten Ausdrucks, so dass er auch dann funktioniert, wenn der Pixelwert n-mal ist. (Beispiel: n = 3 [3-facher Pixelwert])
return cv2.LUT(frame, look_up_table)
In Bezug auf den Teil von wird die Korrespondenz von der zuvor registrierten LUT übernommen. Gibt die konvertierten Bilddaten zurück.
Na dann das Ergebnis.
Das Originalbild | Verbesserung 1 | Verbesserung 2 |
---|---|---|
Sie können das gewünschte Bild erhalten.
Werfen wir einen Blick auf die Ausführungszeit (ms).
n = 2 | n = 3 | n = 4 | |
---|---|---|---|
Verbesserung 1 | 4.9848556 | 9.9725723 | 15.921831 |
Verbesserung 2 | 4.9870014 | 4.9834251 | 4.9870014 |
Die Verarbeitung ist schneller.
Auf die gleiche Weise werden wir Abbildung 2 verbessern.
Konvertierungsfunktion
def toneCurve22(frame, n = 1):
look_up_table = np.zeros((256,1), dtype = 'uint8')
for i in range(256):
if i < 256 - 256 / n :
look_up_table[i][0] = 0
else:
look_up_table[i][0] = i * n - 255 * (n - 1)
return cv2.LUT(frame, look_up_table)
Was ich mache, ist fast das gleiche, also werde ich es nicht im Detail erklären,
if i < 256 - 256 / n :
Der Teil von ist eine Verallgemeinerung des Funktionsteils, wenn "n = 2" ist, wobei "x <128". Wenn n = 2 x <256 - 256 / n = 128 Das heißt, Es kann in "x <128" umgewandelt werden.
Na dann das Ergebnis.
Das Originalbild | Verbesserung 1 | Verbesserung 2 |
---|---|---|
Sie können das gewünschte Bild erhalten.
Werfen wir einen Blick auf die Ausführungszeit (ms).
n = 2 | n = 3 | n = 4 | |
---|---|---|---|
Verbesserung 1 | 25.915145 | 32.911539 | 36.406755 |
Verbesserung 2 | 4.9862861 | 4.9872398 | 4.9846172 |
Immerhin ist derjenige, der schnell verarbeitet, gut.
Dieses Mal sprach ich über die Tonkurve.
OpenCV ist sehr praktisch. Meine Vorfahren ärgern sich nicht ... Darüber hinaus kann Python mit nur einem Befehl verwendet werden.
Wird jemand diesen Artikel sehen? Oder obwohl ich mir Sorgen mache Wenn dies ein Memorandum ist, versichern Sie Ich poste immer.
Ich hoffe, dass dieser Artikel eines Tages für jemanden nützlich sein wird.
Geben Sie zum Schluss den diesmal verwendeten Quellcode ein und beenden Sie den Vorgang. Was soll ich als nächstes tun?
Dann: Welle:
Unter dem aktuellen Verzeichnis In einem Verzeichnis namens image Es gibt eine Bilddatei namens Castle.jpg. Wenn Sie diesen Code verwenden, ändern Sie ihn bitte selbst.
Installieren Sie auch die folgende Bibliothek.
Konsole
$ pip install opencv-python
$ pip freeze
numpy==1.18.4
opencv-python==4.2.0.34
ex.py
import cv2
import numpy as np
def toneCurve(frame):
return 2 * frame
def negaPosi(frame):
return 255 - frame
def toneCurve11(frame, n = 1):
tmp = frame
if n > 1:
for i in range(1, n):
tmp = cv2.add(tmp, frame)
return tmp
def toneCurve12(frame, n = 1):
look_up_table = np.zeros((256, 1), dtype = 'uint8')
for i in range(256):
if i < 256 / n:
look_up_table[i][0] = i * n
else:
look_up_table[i][0] = 255
return cv2.LUT(frame, look_up_table)
def toneCurve21(frame, n = 1):
if n > 1:
return negaPoso(toneCurve11(negaPosi(frame), n))
return frame
def toneCurve22(frame, n = 1):
look_up_table = np.zeros((256, 1), dtype = 'uint8')
for i in range(256):
if i < 256 - 256 / n :
look_up_table[i][0] = 0
else:
look_up_table[i][0] = i * n - 255 * (n - 1)
return cv2.LUT(frame, look_up_table)
def main():
img_path = '.\\image\\castle.jpg'
img = cv2.imread(img_path)
cv2.imwrite('.\\image\\tone00.jpg', toneCurve(img))
cv2.imwrite('.\\image\\tone11.jpg', toneCurve11(img, 2))
cv2.imwrite('.\\image\\tone12.jpg', toneCurve12(img, 2))
cv2.imwrite('.\\image\\tone21.jpg', toneCurve21(img, 2))
cv2.imwrite('.\\image\\tone22.jpg', toneCurve22(img, 2))
if __name__ == '__main__':
main()
[^ 1]: Auszug aus [Computer Graphics] cv(S. 262)
Recommended Posts