日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

OpenCV-Python bindings是如何生成的(2)

發(fā)布時間:2024/8/23 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV-Python bindings是如何生成的(2) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

OpenCV-Python bindings生成流程

通過上篇文章和opencv python模塊中的CMakeLists.txt文件,可以了解到opencv-python bindings生成的整個流程:

  • 生成headers.txt文件
    將每個模塊的頭文件添加到list中,通過一些關(guān)鍵詞過濾掉一些不需要擴(kuò)展的頭文件,file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs}")將過濾后的list寫入文件;
    headers.txt保存需要轉(zhuǎn)換的頭文件路徑,英文;隔開,注意文件末尾沒有換行符

  • 生成cv2.cpp中需要的頭文件

    set(cv2_generated_hdrs"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_include.h""${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_funcs.h""${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_types.h""${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_type_reg.h""${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_ns_reg.h")file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs}") add_custom_command(OUTPUT ${cv2_generated_hdrs}COMMAND ${PYTHON_EXECUTABLE} "${PYTHON_SOURCE_DIR}/src2/gen2.py" ${CMAKE_CURRENT_BINARY_DIR} "${CMAKE_CURRENT_BINARY_DIR}/headers.txt"DEPENDS ${PYTHON_SOURCE_DIR}/src2/gen2.pyDEPENDS ${PYTHON_SOURCE_DIR}/src2/hdr_parser.pyDEPENDS ${CMAKE_CURRENT_BINARY_DIR}/headers.txtDEPENDS ${opencv_hdrs})

    通過調(diào)用gen2.py來實現(xiàn)的,第一個參數(shù)是生成頭文件后保存的路徑,第二個參數(shù)是headers.txt文件路徑

  • 將cv2.cpp編譯成動態(tài)庫

  • OpenCV-Python bindings實踐操作

    紙上得來終覺淺,絕知此事要躬行。整個事情的來龍去脈都已經(jīng)講清楚,單到底怎么應(yīng)用到自己的項目中呢。比如將自己圖像檢測功能實現(xiàn)完成,老大要求將它寫成Web服務(wù),畢竟B/S模式非常流程。C++寫Web?開國際玩笑吧,現(xiàn)在python非常流行的天下。那么接下來看看怎么講c++功能函數(shù)類轉(zhuǎn)換成python的擴(kuò)展庫吧。

    網(wǎng)上查查資料,還真有相關(guān)的blog:

    • How to convert your OpenCV C++ code into a Python module
    • github code https://github.com/spmallick/learnopencv/tree/master/pymodule

    博客寫的很好,但是提供的源碼千般嘗試始終報錯,于是乎決定自己從CMakeLists.txt看起,從gen2.py腳本看起,慢慢查實。

    mkdir ovex cd ovex mkdir src cp ../opencv-3.1.0/modules/python/src2/{pycompat.hpp,cv2.cpp,gen2.py,hdr_parser.py} ./ cp ../learnopencv-master/pymodule/src/* src/ cp ../learnopencv-master/pymodule/headers.txt ./

    準(zhǔn)備使用opencv-3.1.0源碼中的pycompat.hpp,cv2.cpp,gen2.py,hdr_parser.py文件,使用上面博客中的opencv c++源文件,慢慢來

    gen2.py ./ headers.txt命令,第一步就報錯了IOError: [Errno 2] No such file or directory: 'src/bvmodule.hpp\n'
    看到文件名后面居然有個換行符,哎,拿到windows下刪掉換行符。

    去掉headers.txt中的換行符在去執(zhí)行上面的命令,報出另外一個錯誤

    Traceback (most recent call last):File "./gen2.py", line 943, in <module>generator.gen(srcfiles, dstdir)File "./gen2.py", line 855, in genself.code_include.write( '#include "{0}"\n'.format(hdr[hdr.rindex('opencv2/'):]) ) ValueError: substring not found

    hdr.rindex('opencv2/')取頭文件中opencv/的位置,hdr[hdr.rindex('opencv2/'):])取頭文件中opencv/之后的所有字符串。看樣子腳本是opencv定制,應(yīng)用需要改動腳本某些地方,通過不斷嘗試,幾經(jīng)修改,終于大功告成。gen2.py ./ headers.txt命令在當(dāng)前目錄下生成pyopencv_generated_funcs.h pyopencv_generated_include.h pyopencv_generated_ns_reg.h pyopencv_generated_type_reg.h pyopencv_generated_types.h文件。gen2.py修改如下

    調(diào)整博客提供的編譯命令,編譯動態(tài)庫

    g++ -shared -rdynamic -g -O3 -Wall -fPIC \ -I . -I../ -I/usr/local/python2.7.14/lib/python2.7/site-packages/numpy/core/include \ cv2.cpp src/bvmodule.cpp \ -DNDEBUG \ `PKG_CONFIG_PATH=/usr/local/opencv_with_contrib3.1.0/lib/pkgconfig pkg-config --cflags --libs opencv` \ `/usr/local/python2.7.14/bin/python2.7-config --includes --ldflags` \ -L`/usr/local/python2.7.14/bin/python2.7-config --exec-prefix`/lib \ -o bv.so

    出錯

    cv2.cpp:124: 錯誤:‘Stitcher’未聲明 cv2.cpp:124: 錯誤:expected initializer before ‘Status’ cv2.cpp:474: 錯誤:ISO C++ 不允許聲明無類型的‘Status’ cv2.cpp:474: 錯誤:expected ‘,’ or ‘...’ before ‘&’ token cv2.cpp:474: 錯誤:‘PyObject* pyopencv_from(int)’的模板標(biāo)識符‘pyopencv_from<>’不匹配任何模板聲明 cv2.cpp:1257: 警告:‘int convert_to_char(PyObject*, char*, const char*)’定義后未使用

    類型未聲明,用不到的話就刪掉吧

    再次執(zhí)行編譯命令,期待的so動態(tài)庫在當(dāng)前目錄生成了。那就試他一試吧,

    ovex]$ python2.7 Python 2.7.14 (default, Jul 25 2018, 13:52:02) [GCC 4.4.7 20120313 (Red Hat 4.4.7-23)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import bv Traceback (most recent call last):File "<stdin>", line 1, in <module> ImportError: dynamic module does not define init function (initbv)

    這個錯誤的出現(xiàn)不得不促使我去了解一下C/C++為python做擴(kuò)展的整個流程,Extending and Embedding the Python Interpreter,注意python2與python3是有差異的。

    很容易發(fā)現(xiàn),模塊需要一個對應(yīng)初始化函數(shù)來初始化模塊,比如PyInit_bv,那么在opencv中這個初始化函數(shù)在哪定義的呢?直接點在當(dāng)前目錄下執(zhí)行g(shù)rep -n --color=auto "cv2" -R *,在cv2.cpp中找到我們想要的函數(shù)了,接下來就是修改了

    模塊的名稱是通過MODULESTR來定義的,python2以及python3中模塊初始化函數(shù)的聲明與定義。
    再次編譯成功通過,測試OK

    $ python2.7 Python 2.7.14 (default, Jul 25 2018, 13:52:02) [GCC 4.4.7 20120313 (Red Hat 4.4.7-23)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import bv >>> import numpy as np >>> dir(bv) ['CV_16S', 'CV_16SC1', 'CV_16SC2', 'CV_16SC3', 'CV_16SC4', 'CV_16U', 'CV_16UC1', 'CV_16UC2', 'CV_16UC3', 'CV_16UC4', 'CV_32F', 'CV_32FC1', 'CV_32FC2', 'CV_32FC3', 'CV_32FC4', 'CV_32S', 'CV_32SC1', 'CV_32SC2', 'CV_32SC3', 'CV_32SC4', 'CV_64F', 'CV_64FC1', 'CV_64FC2', 'CV_64FC3', 'CV_64FC4', 'CV_8S', 'CV_8SC1', 'CV_8SC2', 'CV_8SC3', 'CV_8SC4', 'CV_8U', 'CV_8UC1', 'CV_8UC2', 'CV_8UC3', 'CV_8UC4', 'Filters', '__doc__', '__file__', '__name__', '__package__', '__version__', 'createTrackbar', 'error', 'fillHoles', 'setMouseCallback'] >>> import cv2 >>> img = cv2.imread("holes.jpg") >>> bv.fillHoles(img) >>> cv2.imwrite("filledHoles.jpg", img) True >>>

    總結(jié)

    以上是生活随笔為你收集整理的OpenCV-Python bindings是如何生成的(2)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。