2014-05-20 4 views
5

मैं वीडियो स्ट्रीम को स्थिर करने के लिए एक प्रोग्राम बना रहा हूं। फिलहाल, मेरा कार्यक्रम चरण सहसंबंध एल्गोरिदम के आधार पर काम करता है। मैं आधार और वर्तमान - दो छवियों के बीच ऑफसेट की गणना कर रहा हूं। इसके बाद मैं नए निर्देशांक के अनुसार वर्तमान छवि को सही करता हूं। यह कार्यक्रम काम करता है, लेकिन परिणाम संतोषजनक नहीं है। संबंधित लिंक आपको मिल सकते हैं कि इलाज किया गया वीडियो अवांछनीय प्रतीत होता है और पूरे वीडियो को हिलाता है और खराब हो रहा है।
छवियों के बीच ऑफसेट की गणना::
Orininal video
Unshaked video
मेरे वर्तमान अहसास नहीं हैवीडियो स्थिरीकरण के लिए सर्वश्रेष्ठ एल्गोरिदम

Point2d calculate_offset_phase_optimized(Mat one, Mat& two) { 

    if(two.type() != CV_64F) { 
    cvtColor(two, two, CV_BGR2GRAY); 
    two.convertTo(two, CV_64F); 
    } 

    cvtColor(one, one, CV_BGR2GRAY); 
    one.convertTo(one, CV_64F); 

    return phaseCorrelate(one, two); 

} 

अनुसार छवि स्थानांतरण इस समन्वय:

void move_image_roi_alt(Mat& img, Mat& trans, const Point2d& offset) { 

    trans = Mat::zeros(img.size(), img.type()); 
    img(
    Rect(
     _0(static_cast<int>(offset.x)), 
     _0(static_cast<int>(offset.y)), 
     img.cols-abs(static_cast<int>(offset.x)), 
     img.rows-abs(static_cast<int>(offset.y)) 
    ) 
).copyTo(trans(
    Rect(
     _0ia(static_cast<int>(offset.x)), 
     _0ia(static_cast<int>(offset.y)), 
     img.cols-abs(static_cast<int>(offset.x)), 
     img.rows-abs(static_cast<int>(offset.y)) 
    ) 
)); 
} 

int _0(const int x) { 
    return x < 0 ? 0 : x; 
} 

int _0ia(const int x) { 
    return x < 0 ? abs(x) : 0; 
} 

मैं दस्तावेज़ लेखकों स्टेबलाइजर यूट्यूब के माध्यम से देख रहा था और कोने का पता लगाने के आधार पर एल्गोरिदम आकर्षक लग रहा था, लेकिन मैं पूरी तरह से स्पष्ट नहीं हूँ यह काम किस प्रकार करता है। तो मेरा सवाल यह है कि इस समस्या को प्रभावी ढंग से कैसे हल करें। शर्तों में से एक - कार्यक्रम धीमे कंप्यूटर पर चलाएगा, इसलिए भारी एल्गोरिदम उपयुक्त नहीं हो सकता है।
धन्यवाद!
पीएस मैं पाठ में किसी भी गलतियों के लिए क्षमा चाहता हूं - यह एक स्वचालित अनुवाद है।

+0

आप किस प्रकार के वीडियो को लक्षित कर रहे हैं? बस कृत्रिम छवियां (जहां दृश्य वास्तव में एक विमान है) या असली वीडियो जहां पिक्सेल अलग गहराई पर हो सकते हैं? और आप किस आंदोलन को सही करना चाहते हैं? चिकनी गति ज्यादातर वांछित हैं, लेकिन उच्च त्वरण के साथ आंदोलन आमतौर पर शोर होते हैं। –

+0

लक्ष्य वीडियो का उदाहरण है: http://www.youtube.com/watch?v=Ta8w_nzuMkU और मेरे वर्तमान स्टेबलाइज़र का मेरा परिणाम: http://www.youtube.com/watch?v=-0p -यूजेईएसीवीआई प्लानर कैमरा आंदोलन में उच्चतम प्राथमिकता समाप्त हो रही है। घूर्णन और पैमाने वैकल्पिक हैं। – iRomul

+1

मैं कल्पना कर सकता था कि दृश्य की गहराई एक वास्तविक समस्या हो सकती है (दूर पिक्सेल जितना करीब पिक्सल नहीं ले जायेगा)।मुझे नहीं पता कि यह आमतौर पर कैसे किया जाता है, लेकिन यहां मैं यह कैसे करूँगा: दो या दो से अधिक छवियों का उपयोग करके प्रत्येक बिंदु की 3 डी स्थिति का अनुमान लगाएं। 3 डी कैमरा आंदोलन का अनुमान लगाएं। कैमरा पथ को चिकना करें (उदा। बॉक्स-फ़िल्टर का उपयोग करके) और दृश्य को दोबारा प्रस्तुत करें, जो हो सकता है कि कोई भी छेद भरें। मुझे यकीन नहीं है कि शुद्ध अनुवाद पर्याप्त होंगे। –

उत्तर

2

आप प्रत्येक फ्रेम में SIFT जैसे छवि वर्णनकर्ताओं का उपयोग कर सकते हैं और फ्रेम के बीच robustmatches की गणना कर सकते हैं। फिर आप फ्रेम के बीच homography की गणना कर सकते हैं और उन्हें संरेखित करने के लिए उपयोग कर सकते हैं। स्पैस विशेषताओं का उपयोग करके घने सहसंबंध का उपयोग करने से तेज कार्यान्वयन हो सकता है।

वैकल्पिक रूप से, यदि आप camera parameters जानते हैं तो आप अंक और कैमरों के calculate 3D positions और छवियों को स्थिर प्रोजेक्शन प्लेन पर दोहरा सकते हैं। नतीजतन, आपको दृश्य के sparse 3D reconstruction भी मिलते हैं (कुछ हद तक कमजोर, आमतौर पर इसे optimized उपयोग करने योग्य होने की आवश्यकता होती है)। यह वही है उदा। Autostitch ऐसा करेगा, लेकिन इसे लागू करना काफी मुश्किल है।

ध्यान दें कि कैमरा पैरामीटर calculated भी हो सकते हैं, लेकिन यह और भी कठिन है।

+0

आपके उत्तर के लिए धन्यवाद! मैं इस क्षेत्र में नया हूं, इसलिए मुझे कुछ चीजों को कुछ गलतफहमी का सामना करना पड़ा। मेरा कोड है: 'detector.detect (base_frame, keypoints_base); detector.detect (current_frame, keypoints_cur); extractor.compute (..., keypoints_base, descriptors_base); extractor.compute (..., keypoints_cur, descriptors_cur); matcher.knnMatch (description_base, description_cur, मैचों, 2); ' मैं सबसे अच्छे मैचों को फ़िल्टर कर रहा हूं और ऐसा करता हूं: ' homography = findHomography (k_base, k_cur, CV_RANSAC); ' लेकिन मुझे अगला कदम क्या करना चाहिए? warpAffine इस होमोग्राफी 3x3, केवल 2x3 नहीं लेता है। – iRomul

+0

इसके बजाय 'warpPerspective' का उपयोग करें (http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html#warpperspective देखें)। –

+0

मैंने इस एल्गोरिदम को लागू करने की कोशिश की, लेकिन परिणाम असंतोषजनक थे: [वीडियो] (http://www.youtube.com/watch?v=DUZ7wDplDHQ&feature=youtu.be) मैं आपको याद दिलाता हूं कि फ़्रेम की तुलना निश्चित फ्रेम के साथ की जाती है । इस मामले में, यह पहला वीडियो फ्रेम है। [पूर्ण कोड] (http://pastebin.com/9rNeXf2t) – iRomul

2

OpenCV कोड की 3 लाइनों में यह तुम्हारे लिए क्या कर सकते हैं (यह निश्चित रूप से सबसे छोटा रास्ता है, हो सकता है यहां तक ​​कि सबसे अच्छा):

t = estimateRigidTransform(newFrame, referenceFrame, 0); // 0 means not all transformations (5 of 6) 
if(!t.empty()){  
    warpAffine(newFrame, stableFrame, t, Size(newFrame.cols, newFrame.rows)); // stableFrame should be stable now 
} 

आप, मैट्रिक्स टी संशोधित करके परिवर्तनों किसी तरह बंद कर सकते हैं यह अधिक स्थिर परिणाम का कारण बन सकता है। यह सिर्फ मूल विचार है, फिर आप इसे जिस तरह से चाहते हैं उसे संशोधित कर सकते हैं: संदर्भ बदलें फ्रेम, मैट्रिक्स टी आदि से रूपांतरण पैरामीटर का चिकना सेट

संबंधित मुद्दे