CUDA+OPENCV+PYTHON tensorflow 源码环境搭建

接上文caffe环境安装

主机环境ubuntu18.04 x86/x64系统 (实体机)

一.bazel的安装

安装指南官网地址见https://docs.bazel.build/versions/master/install-ubuntu.html

python cuda释放内存_python


需要jdk1.8支持

请先安装java jdk1.8此处不做详细说明自行官网参考

继续
步奏1

sudo apt install g++ unzip zip

接下来可以按照官方给出安装java jdk。此处我是从java官网安装,也可参见此网方法安装

sudo apt-get install openjdk-11-jdk

bazel二进制下载地址
https:///bazelbuild/bazel/releases 此时得到如此文件
bazel-0.26.1-installer-linux-x86_64.sh
安装方式为

./bazel-0.26.1-installer-linux-x86_64.sh \
     --prefix=/home/guan/tools/bazel/install_output \
     --bin=/home/guan/tools/bazel/install_output/bin \

此处将文件安装在当前bazel目录下面install_output文件夹里面

安装完成后如下

python cuda释放内存_opencv_02


envs文件里面添加bazel环境变量

export PATH=$PATH:/home/guan/tools/bazel/install_output/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/guan/tools/bazel/install_output/lib

执行

source envs

执行bazel

python cuda释放内存_opencv_03


看到这个截图及安装完成

二.创建python3.6 tensorflow环境

请注释caffe环境变量

export PYTHONPATH=/home/guan/tools/caffe/build/install/python

python cuda释放内存_python cuda释放内存_04


新建一个终端执行

source envs_python_36

envs_python_36 为修改后上述截图文件

执行

conda create -n tensorflow python=3.6

等待创建完成

激活tensorflow环境

conda activate tensorflow

python cuda释放内存_python cuda释放内存_05

三.安装python-opencv4

进入已编译好的opencv4源码build/python_loader目录

python cuda释放内存_python_06

执行

python setup.py build
python setup.py install

等待编译安装成功

1.OpenCV loader: missing configuration file: [‘config-3.6.py’, ‘config-3.py’]. Check OpenCV installation 错误

错误截图如下

python cuda释放内存_linux_07


报错config-3.6.py config-3.py缺失

尝试创建软链接将config-3.6.py ---->config.py

2.ERROR: recursion is detected during loading of “cv2” binary extensions. Check OpenCV installation

查看了半天资料分析得出:

上面的步奏1 2 均是错误

错误1

config-3.6.py config-3.py缺失

我打开了config.py文件对比了别人正常安装的config-3.6.py config-3.py文件

python cuda释放内存_opencv_08

上图左边为config.py文件,右边为config-3.6.py文件

发现是BINARIES_PATHSPYTHON_EXTENSIONS_PATHS变量的区别。

从命名看3.6应该是python的扩展属性,但这里却缺少文件。

错误2
提示:cv2加载二进制扩展时检测到错误,先就这么理解吧。我英语水平不是咋样好 哈哈。
此时联系错误1顿时想起了是缺少扩展问题。

3.错误的解决

之后顿时想到了我已编译的opencv的python是caffe环境编译的为python2.7,而此时我的python环境为python3.6
此时我有以下几点注意情况
************************************************************
1.opencv python编译环境必须2.7对应caffe编译一套,3.6对应tensorflow编译一套针对环境使用。
2.重新编译opencv之后caffe或着tensorflow也必须重新编译。
3.caffe和tensorfow环境必须分两个envs环境变量使用
************************************************************
解决
步奏1
进入opencv源码目录创建build_py36文件夹

mkdir build_py36

修改安装目录

打开CMakeLists.txt

python cuda释放内存_linux_09


修改如下文字(上图为已修改)

set(CMAKE_INSTALL_PREFIX "/home/guan/tools/opencv/build_py36/install_opencv4" CACHE PATH "Installation Directory" FORCE)

进入build_py36
接下来

cmake ..

python cuda释放内存_tensorflow_10

看上图python 为python2.7依然是有问题的
最终我分析cmake语言
见文件…/cmake/OpenCVDetectPython.cmake

python cuda释放内存_linux_11

其中代码:

if(PYTHON_DEFAULT_EXECUTABLE)
    set(PYTHON_DEFAULT_AVAILABLE "TRUE")
elseif(PYTHON2_EXECUTABLE AND PYTHON2INTERP_FOUND)
    # Use Python 2 as default Python interpreter
    set(PYTHON_DEFAULT_AVAILABLE "TRUE")
    set(PYTHON_DEFAULT_EXECUTABLE "${PYTHON2_EXECUTABLE}")
elseif(PYTHON3_EXECUTABLE AND PYTHON3INTERP_FOUND)
    # Use Python 3 as fallback Python interpreter (if there is no Python 2)
    set(PYTHON_DEFAULT_AVAILABLE "TRUE")
    set(PYTHON_DEFAULT_EXECUTABLE "${PYTHON3_EXECUTABLE}")
endif()

可以明显看出是如果查找到了python2则结束,只有在python2找不到的时候才去查找python3
于是我添加了下面代码:

#指定python3  0 python2   1 python3
set(PYTHON3_IS_ON 1)                                                                                                                                  
if(PYTHON3_IS_ON)
    set(PYTHON_DEFAULT_AVAILABLE "TRUE")
    set(PYTHON_DEFAULT_EXECUTABLE "${PYTHON3_EXECUTABLE}")
endif()

再次cmake …

python cuda释放内存_python_12


如上图python 已经显示python3

此时想起之前的caffe环境若是也如此安装要千万注意编译opencv的python环境要和你使用的python环境相同

创建install_opencv4文件夹

mkdir install_opencv4

继续

make -j8
make install

修改envs_python_36文件中的python3的opencv编译环境变量

#opencv4
export OPENCV_HOME=/home/guan/tools/opencv/build_py36/install_opencv4       
export PATH=$PATH:$OPENCV_HOME/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$OPENCV_HOME/lib

python cuda释放内存_python_13


envs_python_36为我的tensorflow所需要的环境变量文件

接下来

source ~/tools/envs_python_36

4.正式开始安装opencv4-python

进入opencv源码目录build_py36/python_loader

python cuda释放内存_tensorflow_14

执行

python setup.py build
python setup.py install

最后验证

我的擦错误!!!依然是

python cuda释放内存_opencv_15

容我缓缓差点要崩溃了!!!!!!!!!!

但 !!! 我在caffe python2.7上面已按照上述方法测试成功了看了CMakeList.txt 代码这里:

python cuda释放内存_python cuda释放内存_16


突然想起之前caffe的python输出比tensorflow这里多,我猜想应该是python3的编译开关没有打开。顿时去搜索python2的环境变量:BUILD_opencv_python2

python cuda释放内存_python_17


python3的环境变量:BUILD_opencv_python3

python cuda释放内存_python cuda释放内存_18

对比我发现BUILD_opencv_python3这个宏被设置OFF了,但是发现没有任何一个代码来设置这宏,我纳闷了好久。网上查得,原来这种宏是在cmake 时采用-D 带入的参数

于是我脑子里浮现出代码

cmake .. -DBUILD_opencv_python3=ON

结果

python cuda释放内存_linux_19


缺少库 Libraries 为NO

我忽略继续编译&安装&安装opencv-python都成功,但最终Import cv2依然是上述错误。

于是我继续调试代码发现…/cmake/OpenCVDetectPython.cmake 这个文件中查找python库的函数find_python函数中:

if(NOT ${found})

竟然不成立也就是也就是OpenCVDetectPython.cmake 这个文件更本就不起作用

我尼玛 。。。。。( 抱歉我得文明)

最后分析出

python cuda释放内存_tensorflow_20

选中的变量为OFF才能使刚刚那个主要查找python的函数起作用

继续分析

grep PYTHON3INTERP_FOUND -r ../

判断出PYTHON3INTERP_FOUND的值默认为ON
由于没有截到图我就不回去截图了哈
但这个变量依然没有代码设置,于是我猜它应该也是通过-D来输入变量值的吧。
于是我脑子有个大胆的想法

cmake .. -DBUILD_opencv_python3=ON -DPYTHON3INTERP_FOUND=OFF

结果

python cuda释放内存_opencv_21

界面

Libraries:                   /home/guan/tools/anaconda3/envs/tensorflow/lib/ (ver 3.6.10)

而上面变为NO 这符合代码分析
则继续

make -j8
mkdir install_opencv4
make install
cd ./python_loader/
python setup.py build
python setup.py install

都成功了
最终测试

import cv2

终于没有任何报错了 OK

附上截图一张

python cuda释放内存_linux_22

5.opencv-python安装总结

上述代码中我通过修改了源码完成以下操作
1.修改安装目录
2.修改查找指定的python3
这样再编译caffe opencv时又得改回代码此处不理想

原则上编译最好不要去动源码来保证源码的干净
我网上查得
可以如下:

CMAKE_INSTALL_PREFIX=/usr #安装路径

上面代码没有验证

代码分析得出:

PYTHON_DEFAULT_EXECUTABLE=/usr/bin/python3.6 #你的python执行文件路径

python cuda释放内存_python_23


这个代码的意思是上面的find_python函数执行完成后

PYTHON_DEFAULT_EXECUTABLE=你的python可执行文件路径而不再为空所以该if语句只执行了第一行赋值PYTHON_DEFAULT_AVAILABLE为TRUE

(find_python found 变量为ON时则PYTHON_DEFAULT_EXECUTABLE为空)

最终则

PYTHON_DEFAULT_AVAILABLE="TRUE"
PYTHON_DEFAULT_EXECUTABLE=你的python可执行文件路径

最终上述1 2问题都得到解决
所以此处不需要修改代码
最终得出无需修改任何源码执行命令

cmake .. -DBUILD_opencv_python3=ON -DPYTHON3INTERP_FOUND=OFF -DCMAKE_INSTALL_PREFIX=/home/guan/tools/opencv/build_py36/install_opencv4

四.编译tensorflow

进入tensorflow源码

编译

运行

./configure

python cuda释放内存_python cuda释放内存_24

python cuda释放内存_linux_25


按照上面选择注意下图这里选择N 不使用clang编译cuda

python cuda释放内存_python cuda释放内存_26

继续

python cuda释放内存_tensorflow_27


没有报错

好现在我们开始使用bazel编译

编译指南见官网:

https://tensorflow.google.cn/install/source

python cuda释放内存_python_28


执行

bazel build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package

等待30分钟
结果错误1
Unknown option ‘-bin2c-path’
于是我搜索-bin2c-path

grep "\-bin2c\-path" -r ./

python cuda释放内存_python_29

于是我查看了此文件

python cuda释放内存_python_30


猜测这个bin2c-path肯定是设置bin2c的路径的,于是我github下载了一个bin2c工程
并且将这个bin2c可执行文件加入环境变量,并且屏蔽该无法识别的’-bin2c-path’选项

如上截图已屏蔽(编译后报错,建议直接删掉吧 不知道咋屏蔽 哈哈)

接着继续

bazel build --cnotallow=opt --cnotallow=cuda //tensorflow/tools/pip_package:build_pip_package

等待2个小时…

结果错误2
No module named ‘keras_preprocessing’
解决方案:

pip install keras_preprocessing

再次继续
bazel build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package

编译OK

附上成功截图

python cuda释放内存_opencv_31

此处应有总结

1.编译tensorflow 需要安装opencv-python (建议和C版本相同,及从opencv源码安装)

2.需要bin2c可执行环境支持,请自行下载。并源码按照上述方案修改(去掉bin2c-path)。

3.安装keras_preprocessing

*******************************************************************

python cuda释放内存_python_32

编译打包完整版分支的包

./bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg

编译打包master的包

./bazel-bin/tensorflow/tools/pip_package/build_pip_package --nightly_flag /tmp/tensorflow_pkg

我不懂打包为master是啥意思,果断选择 release分支
于是执行 release分支代码

安装

python cuda释放内存_python cuda释放内存_33

pip install /tmp/tensorflow_pkg/tensorflow-version-tags.whl

注意上面的version-tags请根据自己的版本名字来

安装完成附图一张:

python cuda释放内存_linux_34

测试

import tensorflow

python cuda释放内存_tensorflow_35


结果警告:in a future version of numpy, it will be understood as (type, (1,)) / ‘(1,)type’

提示numpy为未来版本意思是要版本降级。

仔细查看官网一开始的文字,我找到了解决问题的答案,同时keras_preprocessing的安装也在官网给出,抱歉,我没有仔细看官网说明。

附上官网截图:

python cuda释放内存_linux_36


其中keras_preprocessing的安装正确方式:

pip install -U --user keras_applications --no-deps
pip install -U --user keras_preprocessing --no-deps

注意当为虚拟机时应取消–user的选项
附上官网原话 : if using a virtual environment, omit the --user argument

keras_preprocessing我已经安装了,算了以后有问题再重新按照官网给出严格安装一遍吧。
–no-deps是在离线安装whl时去掉依赖包的安装时使用的参数

anaconda应该也算虚拟环境吧
于是我:

pip install -U  pip six numpy wheel setuptools mock 'future>=0.17.1' -i https://pypi.tuna.tsinghua.edu.cn/simple some-package

来安装numpy

import tensorflow

结果依然错误:FutureWarning: Passing (type, 1) or ‘1type’n a future version of numpy, it will be understood as (type, (1,)) / ‘(1,)type’

python cuda释放内存_python_37

我猜是numpy版本兼容的问题,可是已经按照官网的方案安装了numpy。疑惑半天我。

最终我看了一个python程序高手的博客给出的答案解决了问题。

方法:

修改

/home/guan/tools/anaconda3/envs/tensorflow/lib/python3.6/site-packages/tensorboard/compat/tensorflow_stub/dtypes.py 这个文件代码:

python cuda释放内存_linux_38


上图为修改后的代码,请自行对照你自己的代码

_np_qint8 = np.dtype([("qint8", np.int8, (1,))])                                                                                                                      
 _np_quint8 = np.dtype([("quint8", np.uint8, (1,))])
 _np_qint16 = np.dtype([("qint16", np.int16, (1,))])
 _np_quint16 = np.dtype([("quint16", np.uint16, (1,))])
 _np_qint32 = np.dtype([("qint32", np.int32, (1,))])

同时我给出那个哥们的截图

python cuda释放内存_python cuda释放内存_39


最终测试

import tensorflow

OK 到此安装成功

附上成功截图

python cuda释放内存_linux_40

至此完