python कैसे पूरी तरह से दो छवियों को मिश्रण करने के लिए सही अल्फा मूल्य प्राप्त करने के लिए?




opencv image-processing (2)

आपकी छवियों के साथ 2 स्पष्ट समस्याएं हैं:

  1. सीमा क्षेत्र ने प्रकाश की स्थिति को विकृत कर दिया है

    यह छवियों के अधिग्रहण के लिए इस्तेमाल होने वाले प्रकाशिकी की वजह से सबसे अधिक संभावना है इसलिए उपाय करने के लिए आपको छवियों के अंदर केवल कुछ हिस्सों का इस्तेमाल करना चाहिए (सीमा से कुछ पिक्सल काट देना

    तो जब सीमा से 20 पिक्सल काट दिया और आम रोशनी को सम्मिश्रण किया तो मुझे यह मिला:

    जैसा कि आप देख सकते हैं कि बदसूरत सीमा सीम अब दूर ही रोशनी की समस्याएं बनी रहती हैं (बुलेट # 2 देखें)।

  2. छवियां विभिन्न प्रकाश की स्थिति में ली गई हैं

    यहाँ उपसतह बिखरने प्रभाव छवियों को बनाने में हिट "संगत नहीं" आप उन्हें कुछ वर्दी रोशनी या पोस्ट प्रक्रिया को सामान्य रूप से लाइन से मिश्रित परिणाम रेखा के अनुसार सामान्य बनाना चाहिए और जब सुसंगत टक्कर का पता लगाया जाए तो शेष लाइन गुणा करें ताकि टक्कर कम हो जाए।

    तो बाकी रेखा को लगातार i0/i1 गुणा किया जाना चाहिए। ये प्रकार यदि समानांतर ओवरलैप मूल्यों के बीच किनारों पर केवल बाधा हो सकती है तो आप या तो उनके लिए स्कैन कर सकते हैं या सीधे उन पदों का उपयोग कर सकते हैं ... मान्य टक्कर की पहचान करने के लिए आस-पास और अगली पंक्तियों में पूरी छवि ऊंचाई के साथ पड़ोसी होना चाहिए।

    आप उसी तरह वाई अक्ष की दिशा में यह भी कर सकते हैं ...

मैं दो छवियों को मिश्रण करने की कोशिश कर रहा हूं मैं जो वर्तमान दृष्टिकोण ले रहा हूं, मैं दो छवियों के अतिव्यापी क्षेत्र के निर्देशांक प्राप्त करता हूं, और केवल अतिव्यापी क्षेत्रों के लिए, मैं इसे जोड़ने से पहले 0.5 के हार्डकोड अल्फा के साथ मिश्रण करता हूं। तो मूलतः मैं बस प्रत्येक पिक्सेल के आधे मूल्य ले रहा हूं, दोनों छवियों के अतिव्यापी क्षेत्रों से, और उन्हें जोड़ रहा हूं। यह मुझे सही मिश्रण नहीं देता है क्योंकि अल्फा मान को 0.5 से कठिन है। 3 छवियों के सम्मिश्रण का परिणाम यहां दिया गया है:

जैसा कि आप देख सकते हैं, एक छवि से दूसरे में संक्रमण अब भी दिखाई दे रहा है। मैं सही अल्फा मान कैसे प्राप्त कर सकता हूं जो इस दृश्य संक्रमण को खत्म कर सकता है? या ऐसी कोई चीज नहीं है, और मैं गलत दृष्टिकोण ले रहा हूं?

यहां बताया गया है कि मैं वर्तमान में सम्मिश्रण कर रहा हूं:

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)

अगर कोई इसे शॉट देना चाहता है, तो यहां दो विकृत छवियां और उनके अतिव्यापी क्षेत्र का मुखौटा है: http://imgur.com/a/9pOsQ


मैं इसे सामान्य रूप से कैसे करूँगा:

int main(int argc, char* argv[])
{
    cv::Mat input1 = cv::imread("C://Input/pano1.jpg");
    cv::Mat input2 = cv::imread("C://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;
}

असल में आप अपनी आरओआई सीमा से दूरी की गणना अपने ऑब्जेक्ट्स के केंद्र तक करते हैं और दोनों मुखौटा मूल्यों को मिलाकर अल्फा की गणना करते हैं। इसलिए यदि एक छवि सीमा से एक उच्च दूरी पर है और दूसरे को सीमा से एक कम दूरी है, तो आप पिक्सेल को छवि केंद्र के नजदीक पसंद करते हैं। उन मामलों के लिए उन मानों को सामान्य करना बेहतर होगा, जहां विकृत चित्र समान आकार के नहीं हैं। लेकिन इससे बेहतर और अधिक कुशल ब्लेंडिंग मास्क को प्रीकॉम्पट करना है और उन्हें ताना देना है। सर्वश्रेष्ठ आपके ऑप्टिकल सिस्टम के विगनेटिंग को जानने और चुनने और समान मिश्रण वाले मुखौटा (सीमा के आम तौर पर कम मूल्य) को पता होना चाहिए।

पिछले कोड से आपको ये परिणाम मिलेंगे: आरओआई मास्क:

मिश्रण मुखौटे (बस एक छाप के रूप में, इसके बजाय फ्लोट मैट्रिक्स होना चाहिए):

छवि मोज़ेक:





alphablending