[Qt] Jak skonwertować QVector<double> do QBytearray i wyświetlić za pomocą QPixmap

0

Witam

Od kilku dni nie mogę sobie poradzić z pewnym problemem. Chcę wczytać plik .csv po czym wyświetlić go jako obraz.
Poniżej opisze w punktach co robię.

  1. Wczytuję plik .csv do QVector<double>
    Plik składa się z liczb od 0-3000 i takie wczytuję.

  2. Konwertuję plik do QBytearray, a a przynajmniej tak mi się wydaje:D
    Który ze sposobów konwertowania powinienem wybrać? Który jest poprawny?

 
.hh
private:
      QByteArray byteArray;
      QVector<double> frame;

.cpp
QByteArray InfraredCamera::retFrameBArray(const int* frameNumber)
{
    Frame temp =  Pictures[*frameNumber]; // Pobranie z wektora na którym są obrazki jednego konkretnego
    QVector<double>* vec = temp.retVecFrameValue(); //zwrócienie wektora z wartościami dla konkretnego obrazka
    QByteArray arr; 
    for(int i = 0; i< (320*256); i++) //Wypełnienie QBytearray kolejnymi wartościami wektora
        arr.append(reinterpret_cast<const char*>(temp.retFrameValue(&i)),sizeof(double)); 

    return arr;

}
  1. Następnie próbuję wrzucić to do QPixmap
       int x =3;
    QByteArray arr = test->Termo.retFrameBArray(&x);
    QPixmap pic;
    pic.loadFromData(arr);

Po czym program się zawiesza.

1

Najwyraźniej nie masz pojęcia co robisz.
Nie wiesz co robi reinterpret_cast, ani nie wiesz jakie dane masz i na co je chcesz skonwertować.
Próba użycia reinterpret_cast jest bezcelowa jeśli nie rozumie się foramtu binarnego danych wejściowych i wyjściowych, a szansa, że są kompatybilne (by użyć reinterpret_cast) jest prawie zerowa.

Zacznij od początku o opisania dokładnie co masz w pliku (może przykład).
A następnie co chcesz osiągnąć.

0

Wdytowałem trochę swój pierwszy post i opisałem kod.

Wydaje mi się, że reinterprete_cast to konwersja przez zmianę typu, w tym przypadku wartość double na const char*.

A co chcę zrobić?

  1. Chcę wczytać plik.csv w którym jest zapisany obraz 320x256 do QVector<double>, co już zrobiłem.
  2. Następnie chcę go wyświetlić:
    Z tego co przeczytałem, najlepiej to zrobić wczytując mój wektor do QBytearray, następnie do QImage albo QPixmap.

Byłbym bardzo wdzięczny za pomoc.

2
  1. gdybyś opisał format pliku (zapewne nagłówek opisuje rozdzielczość), to już dałbym ci kod, który wczytuje to z pliku bezpośrednio do QImage albo QPixmap.
  2. W qt nie ma formatu danych dla obrazku, w którym są liczby zmiennoprzecinkowe. Ergo zapomnij o reinterpret_cast z jakiejkolwiek wersji QVecor<double>.
  3. nie wiem skąd ci się ubzdurało manipulowanie na QByteArray, jest to zbędne.
  4. robisz podstawowy błąd nowicjusza zadającego pytanie: prosisz jak naprawić twój pomysł na rozwiązanie problemu, nie dając konkretów na temat właściwego problemu.

Przypuszczalnie potrzebujesz coś w tym stylu (zgaduje format):

QImage readTextStream(QTextStream &data) {
    static const double MaxValue = 30000;
    int width, height;
    QChar ch; // to read coma separator
    data >> width >> ws >> ch >> height;

    QImage result(width, height, QImage::Format_Indexed8);
    QVector<QRgb> table(0x100, 0);
    for (int i=0; i<0x100; ++i) {
            table[i] = qRgb(i,i,i);
    }
    result.setColorTable(table);

    for (int y=0; y<height; ++y) {
         uchar *line = result.scanLine(y);
         for (int x=0; x<width; ++x) {
              double value;
              data >> value >> ws >> ch;
              line[x] = qBound(0, qRound(value/MaxValue*0xff), 0xff);
         }
    }
    return result;
}
0

Dziękuję za odpowiedź.

Plik który wczytuję nie jest typowym formatem obrazu. Jest to plik .asci. Wczytuję coś w tym stylu

Numer obrazu: jakiś numer jest ich około kilkudziesięciu tysięcy
czas: tysięczne części sekundy

32.4 43.3 ... 43.3
3e2.4 43.3 ... 43.3
---------------- ---------------- ---------------- ----------------
... ... ... 43.3
---------------- ---------------- ---------------- ----------------
e32.4 43.3 232.4 43.3
---------------- ---------------- ---------------- ----------------

Wartości jakie wczytuję są z przedziału 0-3000

Ma to rozmiar 320x256 i chciałbym to wyświetlić jako obraz, najlepiej w kolorze. Oraz w daleszej części zrobić z tego film.

Wczytywanie tego wszystkiego łącznie ze sprawdzaniem mam zrobione i działa bardzo dobrze. Zależy mi tylko i wyłącznie na stworzeniu obrazu lub i filmu z moich danych.

1
QImage imageFromData(const QVector<double>& frame, 
                     int width, 
                     int height,
                     QColor (*colorForValue)(double)) {
     QImage result(width, height, QImage::Format_RGB888);
    for (int y=0; y<height; ++y) {
         uchar *line = result.scanLine(y);
         for (int x=0; x<width; ++x) {
              result.setPixel(x, y, colorForValue(frame[x+y*width]))
         }
    }
    return result;
}

colorForValue opisuje jak zmienić czas na kolor, to jak to zrobić musisz zdecydować sam.
Przykładowo jeśli opisujesz zjawiska cykliczne o znanym okresie, to można wykorzystać inny niż RGB opis koloru QColor::fromHsv (część h zachowuje się cyklicznie).

0

Dzięki wielkie!

Trochę przerobiłem ten kod i działa u mnie pięknie, z tym, że czarno-biało...
Mógłbyś mi jeszcze podpowiedzieć jak napisać tą funkcję która generowałaby odpowiedni kolor w zalezności od wartości wektora?

Chciałbym aby, np dla wartości 0-10 wyświetlało kolor niebieski, a dla 10-20 czerwony itd...

1

Poczytaj to: http://qt-project.org/doc/qt-5/qcolor.html#the-hsv-color-model
daj saturację na maksimum (255) oraz wartość (jasność) też na maksimum (255). Wartość opisuj zmianami odcienia (barwy) (s), tylko zakres dobierz mądrze bo tak jak pisałem ta wartość ma charakter cykliczny (360 stopni), więc dobrze by było pozostawić jakiś margines (część koła kolorów poza użytkiem) pomiędzy maksimum a minimum.
Nie jest to trudne, powinieneś dać radę.

0

Dziękuję, za link. Radę sobie dam, po prostu za bardzo nie wiedziałem jak się za to zabrać. Qt uczę się od 2miesięcy, stąd moje braki. Jszcze raz dziękuję za pomoc. Temat do zamknięcia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1