2016-05-16 10 views
0

Aus welchem ​​Grunde auch immer, ich habe ein .tiff Bild, das von OpenCV falsch eingegeben wird cv::imread als CV_16U Art statt CV_16S. Ich weiß, dass es falsch ist, weil mir meine Daten erklärt wurden (das Bild sollte Dummy-Werte von -9999 und einen positiven Max-Wert enthalten), und ich bekomme die richtigen Werte bei der Eingabe in.die Art ändern (Interpretation) von cv :: Mat Bild

Ich kann immer noch durch z. Die .at<type> Funktion selbst, wie ich den realen Typ kenne, so kann ich .at<short> verwenden. Die cv::Mat::type() ist jedoch falsch, was nicht wünschenswert ist, wenn ich andere Funktionen für die weitere Verarbeitung verwende, die sich auf diesen Parameter stützen könnten (wobei die Verarbeitung möglicherweise von cv::Mat::type() abhängt).

Wie kann ich die cv::Mat::type() ändern ohne das Bild zu konvertieren? Das heißt, ich möchte nicht, dass die Werte von der unsigned short zu einer short Darstellung neu berechnet werden, sondern einfach die Weise, in der sie gelesen werden, geändert werden.

Wie ändere ich die zum Bild gehörende cv::Mat::type(). (aber nicht einfach das Bild in einen anderen Typ konvertieren).

Hier ist ein Code Beispiel und es ist ausgegeben, das Problem zu veranschaulichen:

cv::Mat test = cv::imread(argv[1], CV_LOAD_IMAGE_ANYDEPTH); 
if (test.type() == CV_16U){ // true 
    std::cerr << (short)(*std::min_element(test.begin<short>(), 
              test.end<short>())) 
       << std::endl; 
    std::cerr << (short)(*std::max_element(test.begin<short>(), 
              test.end<short>())) 
       << std::endl; 
    // output is OK, "-9999" and "1645" 

    std::cerr << (unsigned short) 
       (*std::min_element(test.begin<unsigned short>(), 
            test.end<unsigned short>())) 
       << std::endl; 
    std::cerr << (unsigned short) 
       (*std::max_element(test.begin<unsigned short>(), 
            test.end<unsigned short>())) 
       << std::endl; 
    // output is not OK: "1" and "55537" 

    cv::Mat test2; 
    test.convertTo(test2, CV_16S); 
    // also tried: 
    // test.assignTo(test2, CV_16S); 

    std::cerr << (short)(*std::min_element(test2.begin<short>(), 
              test2.end<short>())) 
       << std::endl; 
    std::cerr << (short)(*std::max_element(test2.begin<short>(), 
              test2.end<short>())) 
       << std::endl; 
    // output is not OK: "1" and "32767" 

    test.type = CV_16U; // what I would like to do 
} 
+1

@BeyelerStudios es kein Fehler ist, weiß opencv nicht, ob die Inhalte signiert oder unsigniert und setzt es auf unsigned standardmäßig – vu1p3n0x

+1

können Sie immer eine zweite Matrix erstellen 'cv :: Mat actual (test.size(), CV_16S, test.ptr());' ('test' muss dafür kontinuierlich sein, siehe [ptr] (http: // docs.opencv.org/2.4/modules/core/doc/basic_structures.html#mat-ptr)), aber diese Art von stinkt auch :) – BeyelerStudios

+0

@ vu1p3n0x Kann ich es irgendwie zwingen, es auf signierte Eingabe zu setzen? Ich kann sehen, wie es keine Möglichkeit geben würde, es aus den Daten zu ermitteln ... – penelope

Antwort

2

OpenCV lässt seine Datenelemente standardmäßig öffentlich (obwohl Sie in der Regel mit ihnen zu verwirren selbst nicht wollen). Mach weiter und probier es aus; wenn es funktioniert Super! wenn nicht gut ...

Warnung: ungetestet und hackish Lösung

test.flags = (test.flags & ~CV_MAT_TYPE_MASK) | CV_16S; 
Verwandte Themen