2016-04-12 5 views
0

Ich habe wenig Indexierungsproblem mit der folgenden for-Schleife. Ich scanne einfach das Bild mit roi, aber ich kann das ganze Bild nicht scannen. Ich habe einige nicht gescannte Bereiche in den letzten Zeilen und Spalten übrig. Irgendein Vorschlag? Sorry für die einfache Frage.Schiebefenster mit Roi C++

`

// Sliding Window for scaning the image 
for (int rowIndex = 0; rowIndex <= lBPIIImage2.rows - roih; rowIndex = getNextIndex(rowIndex, lBPIIImage2.rows, roih, steprow)) 

{ 
    for (int colindex = 0; colindex <=lBPIIImage2.cols - roiw; colindex = getNextIndex(colindex, lBPIIImage2.cols, roiw, stepcol)) 

    { 
     searchRect = cvRect(colindex, rowIndex, roiw, roih); 
     frameSearchRect = lBPIIImage2(searchRect); 
     LoopDummy = frameSearchRect.clone(); 
     rectangle(frame, searchRect, CV_RGB(255, 0, 0), 1, 8, 0); 
     //normalize(LoopDummy, LoopDummy, 0, 255, NORM_MINMAX, CV_8UC1); 
     //imshow("Track", LoopDummy); 
     //waitKey(30); 
     images.push_back(LoopDummy); 
     Coordinate.push_back(make_pair(rowIndex, colindex)); 
    } 

} 
+0

Warum gibt es 'roiw' und' StepRow', was ist der Unterschied zwischen ihnen? – Dialecticus

+0

Ich gleite mit überlappenden Fenstern, deshalb habe ich Schritt Reihe. Es ist roiw/.5 –

+0

OK, also möchten Sie, dass der letzte 'cvRect' in einer Zeile auch' roiw' width hat, aber 'rowIndex% StepRow' zu sein! = 0 ist, oder möchten Sie' rowIndex% StepRow' um 0 zu sein, aber 'cvRect' width um weniger als' roiw' zu sein? – Dialecticus

Antwort

0

Statt dieser

for (int rowindex = 0; rowindex <= frameWidth - roiw; rowindex += StepRow) 

versuchen so etwas wie dieses

for (int rowIndex = 0; rowIndex < frameWidth - roiw; 
    rowIndex = getNextIndex(rowIndex, frameWidth, roiw, StepRow)) 

wo Funktion getNextIndex ist wie folgt:

int getNextIndex(int currentIndex, int frameSize, int roi, int step) 
{ 
    int temp = min(currentIndex + step, frameSize - roi - 1); 
    return currentIndex != temp ? temp : frameSize; 
} 

Beachten Sie, dass ich <= durch < im Bedingungsteil der Schleife ersetzt habe. Es macht Sinn für mich, diesen Teil zu ändern. In meinen Kommentaren sollten die Indexwerte 0,5,6 anstelle von 0,5,7 sein. Wenn es wirklich stehen sollte <= dann entfernen Sie einfach den - 1 Teil oben.

+0

Viel besser, vielen Dank. Im Verlust sehr wenig unbedeckte Pixel, die vernachlässigt werden können. –

+0

Ich glaube, das '<=' sollte in der Bedingung bleiben und die '- 1' fallengelassen - wenn die letzte Region mit dem Bildende ausgerichtet ist, würde es die '[(frameSize - roiw), (frameSize - 1) ] 'Intervall, das genau' roiw' ganze Zahlen abdeckt. Für eins-zu-eins Fehler ist mein Trick, einen Eckfall zu versuchen. Wenn 'frameWidth' gleich 'roiw' ist, in welchem ​​Fall Sie genau 1 Scan haben, werden Sie mit der gegenwärtigen Bedingung die Schleife überhaupt nicht betreten. – mcmlxxxvi

+0

Ich stoße heute auf ein Problem, wenn die Schrittweite sehr niedrig ist, ich meine ein Pixel in jeder Koordinate, Code scannt zusätzliche Regionen. In der Regel mittlere Abschnitte des Bildes. –

0

Dialecticus hat Ihre problem covered, aber ich möchte ein wenig erweitern. Das Problem betrifft, wie Sie bemerkt haben, sowohl Zeilen als auch Spalten, aber ich werde nur über die Breite sprechen, da die Handhabung der Höhe analog ist.

Teile eines Arrays oder Bereichs, die nicht von einer Schleife durchlaufen werden, insbesondere solche am Ende, sind ein typisches Symptom, dass der Zustand und/oder das Inkrement der Schleife nicht das gesamte Array/Bereich abdecken und angepasst werden müssen. Um in Ihrem Fall die gesamte Bildbreite zu scannen, benötigen Sie frameWidth - roiw als eine exakte Anzahl von StepRow s, d. H. (frameWidth - roiw) % StepRow == 0. Ich vermute stark, dass das in Ihrem Fall nicht stimmt.

Zum Beispiel, wenn Ihr Bild 14 Pixel breit ist, und Ihre Region von Interesse Breite 8, wobei in diesem Fall Ihres Schritt would be 4 pixels (ich nehme an, Sie roiw * 0.5 gemeint), dann wäre dies geschehen: incorrect step iteration

Iteration # 3 würde den Test rowindex <= frameWidth - roiw nicht bestehen und die Schleife verlassen, ohne die letzten 2 Pixel zu scannen.

Ich sehe drei Möglichkeiten, von denen jeder mit seinen Nachteilen:

Haftungsausschluss: Alle nachfolgenden Code ist nicht getestet und kann Tippfehler und logische Fehler enthalten. Bitte testen und entsprechend anpassen.

  1. Ändern der von der letzten Region versetzt, so das Ende des Bildes paßt. In diesem Fall wäre das letzte rowindex Inkrement nicht StepRow, sondern die Anzahl der Pixel zwischen dem Ende des letzten Scanbereichs und dem Ende des Bildes. Der Nachteil ist, dass sich die letzten zwei Regionen mehr als die vor ihnen überlappen können - in unserem Fall würde Region 1 Pixel 0: 7, Region 2 - 4:11 und Region 3 - 6:13 abdecken.

    Um dies zu tun, können Sie Ihre Schleife Schritt ändern können, um zu überprüfen, ob dies die letzte Iteration (bitte denken Sie an, wie es schöner zu schreiben, habe ich nur den ternären Operator die Veränderung kleiner zu machen):

    for (int rowindex = 0; 
        /* Note that a region of (roiw) pixels ending at (frameWidth - 1) should start 
         at (frameWidth - roiw), so the <= operator should be correct. To verify that, 
         check the single-region case where rowindex == 0 and frameWidth == roiw */ 
        rowindex <= frameWidth - roiw; 
        rowindex += ((rowindex + roiw + StepRow <= frameWidth) ? 
           StepRow : 
           (frameWidth - (rowindex + roiw)))) 
    
  2. Klemmen Sie die Größe der letzten Region am Ende des Bildes fest. Der Nachteil wäre, dass Ihre letzte Region kleiner ist als die vorherige - in unserem Fall hätten die Regionen 1 und 2 eine Größe von 8, während Region 3 6 Pixel hätte.

    Um dies zu tun, können Sie eine Überprüfung beim Erstellen der cvRect, um zu sehen, ob es kleiner sein muss. Sie sollten auch irgendwie Ihre Schleifenbedingung ändern, so dass Sie es tatsächlich in diesem Fall ein:

    /* (StepRow - 1) should make sure that enter the loop is entered when the 
        last unscanned region has a width between 1 and stepRow, inclusive */ 
    for (int rowindex = 0; rowindex <= frameWidth - roiw + (StepRow - 1); rowindex += StepRow) 
    /* ... column loop ... */ 
        { 
        if (rowindex > frameWidth - roiw) 
        { 
         roiw = frameWidth - rowindex; 
        } 
        searchRect = cvRect(rowindex, colindex, roiw, roih) 
    
  3. Verwenden Sie einen unterschiedlichen Schritt, so dass Ihre Bereiche gleicher Breite sind und so gleichmäßig wie möglich überlappen. In unserem Fall würden sich die drei Regionen mit den Pixeln 0: 7, 3:11 und 6:14 gleich überlappen, aber das wird offensichtlich in den meisten Fällen nicht der Fall sein.

    Um dies zu tun, können Sie berechnen, wie viele Iterationen Sie mit Ihrem aktuellen Schritt erwarten, und dann durch diese Zahl den Unterschied zwischen Ihrer Rahmen- und ROI-Breite dividieren, was Ihnen Ihren Teilschritt geben würde. Da der Pixel-Offset eine Ganzzahl ist, benötigen Sie für den Aufbau der cvRect einen Integer-Wert. Ich schlage vor, die rowindex beizubehalten und zu inkrementieren und als Brüche zu schreiten und direkt vor der Verwendung in den Konstruktor cvRect in int zu konvertieren - auf diese Weise wird sich dein Index so gleichmäßig wie möglich bewegen.

    Beachten Sie, dass ich einen epsilon-Wert verwendet habe, um (hoffentlich) Rundungsfehler in der Float-Int-Konvertierung zu vermeiden, wenn der Gleitkommawert sehr nahe an einem int liegt. Ein Beispiel und eine Erläuterung der Technik finden Sie unter this blog post and comments. Beachten Sie jedoch, dass der Code nicht getestet wird und es trotzdem zu Rundungsfehlern kommen kann, insbesondere wenn Ihre int-Werte groß sind!

    /* To see how these calculations work out, experiment with 
        roiw == 8, StepRow == 4 and frameWidth == 14, 15, 16, 17 */ 
    /* N.B.: Does not cover the case when frameWidth < roiw! */ 
    int stepRowCount = (frameWidth - roiw + (StepRow - 1))/StepRow + 1; 
    float step = ((float)(frameWidth - roiw))/(stepRowCount - 1); 
    float eps = 0.005; 
    
    for (float rowindex = 0.0; (int)(rowindex + eps) <= frameWidth - roiw; rowindex += StepRow) 
    /* ... column loop ... */ 
        { searchRect = cvRect((int)(rowindex + eps), colindex, roiw, roih); 
    

PS: Sollte nicht Ihr Index, der die Bildbreite iteriert colIndex und umgekehrt genannt werden, da in einem 1920x1080 Bild, das Sie 1920 Spalten und 1080 Zeilen (daher Begriffe wie 1080p)

+0

Als erstes antworte ich auf PS: Ja, es ist ein Vers. Ich denke, während ich hier war, habe ich mit Matlab verwechselt. –

+0

Ich werde versuchen, die Logik hinter Ihrer Antwort zu verstehen Danke für Ihre Hilfe, Sir! +1 –

+0

Wenn Sie Probleme mit irgendeinem Teil haben, hinterlassen Sie einen Kommentar und ich werde versuchen, es zu klären. – mcmlxxxvi

Verwandte Themen