दिलचस्प पोस्ट
दिन को बचाने के लिए "! महत्वपूर्ण" का उपयोग करने के लिए (सीएसएस के साथ काम करते समय) पायथन में स्ट्रिंग के रूप में फ़ंक्शन का नाम कैसे प्राप्त करें? sed या awk: एक पैटर्न के बाद n लाइनों को हटा दें दिए गए k विभाजन के साथ पायथन पूर्णांक विभाजन ऐप स्टोर (iTunes) में अपने ऐप को कैसे जोड़ सकता हूं? क्या मैं कॉर्डोवा में फ़ास्टक्लिक रिएक्टजेएस चल रहा हूं? एसएसआरएस 2008 की रिपोर्ट में शून्य / नल वर्कअराउंड से विभाजित करें सी # डबल अर्द्धविराम की अनुमति नहीं है; ; यदि हां, तो क्या कोई विशेष तरीके हैं? जावा में वस्तुओं की एक सरणी को सॉर्ट करने के लिए कैसे? Graphviz: कैसे एक ग्राफ से। करने के लिए जाना है? क्या नोड.जेएस के लिए MySQL ड्राइवर उपलब्ध हैं? पंडों में डेटा को सामान्य करें जनरेटेड फ़ाइल को अस्थायी रूप से सर्वलेट आधारित वेब अनुप्रयोग में कैसे सहेजें कैसे phantomjs के साथ सांत्वना करने के लिए html स्रोत को मुद्रित करें वर्तमान JSON ऑब्जेक्ट (उदाहरण के लिए {"नाम": "मान"}) प्रकार 'System.Collections.Generic.List11' को डिसेरीलाइज़ नहीं कर सकता

ओपनसीवी युद्धपोत

किसी कारण के लिए जब भी मैं OpenCV के warpPerspective () फ़ंक्शन का उपयोग करता हूं, अंतिम विकृत छवि में मूल छवि में सब कुछ शामिल नहीं होता है छवि का बाएं भाग काट लगता है मुझे लगता है कि ऐसा क्यों हो रहा है, क्योंकि इस विकृत छवि को युद्धपोत के लिए कैनवास की बाईं ओर बनाया गया है। क्या यह तय करने का कोई तरीका है? धन्यवाद

Solutions Collecting From Web of "ओपनसीवी युद्धपोत"

समस्या तब होती है क्योंकि चित्र का आकृतियाँ नकारात्मक x, y मानों के लिए छवि का हिस्सा है, जो छवि क्षेत्र के बाहर हैं, इसलिए प्लॉट नहीं किया जा सकता। हम क्या करना चाहते हैं, विकृत उत्पादन को कुछ पिक्सल से 'शंट' को पूरी विकृत छवि को सकारात्मक निर्देशांक (और इसलिए छवि क्षेत्र के अंदर) में ऑफसेट करना है।

मैथ्रिक्स गुणा का उपयोग करके होमोफिज़ियों को जोड़ा जा सकता है (यही वजह है कि वे बहुत शक्तिशाली हैं)। अगर ए और बी में जीवनशैली हैं, तो एबी उस व्यक्तित्व का प्रतिनिधित्व करता है जो बी को पहले लागू करता है, और फिर ए।

इस वजह से हमें उत्पादन ऑफसेट करने की ज़रूरत है, कुछ ऑफसेट के अनुवाद के लिए ब्रीफ़ोग्राफ़िक्स मैट्रिक्स बनाते हैं, और फिर पूर्व-गुणा करें कि हमारे मूल बंगाल मैट्रिक्स द्वारा

एक 2 डी स्वलेखिका मैट्रिक्स इस तरह दिखता है:

[R11,R12,T1] [R21,R22,T2] [ P , P , 1] 

जहां R एक रोटेशन मैट्रिक्स का प्रतिनिधित्व करता है, टी एक अनुवाद का प्रतिनिधित्व करता है, और पी एक परिप्रेक्ष्य ताने का प्रतिनिधित्व करता है। और इसलिए एक विशुद्ध रूप से अनुवादित व्यक्तित्व इस तरह दिखता है:

 [ 1 , 0 , x_offset] [ 0 , 1 , y_offset] [ 0 , 0 , 1 ] 

तो बस ऊपर की तरह एक मैट्रिक्स द्वारा अपनी व्यक्तित्व premultiply, और अपनी आउटपुट छवि ऑफसेट किया जाएगा

(सुनिश्चित करें कि आप मैट्रिक्स गुणन का उपयोग नहीं करते हैं, तत्व बुद्धिमान गुणा नहीं!)

रहस्य दो भागों में आता है: परिणत मैट्रिक्स (व्यक्तित्व), और परिणामी छवि आकार।

  • getPerspectiveTransform () का उपयोग करके सही परिणत की गणना करें मूल छवि से 4 अंक लें, गंतव्य में उनकी सही स्थिति की गणना करें, उन्हें एक ही क्रम में दो वैक्टर में डाल दें, और परिप्रेक्ष्य बदलने मैट्रिक्स की गणना करने के लिए उनका उपयोग करें।

  • सुनिश्चित करें कि गंतव्य छवि आकार (warpPerspective ()) के लिए तीसरा पैरामीटर ठीक वही है जो आप चाहते हैं। इसे परिभाषित करें आकार (myWidth, myHeight) के रूप में

मैंने एक तरीका किया है … यह काम कर रहा है

  perspectiveTransform(obj_corners,scene_corners,H); int maxCols(0),maxRows(0); for(int i=0;i<scene_corners.size();i++) { if(maxRows < scene_corners.at(i).y) maxRows = scene_corners.at(i).y; if(maxCols < scene_corners.at(i).x) maxCols = scene_corners.at(i).x; } 

मैं अधिकतम एक्स अंक और y अंकों को क्रमशः खोजता हूं और इसे डालता हूं

 warpPerspective( tmp, transformedImage, homography, Size( maxCols, maxRows ) ); 

निम्न homography_warp कोशिश करो।

 void homography_warp(const cv::Mat& src, const cv::Mat& H, cv::Mat& dst); 

स्रोत स्त्रोत छवि है

H आपका व्यक्तित्व है

dst विकृत छवि है

अपने जवाब में https://stackoverflow.com/users/1060066/matt-freeman द्वारा वर्णित homography_warp अपनी व्यक्तित्व को समायोजित करें https://stackoverflow.com/a/8229116/15485

 // Convert a vector of non-homogeneous 2D points to a vector of homogenehous 2D points. void to_homogeneous(const std::vector< cv::Point2f >& non_homogeneous, std::vector< cv::Point3f >& homogeneous) { homogeneous.resize(non_homogeneous.size()); for (size_t i = 0; i < non_homogeneous.size(); i++) { homogeneous[i].x = non_homogeneous[i].x; homogeneous[i].y = non_homogeneous[i].y; homogeneous[i].z = 1.0; } } // Convert a vector of homogeneous 2D points to a vector of non-homogenehous 2D points. void from_homogeneous(const std::vector< cv::Point3f >& homogeneous, std::vector< cv::Point2f >& non_homogeneous) { non_homogeneous.resize(homogeneous.size()); for (size_t i = 0; i < non_homogeneous.size(); i++) { non_homogeneous[i].x = homogeneous[i].x / homogeneous[i].z; non_homogeneous[i].y = homogeneous[i].y / homogeneous[i].z; } } // Transform a vector of 2D non-homogeneous points via an homography. std::vector<cv::Point2f> transform_via_homography(const std::vector<cv::Point2f>& points, const cv::Matx33f& homography) { std::vector<cv::Point3f> ph; to_homogeneous(points, ph); for (size_t i = 0; i < ph.size(); i++) { ph[i] = homography*ph[i]; } std::vector<cv::Point2f> r; from_homogeneous(ph, r); return r; } // Find the bounding box of a vector of 2D non-homogeneous points. cv::Rect_<float> bounding_box(const std::vector<cv::Point2f>& p) { cv::Rect_<float> r; float x_min = std::min_element(p.begin(), p.end(), [](const cv::Point2f& lhs, const cv::Point2f& rhs) {return lhs.x < rhs.x; })->x; float x_max = std::max_element(p.begin(), p.end(), [](const cv::Point2f& lhs, const cv::Point2f& rhs) {return lhs.x < rhs.x; })->x; float y_min = std::min_element(p.begin(), p.end(), [](const cv::Point2f& lhs, const cv::Point2f& rhs) {return lhs.y < rhs.y; })->y; float y_max = std::max_element(p.begin(), p.end(), [](const cv::Point2f& lhs, const cv::Point2f& rhs) {return lhs.y < rhs.y; })->y; return cv::Rect_<float>(x_min, y_min, x_max - x_min, y_max - y_min); } // Warp the image src into the image dst through the homography H. // The resulting dst image contains the entire warped image, this // behaviour is the same of Octave's imperspectivewarp (in the 'image' // package) behaviour when the argument bbox is equal to 'loose'. // See http://octave.sourceforge.net/image/function/imperspectivewarp.html void homography_warp(const cv::Mat& src, const cv::Mat& H, cv::Mat& dst) { std::vector< cv::Point2f > corners; corners.push_back(cv::Point2f(0, 0)); corners.push_back(cv::Point2f(src.cols, 0)); corners.push_back(cv::Point2f(0, src.rows)); corners.push_back(cv::Point2f(src.cols, src.rows)); std::vector< cv::Point2f > projected = transform_via_homography(corners, H); cv::Rect_<float> bb = bounding_box(projected); cv::Mat_<double> translation = (cv::Mat_<double>(3, 3) << 1, 0, -bb.tl().x, 0, 1, -bb.tl().y, 0, 0, 1); cv::warpPerspective(src, dst, translation*H, bb.size()); } 

warpPerspective () ठीक काम करता है इसे फिर से लिखना नहीं चाहिए आप शायद इसका गलत इस्तेमाल करते हैं

निम्नलिखित टिप्स याद रखें:

  1. (0,0) पिक्सल केंद्र में नहीं बल्कि बायां-ऊपरी कोने में है इसलिए यदि आप छवि x2 को बढ़ाना चाहते हैं तो आप निचले और दाहिने हिस्सों को खो देंगे, न कि बॉर्डर (जैसे मटैब में)
  2. यदि आप दो बार छवि को ताना करते हैं तो परिवर्तनों को गुणा करना और फ़ंक्शन को एक बार सक्रिय करना बेहतर होता है।
  3. मुझे लगता है कि यह केवल चार / इंट मैट्रिक्स पर काम करता है, फ्लोट / डबल पर नहीं।
  4. जब आपके पास परिवर्तन होता है, पहले ज़ूम / स्क्व्यू / रोटेशन / परिप्रेक्ष्य लागू होते हैं और अंत में अनुवाद होता है। इसलिए अगर मैट्रिक्स में छवि का हिस्सा गायब है तो बस ट्रांसएशन (पिछले कॉलम की दो ऊपरी पंक्ति) को बदल दें।

यह मेरा समाधान है

क्योंकि "warpPerspective ()" में तीसरा पैरामीटर एक रूपांतरण मैट्रिक्स है,

हम एक परिवर्तन मैट्रिक्स बना सकते हैं, जो पहले छवि को पिछड़े स्थानांतरित करता है, फिर छवि को घूमता है, अंत में छवि आगे बढ़ता है

मेरे मामले में, मेरे पास 160 पीएक्स की ऊंचाई और 160 पीएक्स की चौड़ाई है। मैं चारों ओर की [80,080] के आसपास की छवि को घुमाएगा [0,0]

सबसे पहले, छवि को पिछड़े स्थानांतरित करता है (जिसका अर्थ है टी 1)

फिर छवि को घूमता है (जिसका अर्थ है आर)

आखिरकार छवि आगे बढ़ती है (जिसका मतलब है टी 2)

 void rotateImage(Mat &src_img,int degree) { float radian=(degree/180.0)*M_PI; Mat R(3,3,CV_32FC1,Scalar(0)); R.at<float>(0,0)=cos(radian);R.at<float>(0,1)=-sin(radian); R.at<float>(1,0)=sin(radian);R.at<float>(1,1)=cos(radian); R.at<float>(2,2)=1; Mat T1(3,3,CV_32FC1,Scalar(0)); T1.at<float>(0,2)=-80; T1.at<float>(1,2)=-80; T1.at<float>(0,0)=1; T1.at<float>(1,1)=1; T1.at<float>(2,2)=1; Mat T2(3,3,CV_32FC1,Scalar(0)); T2.at<float>(0,2)=80; T2.at<float>(1,2)=80; T2.at<float>(0,0)=1; T2.at<float>(1,1)=1; T2.at<float>(2,2)=1; std::cerr<<T1<<std::endl; std::cerr<<R<<std::endl; std::cerr<<T2<<std::endl; std::cerr<<T2*R*T1<<"\n"<<std::endl; cv::warpPerspective(src_img, src_img, T2*R*T1, src_img.size(), cv::INTER_LINEAR); }