16-Bit Graustufenbild mit QT lesen

Schwachkopp schrieb:
Ok nun haben wir schon drei Möglichkeiten
Im Zweifel würde ich auf OpenCV vertrauen, aber der Code von @blöderidiot ist nicht allzu zugänglich. Ich hab das so gemacht mit Matlab:
Code:
>> [A,~,~] = imread("test.png");
>> length(unique(A(:)))

ans =

       51073
Schwachkopp schrieb:
Ich würde doch darauf tippen, dass etwas mit der Bilddatei nicht stimmt
Das kannst du ja relativ leicht prüfen.
Jedenfalls klingt für mich weiterhin das Problem so, dass die scanline Methode nicht hinreichend verstanden wird. Ich persönlich verstehe die Zeile mit dem Alignment nicht so ganz, ob sich das auf die Zeile als Gesamtheit beziehen soll (ergibt mMn keinen Sinn) oder auf jedes Pixel. Jedenfalls imHo fügt scanline padding bits ein für das Alignment, d.h. scanline gibt dir mehr bytes zurück als bytesPerLine dir anzeigt vorab. Jedenfalls so als eine zu testende Theorie.
Zweite Theorie: scanline gibt dir RGB-Werte aus und die kannst nicht einfach als Grayscale interpretieren.
 
  • Gefällt mir
Reaktionen: Schwachkopp
BeBur schrieb:
Das kannst du ja relativ leicht prüfen.
Jedenfalls klingt für mich weiterhin das Problem so, dass die scanline Methode nicht hinreichend verstanden wird. Ich persönlich verstehe die Zeile mit dem Alignment nicht so ganz, ob sich das auf die Zeile als Gesamtheit beziehen soll (ergibt mMn keinen Sinn) oder auf jedes Pixel. Jedenfalls imHo fügt scanline padding bits ein für das Alignment, d.h. scanline gibt dir mehr bytes zurück als bytesPerLine dir anzeigt vorab. Jedenfalls so als eine zu testende Theorie.
Zweite Theorie: scanline gibt dir RGB-Werte aus und die kannst nicht einfach als Grayscale interpretieren.
Die Bildgröße erlaubt nicht, dass scanline mehr Daten zurückgibt als 8192 Bytes. Das lässt sich leicht aus der Bilddimension und der 16 Bit Farbtiefe ausrechnen. Ich habe auch schon einige Experimente mit pixelColor durchgeführt um scanline zu vermeiden, jedoch mit gleichem Ergebnis. Außerdem habe ich diverse andere, nicht selbsterzeugte 16-Bit Graustufenbilder getestet.
 
Schwachkopp schrieb:
Die Bildgröße erlaubt nicht, dass scanline mehr Daten zurückgibt als 8192 Bytes. Das lässt sich leicht aus der Bilddimension und der 16 Bit Farbtiefe ausrechnen.
Nur wenn scanline 1:1 die Bytes ausliest, aber davon steht in der Doku nichts, stattdessen steht da "The scanline data is as minimum 32-bit aligned.", das liest sich für mich so, als wenn ggf. Bits hinzugefügt werden.
 
  • Gefällt mir
Reaktionen: Schwachkopp
Das habe ich auch gelesen. Mir ist das einfach zu hoch.^^ Die Doku hilft mir nicht weiter. Entweder ist sie an dieser Stelle zu ungenau oder bin nicht kompetent genug den Inhalt zu verstehen.

Ich könnte das Bild noch mal mit Kompressionslevel 0 abspeichern und dann einfach die Rohdaten direkt untersuchen ohne Qt zu involvieren. Das sollte ja irgendwie funktionieren auch wenn durch das PNG-Format ein paar zusätzliche Daten in der Datei landen werden. Wobei das eigentlich sinnlose Zeitverschwendung ist, da hier mehrere Leute festgestellt haben, dass tatsächlich 16-Bit Informationen enthalten sind. Zudem haben andere 16-Bit Bilder zum gleichen Problem geführt.

Ein weiterer Ansatz wäre libPNG direkt ohne Umweg über QImage zu verwenden oder doch OpenCV einzubinden, was aber bei meinem Kenntnisstand in eine ziemliche Quälerei ausarten dürfte.
 
Wie gesagt, hangel dich vorwärts, verwende den output von scanline erstmal so wie vorgesehen, also im Sinne von RGBA-Werten mit jeweils 8 Bit (imHo), lass dir das mal ausgeben. Dann schau mal oder plotte das mal. Grobe Vermutung: Du erhältst ein 8 Bit Graustufen Bild.
Dann entweder halt auf die Bits mal schauen, wie die konkret aussehen vs. aussehen sollten. Schau nochmal in der Doku. Es gibt noch isGrayScale(), depth(), format(), etc.. Und einfach mal auf SO nachfragen oder in deren IRC/Discord Chat.
Oder halt ne andere Funktion/Klasse hernehmen, evtl. ist das einfach keine gute Funktion für 16 Bit graustufe.

Ich find die Doku auch nicht besonders toll an der Stelle. Allerdings ignorierst du den immer selben Hinweis und Rat den ich dir seit Freitag in jedem einzelnen Beitrag geschrieben habe.
 
  • Gefällt mir
Reaktionen: Schwachkopp
So Fehler gefunden. Durch den unnötigen Umweg über QPixmap wird das Format falsch gesetzt. Dadurch wurden wohl Informationen zerstört. Auf einen möglichen Zusammenhang mit dem Bildformat wurde ja weiter vorne von euch hingewiesen. Allerdings hatte ich nicht begriffen, dass und wie QPixmap da mit reinspielen könnte. Wie dem auch sei, hier ist die korrigierte Fassung meines Code:


C++:
#include <QDebug>
#include <QImage>

QImage img;
img.load("test.png");
QSize dim = img.size();

for (int x = 0 ; x < dim.width(); x++) {
    const uint16 *h = reinterpret_cast<const uint16*>(img.scanLine(x));
    for (int y = 0; y < dim.height(); y++) {
        qDebug() << x << y << h[y] / pow(2, 16);
    }
}

Ich danke euch allen für eure Unterstützung!!!

BeBur schrieb:
Ich find die Doku auch nicht besonders toll an der Stelle. Allerdings ignorierst du den immer selben Hinweis und Rat den ich dir seit Freitag in jedem einzelnen Beitrag geschrieben habe.
Ich ignoriere hier nichts bewusst. Tut mir leid wenn du das so wahrgenommen hast. Vermutlich habe ich nur nicht verstanden, was genau du meintest.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: BeBur
Zurück
Oben