在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            博客專欄

            EEPW首頁(yè) > 博客 > 深度解決添加復(fù)雜數(shù)據(jù)增強(qiáng)導(dǎo)致訓(xùn)練模型耗時(shí)長(zhǎng)的痛點(diǎn)(2)

            深度解決添加復(fù)雜數(shù)據(jù)增強(qiáng)導(dǎo)致訓(xùn)練模型耗時(shí)長(zhǎng)的痛點(diǎn)(2)

            發(fā)布人:計(jì)算機(jī)視覺工坊 時(shí)間:2022-12-22 來(lái)源:工程師 發(fā)布文章

            4. C++ And CUDA Extensions 

            For Python/ PyTorch


            C++ 與 Python 或 PyTorch 的交互,業(yè)界主流做法是采用 pybind11,關(guān)于Pybind11 的更多詳細(xì)說(shuō)明可以參看文獻(xiàn) [15],其核心原理如下圖所示:


            圖片

            pybind11 pipeline


            由于 PyTorch 的 C++ 拓展與純 Python 有一些區(qū)別,因?yàn)?PyTorch 的基礎(chǔ)數(shù)據(jù)類型是 torch.Tensor,該數(shù)據(jù)類型可以認(rèn)為是 Pytorch 庫(kù)對(duì) np.array 進(jìn)行了更高一層的封裝。所以,在寫拓展程序時(shí),其接口函數(shù)所需要的數(shù)據(jù)類型以及調(diào)用的庫(kù)會(huì)有些區(qū)別,下面會(huì)詳細(xì)解釋。


            4.1. C++ Extensions For Python


            首先我們看 Python 代碼,如下所示(scripts/test_warpaffine_opencv.py):





















            import cv2import torch  # 不能刪掉, 因?yàn)樾枰獎(jiǎng)討B(tài)加載torch的一些動(dòng)態(tài)庫(kù),后面會(huì)詳細(xì)說(shuō)明.import numpy as npfrom orbbec.warpaffine import affine_opencv  # C++ interface
            data_path = "./demo.png"img = cv2.imread(data_path, cv2.IMREAD_GRAYSCALE)
            # python中的numpy.array()與 pybind中的py::array_t一一對(duì)應(yīng).src_point = np.array([[262.0, 324.0], [325.0, 323.0], [295.0, 349.0]], dtype=np.float32)dst_point = np.array([[38.29, 51.69], [73.53, 51.69], [56.02, 71.73]], dtype=np.float32)# python interface mat_trans = cv2.getAffineTransform(src_point, dst_point)res = cv2.warpAffine(img, mat_trans, (600,800))cv2.imwrite("py_img.png", res)
            # C++ interfacewarpffine_img = affine_opencv(img, src_point, dst_point)cv2.imwrite("cpp_img.png", warpffine_img)


            從上述代碼可以看到,Python 文件中調(diào)用了 affine_opencv 函數(shù),而 affine_opencv 的 C++ 實(shí)現(xiàn)在 orbbec/warpaffine/src/cpu/warpaffine_opencv.cpp 中,如下所示:








































            #include<vector>#include<iostream>#include<pybind11/pybind11.h>#include<pybind11/numpy.h>#include<pybind11/stl.h>#include<opencv2/opencv.hpp>

            namespace py = pybind11;
            /* Python->C++ Mat */cv::Mat numpy_uint8_1c_to_cv_mat(py::array_t<unsigned char>& input){        ...}
            cv::Mat numpy_uint8_3c_to_cv_mat(py::array_t<unsigned char>& input){        ...}
            /* C++ Mat ->numpy */py::array_t<unsigned char> cv_mat_uint8_1c_to_numpy(cv::Mat& input){        ...}
            py::array_t<unsigned char> cv_mat_uint8_3c_to_numpy(cv::Mat& input){        ...}
            py::array_t<unsigned char> affine_opencv(py::array_t<unsigned char>& input,                                        py::array_t<float>& from_point,                                        py::array_t<float>& to_point){        ...}


            由于本工程同時(shí)兼容了 PyTorch 的 C++/CUDA 拓展,為了更加規(guī)范,這里在拓展接口程序(orbbec/warpaffine/src/warpaffine_ext.cpp)中通過(guò) PYBIND11_MODULE 定義好接口,如下所示:














































            #include <torch/extension.h>#include<pybind11/numpy.h>
            // python的C++拓展函數(shù)申明py::array_t<unsigned char> affine_opencv(py::array_t<unsigned char>& input,                                        py::array_t<float>& from_point,                                        py::array_t<float>& to_point);
            // Pytorch的C++拓展函數(shù)申明(CPU)at::Tensor affine_cpu(const at::Tensor& input,          /*[B, C, H, W]*/                      const at::Tensor& affine_matrix,  /*[B, 2, 3]*/                      const int out_h,                      const int out_w);
            // Pytorch的CUDA拓展函數(shù)申明(GPU)#ifdef WITH_CUDAat::Tensor affine_gpu(const at::Tensor& input,          /*[B, C, H, W]*/                      const at::Tensor& affine_matrix,  /*[B, 2, 3]*/                      const int out_h,                      const int out_w);#endif
            // 通過(guò)WITH_CUDA宏進(jìn)一步封裝Pytorch的拓展接口at::Tensor affine_torch(const at::Tensor& input,          /*[B, C, H, W]*/                                  const at::Tensor& affine_matrix,  /*[B, 2, 3]*/                                  const int out_h,                                  const int out_w){        if (input.device().is_cuda())          {#ifdef WITH_CUDA    return affine_gpu(input, affine_matrix, out_h, out_w);#else    AT_ERROR("affine is not compiled with GPU support");#endif          }          return affine_cpu(input, affine_matrix, out_h, out_w);}
            // 使用pybind11模塊定義python/pytorch接口PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {  m.def("affine_opencv", &affine_opencv, "affine with c++ opencv");  m.def("affine_torch", &affine_torch,   "affine with c++ libtorch");}


            從上面代碼可以看出,Python 中的 np.array 數(shù)組與 pybind11 的 py::array_t 相互對(duì)應(yīng),也即 Python 接口函數(shù)中,傳入的 np.array 數(shù)組,在 C++ 對(duì)應(yīng)的函數(shù)中用 py::array_t 接收,操作 Numpy 數(shù)組,需要引入頭文件。


            數(shù)組本質(zhì)上在底層是一塊一維的連續(xù)內(nèi)存區(qū),通過(guò) pybind11 中的 request() 函數(shù)可以把數(shù)組解析成 py::buffer_info 結(jié)構(gòu)體,buffer_info 類型可以公開一個(gè)緩沖區(qū)視圖,它提供對(duì)內(nèi)部數(shù)據(jù)的快速直接訪問,如下代碼所示:










            struct buffer_info {    void *ptr;                         // 指向數(shù)組(緩沖區(qū))數(shù)據(jù)的指針    py::ssize_t itemsize;              // 數(shù)組元素總數(shù)    std::string format;                // 數(shù)組元素格式(python表示的類型)    py::ssize_t ndim;                  // 數(shù)組維度信息    std::vector<py::ssize_t> shape;    // 數(shù)組形狀    std::vector<py::ssize_t> strides;  // 每個(gè)維度相鄰元素的間隔(字節(jié)數(shù)表示)};


            在寫好 C++ 源碼以后,在 setup.py 中將相關(guān) C++ 源文件,以及依賴的第三方庫(kù):opencv、pybind11 的路徑寫入對(duì)應(yīng)位置(本工程已經(jīng)寫好,請(qǐng)具體看 setup.py 文件),然后進(jìn)行編譯和安裝:








            # 切換工作路徑step 1: cd F:/code/python_cpp_extension# 編譯step 2: python setup.py develop# 安裝, 如果沒有指定--prefix, 則最終編譯成功的安裝包(.egg)文件會(huì)安裝到對(duì)應(yīng)的python環(huán)境下的site-packages下.step 3: python setup.py install


            【注】:關(guān)于工程文件中的 setup.py 相關(guān)知識(shí)可以參考文獻(xiàn) [7]、[12]、[13],該三篇文獻(xiàn)對(duì)此有詳細(xì)的解釋。


            執(zhí)行 step 2 和 step3 之后,如下圖所示,最終源碼文件會(huì)編譯成 .pyd 二進(jìn)制文件(Linux 系統(tǒng)下編譯成 .so 文件),且會(huì)生成一個(gè) Python 包文件:orbbec-0.0.1-py36-win-amd64.egg,包名取決于 setup.py 中規(guī)定的 name 和 version 信息,該安裝包會(huì)被安裝在當(dāng)前 Python環(huán)境的 site-packages 文件夾下。


            同時(shí),在終端執(zhí)行命令:pip list,會(huì)發(fā)現(xiàn)安裝包以及對(duì)應(yīng)的版本信息。安裝成功后,也就意味著,在該 Python環(huán)境(本工程的 Python環(huán)境是 cpp_extension)下,可以在任何一個(gè) Python 文件中,導(dǎo)入 orbbec 安裝包中的接口函數(shù),比如上述 scripts/test_warpaffine_opencv.py 文件中的語(yǔ)句:from orbbec.warpaffine import affine_opencv。


            圖片

            編譯和安裝成功


            圖片

            pip list 顯示相關(guān)安裝包信息


            編譯完成后,可以運(yùn)行 tools/collect_env.py,查看當(dāng)前一些必要工具的版本等一系列信息,輸出如下:


























            sys.platform    : win32Python  : 3.6.13 |Anaconda, Inc.| (default, Mar 16 2021, 11:37:27) [MSC v.1916 64 bit (AMD64)]CUDA available  : TrueCUDA_HOME       : C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1NVCC    : Not AvailableGPU 0   : NVIDIA GeForce GTX 1650OpenCV  : 3.4.0PyTorch : 1.5.0PyTorch compiling details       : PyTorch built with:  - C++ Version: 199711  - MSVC 191627039  - Intel(R) Math Kernel Library Version 2020.0.0 Product Build 20191125 for Intel(R) 64 architecture applications  - Intel(R) MKL-DNN v0.21.1 (Git Hash 7d2fd500bc78936d1d648ca713b901012f470dbc)  - OpenMP 200203  - CPU capability usage: AVX2  - CUDA Runtime 10.1  - NVCC architecture flags: -gencode;arch=compute_37,code=sm_37;-gencode;arch=compute_50,code=sm_50;-gencode;arch=compute_60,code=sm_60;-gencode;arch=compute_61,code=sm_61;-gencode;arch=compute_70,code=sm_70;-gencode;arch=compute_75,code=sm_75;-gencode;arch=compute_37,code=compute_37  - CuDNN 7.6.4  - Magma 2.5.2  - Build settings: BLAS=MKL, BUILD_TYPE=Release, CXX_FLAGS=/DWIN32 /D_WINDOWS  /GR  /w /EHa /bigobj -openmp -DNDEBUG -DUSE_FBGEMM, PERF_WITH_AVX=1, PERF_WITH_AVX2=1, PERF_WITH_AVX512=1, USE_CUDA=ON, USE_EXCEPTION_PTR=1, USE_GFLAGS=OFF, USE_GLOG=OFF, USE_MKL=ON, USE_MKLDNN=ON, USE_MPI=OFF, USE_NCCL=OFF, USE_NNPACK=OFF, USE_OPENMP=ON, USE_STATIC_DISPATCH=OFF,
            TorchVision     : 0.6.0C/C++ Compiler  : MSVC 191627045CUDA Compiler   : 10.1


            在運(yùn)行 scripts/test_warpaffine_opencv.py 文件之前,由于 warpaffine_opencv.cpp 源碼用到相關(guān) opencv 庫(kù),因此,還需要配置動(dòng)態(tài)庫(kù)路徑,Windows 系統(tǒng)配置如下:


            圖片

            Windows 相關(guān)環(huán)境配置(opencv 第三方庫(kù))


            Linux 系統(tǒng)同樣也需要配置進(jìn)行配置,命令如下:




            root@aistation:/xxx/code/python_cpp_extension# export LD_LIBRARY_PATH=/xxx/code/python_cpp_extension/3rdparty/opencv/linux/libroot@aistation:/xxx/code/python_cpp_extension# ldconfig


            也可以通過(guò)修改 ~/.bashrc 文件,加入上述 export LD_LIBRARY_PATH=/...,然后命令:source ~/.bashrc。也可以直接修改配置文件 /etc/profile,與修改 .bashrc 文件 一樣,對(duì)所有用戶有效。


            可以通過(guò) tools 下的 Dependencies_x64_Release 工具(運(yùn)行:DependenciesGui.exe),查看編譯好的文件(.pyd)依賴的動(dòng)態(tài)庫(kù)是否都配置完好,如下圖所示:


            圖片

            檢查編譯好的動(dòng)態(tài)庫(kù)依賴的動(dòng)態(tài)庫(kù)路徑


            可以發(fā)現(xiàn),該工具沒有找到 python36.dll、c10.dll、torch_cpu.dll、torch_python.dll 和 c10_cuda.dll 的路徑。


            這里說(shuō)明一下,Python 相關(guān)的 dll 庫(kù)以及 torch 相關(guān)的動(dòng)態(tài)庫(kù)是動(dòng)態(tài)加載的,也就是說(shuō),如果你在 Python 代碼中寫一句:import torch,只有在程序運(yùn)行時(shí)才會(huì)動(dòng)態(tài)加載 torch 相關(guān)庫(kù)。


            所以,Dependencies_x64_Release工具檢查不到編譯好的 warpaffine_ext.cp36-win_amd64.pyd 文件依賴完好性。


            這里還需要說(shuō)明一下為什么 warpaffine_ext.cp36-win_amd64.pyd 需要依賴 torch 相關(guān)庫(kù),這是因?yàn)樵次募?orbbec/warpaffine/src/warpaffine_ext.cpp 兼容了 PyTorch 的 C++ 拓展,所以依賴 torch 和 cuda 相關(guān)動(dòng)態(tài)庫(kù)文件,如果你單純只在 orbbec/warpaffine/src/warpaffine_ext.cpp 實(shí)現(xiàn)純粹 Python 的 C++拓展,則是不需要依賴 torch 和 cuda 相關(guān)動(dòng)態(tài)庫(kù)。


            配置好之后,還需要將 warpaffine_ext.cp36-win_amd64.pyd 無(wú)法動(dòng)態(tài)加載的動(dòng)態(tài)庫(kù)文件(opencv_world453.dll)放到 scripts/test_warpaffine_opencv.py 同路徑之下(Linux 系統(tǒng)也一樣),如下圖所示:


            圖片

            拷貝動(dòng)態(tài)庫(kù)與測(cè)試腳本同一目錄


            需要注意一個(gè)問題,有時(shí)候,如果在 docker 中進(jìn)行編譯和安裝,其最終生成的 Python 安裝包(.egg)文件并不會(huì)安裝到當(dāng)前 Python 環(huán)境下的 site-packages 中。


            也就意味著,在 Python 文件中執(zhí)行:from orbbec.warpaffine import affine_opencv 會(huì)失敗。


            原因是 orbbec.warpaffine 并不在其 Python 的搜索路徑中,這個(gè)時(shí)候有兩種解決辦法:一種是在執(zhí)行:python setup.py install 時(shí),加上 --prefix='install path',但是經(jīng)過(guò)本人驗(yàn)證,有時(shí)候不可行,另外一種辦法是在 Python 文件中,將 orbbec 文件夾路徑添加到 Python 的搜索路徑中,如下所示:











            import cv2import torch  # 不能刪掉, 因?yàn)樾枰獎(jiǎng)討B(tài)加載torch的一些動(dòng)態(tài)庫(kù).import numpy as np
            # 添加下述兩行代碼,這里默認(rèn)此python腳本所在目錄的上一層目錄路徑包含orbbec文件夾._FILE_PATH = os.path.dirname(os.path.abspath(__file__))sys.path.insert(0, os.path.join(_FILE_PATH, "../"))
            from orbbec.warpaffine import affine_opencv  # C++ interface



            *博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



            關(guān)鍵詞: AI

            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉