家居網(wǎng)站源碼軟文推送
目錄
- 0、前言
- 1、安裝 pybind11庫(kù)
- c++側(cè)
- python側(cè)
- 2、C++引入bybind11
- vs增加相關(guān)依賴及設(shè)置
- cpp中添加頭文件及導(dǎo)出模塊
- cpp中添加numpy相關(guān)數(shù)據(jù)結(jié)構(gòu)的接收和返回
- 編譯生成dll后改成導(dǎo)出模塊同名文件的.pyd
- 3、python調(diào)用c++
- 4、C++引入bybind11
0、前言
在當(dāng)今的計(jì)算機(jī)視覺和機(jī)器學(xué)習(xí)領(lǐng)域,Python 和 C++ 是兩種最常用的編程語(yǔ)言。Python 以其簡(jiǎn)單易學(xué)、高效編程和強(qiáng)大的科學(xué)計(jì)算庫(kù)而聞名,而 C++ 則以其高效性和強(qiáng)大的計(jì)算能力而著稱。然而,這兩種語(yǔ)言各有優(yōu)劣,因此將它們結(jié)合起來(lái)使用可以發(fā)揮它們的優(yōu)點(diǎn),同時(shí)彌補(bǔ)它們的缺點(diǎn)。在本文中,我們將介紹如何在 Windows VS 環(huán)境下使用 pybind11 進(jìn)行 C++ 和 Python 聯(lián)合編程示例,進(jìn)行機(jī)器視覺和相機(jī)位姿優(yōu)化相關(guān)的程序開發(fā)。我們將使用 Python 3.7 和 C++,并利用 numpy 數(shù)組格式接收 Python 側(cè)的兩幅圖像,并利用 g2o 進(jìn)行 BA 優(yōu)化,最后將優(yōu)化結(jié)果以 numpy 數(shù)組形式返回 Python。
1、安裝 pybind11庫(kù)
首先,我們需要安裝 pybind11 庫(kù)。pybind11 是一個(gè)用于將 C++ 代碼綁定到 Python 解釋器的庫(kù),它提供了一種簡(jiǎn)單的方法來(lái)創(chuàng)建 Python 模塊,這些模塊可以直接調(diào)用 C++ 代碼。
c++側(cè)
pybind11庫(kù)是一個(gè)純頭文件的庫(kù),其實(shí)只要從github上下載源碼,即可供使用。
git clone https://github.com/pybind/pybind11.git
python側(cè)
python側(cè),可以進(jìn)入conda虛擬環(huán)境,注意需要3.7版本的python,直接pip安裝:
pip install pybind11
2、C++引入bybind11
安裝 pybind11 庫(kù)后,我們可以開始編寫 C++ 代碼。以g2o ba為例,我們將上篇博文中的c++代碼進(jìn)行稍加改造,開個(gè)python的調(diào)用“接口”即可:
vs增加相關(guān)依賴及設(shè)置
使用bybind11,需要將下載的頭文件路徑引入項(xiàng)目,同時(shí),需要將python3.7的頭文件路徑及l(fā)ib引入及鏈接進(jìn)項(xiàng)目。
(1)頭文件路徑加入:
(2)python3.7的lib加入:
(3)生成動(dòng)態(tài)庫(kù)dll類型:
cpp中添加頭文件及導(dǎo)出模塊
在c++程序中去掉main函數(shù),添加頭文件,及導(dǎo)出模塊設(shè)置:
如上兩圖,在常規(guī)c++文件中首位加入頭文件和導(dǎo)出模塊定義,我們這次導(dǎo)出的是ab這個(gè)函數(shù),ab是將上篇博文的main函數(shù)改成的。
cpp中添加numpy相關(guān)數(shù)據(jù)結(jié)構(gòu)的接收和返回
// 將Python中的圖像傳遞給C++進(jìn)行處理
py::array_t<double> ab(py::array_t<uint8_t> &imge1, py::array_t<uint8_t> &imge2){//創(chuàng)建全0 numpy數(shù)組py::array_t<double> output_array({3,4});auto buf = output_array.mutable_data();for (int i = 0; i < 3; i++) {for (int j = 0; j < 4; j++) {buf[i * 4 + j] = 0;}}// 將輸入圖像轉(zhuǎn)換為OpenCV的Mat對(duì)象auto bufimg1 = imge1.request();auto bufimg2 = imge2.request();int type = CV_8UC3;int channels = 3;if (bufimg1.ndim == 3) {channels = bufimg1.shape[2];if (channels == 4) {type = CV_8UC4;}}//如果不是3或4通道則退出if (channels != 3 && channels != 4) {return output_array;}cv::Mat img1(bufimg1.shape[0], bufimg1.shape[1], type, bufimg1.ptr);cv::Mat img2(bufimg2.shape[0], bufimg2.shape[1], type, bufimg2.ptr);
如上,我們ab函數(shù),可以接收來(lái)自python的圖像numpy數(shù)組,并將圖像轉(zhuǎn)化為了cv::mat格式,交給c++后續(xù)處理。最后返回numpy形式的g2o優(yōu)化后的位姿數(shù)組:
g2o::VertexSE3Expmap* v = dynamic_cast<g2o::VertexSE3Expmap*>(optimizer.vertex(1));Eigen::Isometry3d pose = v->estimate();// 獲取輸出數(shù)組的指針auto output_ptr = output_array.mutable_data();// 將isometry的旋轉(zhuǎn)矩陣和平移向量存儲(chǔ)在numpy數(shù)組中Eigen::Map<Eigen::Matrix<double, 3, 4, Eigen::RowMajor>> result_map(output_ptr);result_map.block<3, 3>(0, 0) = pose.rotation().matrix();result_map.block<3, 1>(0, 3) = pose.translation();return output_array;
編譯生成dll后改成導(dǎo)出模塊同名文件的.pyd
將生成的dll改成g2opy.pyd
3、python調(diào)用c++
進(jìn)入與c++依賴的同一個(gè)python環(huán)境,然后編輯簡(jiǎn)單的調(diào)用程序:
兩幀圖像送入c++,優(yōu)化計(jì)算后返回輸出:
本篇所有源碼已上傳,鏈接如下:
python實(shí)現(xiàn)C++程序g2o的ba優(yōu)化模塊調(diào)用,python側(cè)的程序資源
本資源為python和C++聯(lián)合編程的示例vs工程源碼
4、C++引入bybind11
通過(guò)本文的示例,我們驗(yàn)證了如何在 Windows VS 環(huán)境下使用 pybind11 進(jìn)行 C++ 和 Python 聯(lián)合編程的可行性,可進(jìn)一步進(jìn)行機(jī)器視覺和相機(jī)位姿優(yōu)化相關(guān)的程序開發(fā)。
有了C++的加持,python的機(jī)器人開發(fā)在性能上或者是解決方案上,又有了更多的可選項(xiàng)??梢园l(fā)揮python的更大威力了,keep go on!