2017-02-15 1 views
2

diese einfache Standalone-Demo verwenden:cv :: connectedComponentsWithStats in OpenCV 3.2.0 manchmal stürzt mit gcc 6.2

#include <opencv2/opencv.hpp> 

#include <iostream> 

int main(int argc, char *argv[]) { 
    // unsigned char data[] = {1, 0, 1}; // crashes 
    unsigned char data[] = {1, 1, 0}; // does not crash 

    cv::Mat1b testImage = cv::Mat1b(3, 1, data); 

    cv::Mat labeledImage; 
    cv::Mat stats; 
    cv::Mat centroids; 
    int neighborhood = 8; 

    int componentCount = cv::connectedComponentsWithStats(
     testImage, labeledImage, stats, centroids, neighborhood); 

    std::cout << "componentCount: " << componentCount << std::endl; 

    return EXIT_SUCCESS; 
} 

mit gcc 5.4 es funktioniert gut für beide Werte 'Daten'. Mit gcc 6.2, funktioniert es für {1,1,0} in Ordnung, aber Dumps dies mit data = {1,0,0}:

======= Memory map: ======== 
00400000-00407000 r-xp 00000000 08:01 15214967       /home/doria/build/Examples/c++/OpenCV/Bug/Bug 
00606000-00607000 rw-p 00006000 08:01 15214967       /home/doria/build/Examples/c++/OpenCV/Bug/Bug 
020b2000-0216c000 rw-p 00000000 00:00 0         [heap] 
7f2608000000-7f2608021000 rw-p 00000000 00:00 0 
7f2608021000-7f260c000000 ---p 00000000 00:00 0 
7f260cc1d000-7f260cc24000 r-xp 00000000 08:01 10883576     /lib/x86_64-linux-gnu/librt-2.23.so 
7f260cc24000-7f260ce23000 ---p 00007000 08:01 10883576     /lib/x86_64-linux-gnu/librt-2.23.so 
7f260ce23000-7f260ce24000 r--p 00006000 08:01 10883576     /lib/x86_64-linux-gnu/librt-2.23.so 
7f260ce24000-7f260ce25000 rw-p 00007000 08:01 10883576     /lib/x86_64-linux-gnu/librt-2.23.so 
7f260ce25000-7f260ce28000 r-xp 00000000 08:01 10883446     /lib/x86_64-linux-gnu/libdl-2.23.so 

Irgendwelche Gedanken?

+0

Hallo David! Ich glaube, ich habe den Käfer entdeckt. Ich werde eine E-Mail an den Autor des Algorithmus schreiben, um zu sehen, ob er weitere Einsichten hat. – Miki

Antwort

3

Ich bin verantwortlich für den Bug ... Seufzer.

Das Problem ist, dass der Algorithmus in 2x2 Blöcken auf dem Bild funktioniert. Die maximale Anzahl von Etiketten ist eine pro Block. Leider, wenn das Bild eine ungerade Anzahl von Zeilen und/oder Spalten hat, ist die Schätzung der Anzahl der Blöcke falsch. Also, dies zu beheben wir tun sollten:

const size_t Plength = ((img.rows + 1)/2) * ((img.cols + 1)/2); 

Wir werden eine Pull-Anforderung an OpenCV für diese heute einreichen. Plus eine verbesserte Reihe von Tests. Übrigens warten wir immer noch auf die parallele Version (Multicore) des einzubeziehenden Algorithmus. Wir haben bereits im November eine pull request für die parallele Version (Multicore) des Algorithmus eingereicht, der auch den Fehler behebt.

Die feste Version finden Sie seit Juni 2017 in OpenCV 3.3. Darüber hinaus beinhaltet sie auch die parallele Version.

3

Ich kann diesen Fehler mit Visual Studio 2015 (vc14 x64) reproduzieren.

Die Probleme scheint im Einklang 352 of connectedcomponents.cpp:

//A quick and dirty upper bound for the maximimum number of labels. 
const size_t Plength = img.rows*img.cols/4; 
LabelT *P = (LabelT *)fastMalloc(sizeof(LabelT)* Plength); 

Mit Ihrem Testbild, das PLength-0 auswertet:

Plength = (3*1)/4 = 0 

So *P Null-Elemente hat.

Allerdings gibt es diese assignement an wenigen Stellen im Algorithmus:

P[lunique] = lunique; 

und lunique Werte haben >0. So verursacht dies die Heap-Korruption manchmal.

Der Fix sollte eine bessere Schätzung der oberen Grenze Plength bieten.

+1

Ich wünschte, ich könnte +5 geben :) Dies verursachte heute ernsthafte Kopfschmerzen. –

+0

Ich benutzte sowohl Elektrozaun als auch Valgrind (jeweils einzeln) und tatsächlich stürzte es bei beiden nicht, wenn ich es als "crashes" bezeichnete. Wie sonst würdest du so etwas aufspüren? –

+0

@David Ich nehme an, der Visual Studio Debugger hat einen ziemlich guten Job gemacht. Der Absturz befand sich in der Nähe von 'fastFree' von' P', also war klar, wonach zu suchen war – Miki

Verwandte Themen