Kamera Frame 8/16 Bit Umwandlung in Python

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Kriccemis
User
Beiträge: 15
Registriert: Freitag 8. Mai 2020, 20:10

Hallo Zusammen,

ich arbeite gerade an einem kleinen Projekt zur Bilderkennung.
Ich verwende eine IDS Kamera, welche von 8-12 Bit Bilder übertragen kann, der Hersteller hat sogar eine Bibliothek und Tutorial bereitgestellt.
Mein Problem ist es, wenn ich Bilder größer 8 Bit ausgeben lassen möchte, da die Kamera das Array immer nur als "uint8" Format übertragen.
Solange ich 8 Bit Frames aufnehme ist alles in Ordnung, aber sobald ich auf 10 oder 12 gehe bin ich etwas ratlos mit der Umwandlung.
Der Pixelwert wird in zwei Bytes im Array (Frame) gespeichert und muss wieder zusammengefügt werden, es sieht etwa so aus:

array of uint8 = [136, 4, 125, 4, 133, 5, 128, 4, 131, 5, ...]

Es müssen sozusagen immer zwei Werte zusammengefasst werden um die Bildinformation zu erhalten.
Sollte jemand das gleiche problem auch schonmal gehabt haben, wäre ich sehr dankbar über Hilfe!
Bei Bedarf kann ich gern den Code noch aufführen, aber ich denke der wird in diesem Fall nicht helfen?

Danke
Sirius3
User
Beiträge: 17844
Registriert: Sonntag 21. Oktober 2012, 17:20

Kommt drauf an, als welchen Typ Du die Daten vorliegen hast,
Bei numpy-Arrays mußt Du nur ein View vom richtigen Typ erzeugen:

Code: Alles auswählen

import numpy as np
data = np.array([136, 4, 125, 4, 133, 5, 128, 4, 131, 5], dtype='u1')
data = data.view('<u2')
# array([1160, 1149, 1413, 1152, 1411], dtype=uint16)
Kriccemis
User
Beiträge: 15
Registriert: Freitag 8. Mai 2020, 20:10

Erstmal danke für die schnelle Antwort. ALso von der Kamera erhalte ich die Daten über:

Code: Alles auswählen

array = ueye.get_data(pcImageMemory, width, height, nBitsPerPixel, pitch, copy=False)
Typ: "Array of uint8"

Wenn ich es so schreibe werden dann nur Nullen ausgegeben, sicher ist der Code so nicht korrekt.

Code: Alles auswählen

array = ueye.get_data(pcImageMemory, width, height, nBitsPerPixel, pitch, copy=False)

data = np.array(array, dtype='u1')
data = data.view('<u2')
Benutzeravatar
__blackjack__
User
Beiträge: 13268
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Kriccemis: Was enthält denn `array`? Wenn `data` am Ende nur 0en enthält, dann müsste `array` das auch schon getan haben. Ist die vorletzte Zeile überhaupt notwendig? Welchen Typ hat denn `array`? Was ist `ueye`? Wir müssen hier eine Menge raten.
Please call it what it is: copyright infringement, not piracy. Piracy takes place in international waters, and involves one or more of theft, murder, rape and kidnapping. Making an unauthorized copy of a piece of software is not piracy, it is an infringement of a government-granted monopoly.
Kriccemis
User
Beiträge: 15
Registriert: Freitag 8. Mai 2020, 20:10

Ich muss mich entschuldigen für meinen letzten Post....hatte beim Test die Lichtquelle aus, daher die Nullen....oh man.
Also es geht alles, danke dafür!

Jetzt kommt ein neues Problem dazu. Das 12 Bit Bild ist in 16 Bit gespeichert, somit befinden sich alle Grauwerte unter 4000 und werden schwarz dargestellt. Gibt es eine einfache möglichkeit die Darstellung bei CV2 oder Tiff reader auf 12 Bit zu ändern?

Danke und VG!
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mal 4 nehmen, das spreizt deinen Wertebereich entsprechend. Und ist in numpy trivial.
Kriccemis
User
Beiträge: 15
Registriert: Freitag 8. Mai 2020, 20:10

Um auf die offene Frage einzugehen. UEYE ist eine Bibliothek zur Kamerasteuerung von IDS Kameras.

Auch wenn das anscheinend sehr trivial ist, klappt es nicht :(

Code: Alles auswählen

# Test Bild
array = ueye.get_data(pcImageMemory, width, height, nBitsPerPixel, pitch, copy=False)
array = array.view('<u2')

array_new1 = array * 16
# oder
array_new2 = np.multiply(array, 16)
Als Ergebnis kommen nur Nullen.
Ist das Dateiformat des Array´s der Fehler?

Bild
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Eh, du hast recht, es haette natuerlich 16 statt 4 sein sollen in meinem Post.

Aber es funktioniert wie gedacht:

Code: Alles auswählen

>>> import numpy as np
>>> a = np.array(range(2**12), dtype=np.uint16)
>>> a
array([   0,    1,    2, ..., 4093, 4094, 4095], dtype=uint16)
>>> a * 16
array([    0,    16,    32, ..., 65488, 65504, 65520], dtype=uint16)
Kriccemis
User
Beiträge: 15
Registriert: Freitag 8. Mai 2020, 20:10

Wenn ich zum testen ein Array selber schreibe funktioniert es auch, aber wie man auf dem Screenshot sehen kann, bekomme ich als Ergebnis alles Nullen?!
Das verstehe ich nicht...
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich habe keine Ahnung was das fuer eine Umgebung da ist, aber die waere mein erster Kandidat fuer eine Fehlersuche.
Kriccemis
User
Beiträge: 15
Registriert: Freitag 8. Mai 2020, 20:10

Also als Programmierumgebung nutze ich Spyder.
das Merkwürdige ist auch, selbst wenn ich aus dem Array einen Einzelwert in eine Variable übergebe ist dieser Null...

Bin echt Ratlos.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dazu kann ich nichts sagen, ausser: verzichte zur Ausfuehrung auf Spyder, und benutze die Kommandozeile, mit der entsprechenden Python-Version (ggf venv beachten, falls das implizit oder explizit benutzt wird). Denn wenn man ein numpy array hat, dann wird das wie gezeigt durch Multiplikation nicht alles null. Das kann nur daran liegen, dass da jemand an der Laufzeitumgebung rumfuhrwerkt, ausser Spyder habe ich da keinen Verdacht.
Antworten