मेरे पास टीएफ में एक पूर्व-प्रशिक्षित नेटवर्क है और मैं इसे नेटवर्क पर भेजने से पहले इनपुट छवि को प्रीप्रोसेस करना चाहता हूं (एकल चैनल फ्लोट32 में कनवर्ट करें और इसे [-1 1] पर सामान्यीकृत करें)।
//initialize network
dnn::Net net = readNetFromTensorflow(modelFile);
assert(!net.empty());
Mat frame = imread(imageFile, IMREAD_GRAYSCALE);
cv::equalizeHist(frame, frame);
Mat procFrame(frame.size(), CV_32FC1);
क्या प्रीप्रोसेसिंग करने के निम्नलिखित दो तरीकों और कौन सा अधिक कुशल है, के बीच कोई प्रदर्शन अंतर है?
// preprocess 1st way
for (int i = 0; i < frame.rows; i++) {
for (int j = 0; j < frame.cols; j++){
procFrame.at<float>(i, j) = frame.at<uint8_t>(i, j)*(2. / 255.) - 1.;
}
}
या
// preprocess 2nd way
procFrame = frame*(2./ 255.);
procFrame -= 1.;
2 जवाब
कॉपी करने का पहला तरीका बेहतर है क्योंकि आप मूल चर पर वापस लिखने के बजाय केवल एक दिशा में फ़्लोट को कॉपी और कनवर्ट करते हैं।
दूसरा तरीका जो आप अंकगणित करते हैं वह बहुत बेहतर है क्योंकि ओपनसीवी में अपने स्वयं के लूप को रोल करना बिल्टिन अंकगणितीय कार्यों का उपयोग करने से लगभग हमेशा धीमा होता है क्योंकि ओपनसीवी को सिम वेक्टराइजेशन और असेंबली स्तर पर अनुकूलन के कई अन्य रूपों का उपयोग करने के लिए संकलित किया जाता है।
लेकिन ये दोनों मेमोरी आवंटन (महत्वपूर्ण मंदी) के संबंध में अक्षम हैं यदि आप समय से पहले जानते हैं कि आपके फ्रेम किस आकार के होंगे क्योंकि आप रूपांतरण के लिए फ्लोट मैट्रिक्स को लगातार आवंटित और हटाते हैं।
procFrame
को स्टेटिक (static Mat
) घोषित करके और इसे ठीक उसी तरह बना कर जैसे आप उचित आकार के लिए कर रहे हैं, इससे बचने के लिए एक प्रीआलोकेटेड फ्लोट मैट्रिक्स को मेमोरी में रखें।
static Mat procFrame(frame.size(), CV_32FC1);
cv::equalizeHist(frame, frame);
frame.convertTo(procFrame, CV_32FC1);
procFrame = procFrame*(2./ 255.);
procFrame -= 1.;
यदि आपके फ्रेम का आकार रनटाइम के दौरान बदलता है, तो इसे स्थिर घोषित न करें।
procFrame *= 2./ 255.;
, procFrame = procFrame*(2./ 255.);
की तुलना में अधिक कुशल होने की संभावना है, क्योंकि यह जगह पर काम कर सकता है।
प्रदर्शन हमेशा अंतिम लक्ष्य नहीं होता है। यदि आप दूसरे दृष्टिकोण का उपयोग करते हैं, तो आप मैट के असाइनमेंट ऑपरेटर का उपयोग करेंगे। इसका मतलब है कि ऑपरेशन के दौरान किसी भी अपवाद को Mat& operator= (const Mat &m)
के अंदर संभाला जाएगा जो पेशेवरों द्वारा लिखा गया है।
वैसे भी, मेरा मानना है कि Mat& operator= (const Mat &m)
का उपयोग करना सबसे कुशल और कम से कम त्रुटि प्रवण असाइनमेंट का तरीका है। Mat
तत्वों पर पुनरावृति करके इसे स्वयं लिखने का प्रयास न करें।
संबंधित सवाल
नए सवाल
c++
C ++ एक सामान्य-प्रयोजन प्रोग्रामिंग भाषा है। यह मूल रूप से C के विस्तार के रूप में डिज़ाइन किया गया था और इसमें एक समान सिंटैक्स है, लेकिन यह अब पूरी तरह से अलग भाषा है। C ++ कंपाइलर के साथ संकलित कोड के बारे में प्रश्नों के लिए इस टैग का उपयोग करें। विशिष्ट मानक संशोधन [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] या [C ++ 23], आदि से संबंधित प्रश्नों के लिए संस्करण-विशिष्ट टैग का उपयोग करें। ।
procFrame.at<float>(i, j)
वास्तव में अक्षम है। यदि आप वास्तव में सभी पिक्सेल पर मैन्युअल रूप से लूप लिखना चाहते हैं, तो पॉइंटर्स का उपयोग करें।