9

Ich habe versucht, zwei Bilder zu mischen. Der aktuelle Ansatz ist, ich erhalte die Koordinaten des Überlappungsbereichs der beiden Bilder, und nur für die überlappenden Bereiche mische ich mit einem fest codierten Alpha von 0,5, bevor ich ihn addiere. SO nehme ich im Grunde genommen nur den halben Wert jedes Pixels aus überlappenden Bereichen beider Bilder und füge sie hinzu. Das gibt mir keine perfekte Mischung, weil der Alpha-Wert auf 0.5 fest codiert ist. Hier ist das Ergebnis der Mischung von 3 Bildern:Wie erhält man den richtigen Alpha-Wert, um zwei Bilder perfekt zu mischen?

Wie Sie sehen können, ist der Übergang von einem Bild zum anderen noch sichtbar. Wie erhalte ich den perfekten Alpha-Wert, der diesen sichtbaren Übergang eliminieren würde? Oder gibt es so etwas nicht, und ich gehe einen falschen Weg?

Hier ist, wie ich zur Zeit das Mischungs tun:

for i in range(3): 
      base_img_warp[overlap_coords[0], overlap_coords[1], i] = base_img_warp[overlap_coords[0], overlap_coords[1],i]*0.5 
      next_img_warp[overlap_coords[0], overlap_coords[1], i] = next_img_warp[overlap_coords[0], overlap_coords[1],i]*0.5 
final_img = cv2.add(base_img_warp, next_img_warp) 

Wenn jemand möchte, dass ihm eine Chance geben, hier sind zwei verzerrte Bilder, und die Maske von ihrem Überlappungsbereich: http://imgur.com/a/9pOsQ

+0

Die Quelle Bilder scheinen mit Hintergrund Pre-multipliziert zu werden. Kannst du die Formel zeigen, die du bis jetzt benutzt hast? – K3N

+0

@ K3N, ich habe einen Code bearbeitet und hinzugefügt. Lass es mich wissen, wenn das hilft. – Metal

+2

Könnten Sie die 3 separaten verzerrten Bilder sowie die überlappenden Koordinaten bereitstellen? Dies ermöglicht es den Menschen, verschiedene Ansätze zu überprüfen. – Miki

Antwort

8

hier ist die Art, wie ich es im allgemeinen tun würde:

int main(int argc, char* argv[]) 
{ 
    cv::Mat input1 = cv::imread("C:/StackOverflow/Input/pano1.jpg"); 
    cv::Mat input2 = cv::imread("C:/StackOverflow/Input/pano2.jpg"); 

    // compute the vignetting masks. This is much easier before warping, but I will try... 
    // it can be precomputed, if the size and position of your ROI in the image doesnt change and can be precomputed and aligned, if you can determine the ROI for every image 
    // the compression artifacts make it a little bit worse here, I try to extract all the non-black regions in the images. 
    cv::Mat mask1; 
    cv::inRange(input1, cv::Vec3b(10, 10, 10), cv::Vec3b(255, 255, 255), mask1); 
    cv::Mat mask2; 
    cv::inRange(input2, cv::Vec3b(10, 10, 10), cv::Vec3b(255, 255, 255), mask2); 


    // now compute the distance from the ROI border: 
    cv::Mat dt1; 
    cv::distanceTransform(mask1, dt1, CV_DIST_L1, 3); 
    cv::Mat dt2; 
    cv::distanceTransform(mask2, dt2, CV_DIST_L1, 3); 

    // now you can use the distance values for blending directly. If the distance value is smaller this means that the value is worse (your vignetting becomes worse at the image border) 
    cv::Mat mosaic = cv::Mat(input1.size(), input1.type(), cv::Scalar(0, 0, 0)); 
    for (int j = 0; j < mosaic.rows; ++j) 
    for (int i = 0; i < mosaic.cols; ++i) 
    { 
     float a = dt1.at<float>(j, i); 
     float b = dt2.at<float>(j, i); 

     float alpha = a/(a + b); // distances are not between 0 and 1 but this value is. The "better" a is, compared to b, the higher is alpha. 
     // actual blending: alpha*A + beta*B 
     mosaic.at<cv::Vec3b>(j, i) = alpha*input1.at<cv::Vec3b>(j, i) + (1 - alpha)* input2.at<cv::Vec3b>(j, i); 
    } 

    cv::imshow("mosaic", mosaic); 

    cv::waitKey(0); 
    return 0; 
} 

Grundsätzlich berechnen Sie die Entfernung von Ihrer ROI Grenze zum Zentrum Ihrer Objekte und berechnen die Alp ha von beiden Mischmaskenwerten. Wenn also ein Bild eine große Entfernung von der Grenze und eine andere eine geringe Entfernung von der Grenze hat, bevorzugen Sie das Pixel, das näher an der Bildmitte liegt. Es wäre besser, diese Werte für Fälle zu normalisieren, in denen die verzogenen Bilder nicht von ähnlicher Größe sind. Aber noch besser und effizienter ist es, die Mischmasken vorzurechnen und sie zu verzerren. Am besten wäre es, die Vignettierung Ihres optischen Systems zu kennen und eine identische Mischmaske zu wählen (normalerweise niedrigere Werte der Grenze).

Von dem vorherigen Code werden Sie diese Ergebnisse erhalten: ROI Masken:

enter image description here

enter image description here

Blending Masken (nur als Abdruck, müssen Schwimmer Matrizen statt sein):

enter image description here

enter image description here

Bildmosaik:

enter image description here

+0

Hey, wie hast du die Masken bekommen? 'cv2.distanceTransform (img_1_mask, cv2.DIST_L1, 3)' gibt nur die ursprüngliche Maske in Python zurück. – Metal

+0

vor der Anzeige müssen Sie sie skalieren, da Float-Werte> = 1 weiß angezeigt werden. Probiere 'imshow (windowname, dt1/255)' oder etw. so (das weiß ich nicht, numpy/python syntax, sorry) – Micka

+0

Es ist 'cv2.imshow (windowname, img/255)', danke! Ich frage mich auch, ob es einen schnelleren Weg gibt, alle Pixel zu manipulieren, anstatt über alle zu iterieren. Irgendwelche Ideen? – Metal

4

Es gibt zwei offensichtliche Probleme mit Ihren Bildern:

  1. Grenzgebiet Lichtverhältnisse verzerrt

    Das ist höchstwahrscheinlich verursacht durch die Optik, um Bilder zu erfassen. Um Abhilfe zu schaffen, sollten Sie nur einen Teil der Bilder verwenden (schneiden Sie einige Pixel vom Rand ab).

    Also, wenn 20 Pixel von der Grenze abgeschnitten und Mischen bis zur gemeinsamen Beleuchtung habe ich dies:

    border cut off

    Wie Sie die hässliche Grenze Naht jetzt weg bleibt nur die Beleuchtung sehen können Probleme (siehe Kugel # 2).

  2. Bilder werden bei unterschiedlichen Lichtverhältnissen genommen

    Hier ist der Untergrund der Bilder „nicht-kompatibel“ -Effekte trifft Streuung bei der Herstellung. Sie sollten sie zu einer gleichmäßigen Beleuchtung normalisieren oder das gemischte Ergebnis zeilenweise nachbearbeiten, und wenn ein zusammenhängender Stoß erkannt wird, den Rest der Linie multiplizieren, so dass der Stoß verringert wird.

    bump

    So ist der Rest der Zeile sollte durch ständige i0/i1 multipliziert werden. Diese Art, wenn Unebenheiten nur an den Rändern zwischen Überlappungswerten auftreten können, können Sie entweder nach ihnen suchen oder diese Positionen direkt verwenden ... Um gültige Unebenheiten zu erkennen, sollten Nachbarn in der vorherigen und nächsten Zeile entlang der gesamten Bildhöhe in der Nähe sein.

    Sie dies auch in Y-Achsenrichtung auf die gleiche Weise tun können ...

Verwandte Themen