提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
最近在做一个项目,用到了opencv
里面的jepg
编解码,当你使用opencv
的imwrite
或者imread
命令的时候,实际上已经完成了jpeg的编码或解码,这个方法调用的是CPU来计算的,速度不理想。有条件的话可以使用硬编解码资源,如果没有硬编解码资源的话就需要借用turbojpeg
库了。实际测试使用了turbojpeg
之后速度最大可以提升4-6倍,提升还是很明显的。turbojpeg
在ARM和x86
上都是有效的,其中arm
需要armv7
以后的CPU且要支持neon
单元,x86
需要支持sse
指令集。
接下来就分别演示怎么分别在arm
和x86
上让opencv
支持turbojpeg
。
一、SIMD
SIMD全称Single Instruction Multiple Data,单指令多数据流,能够复制多个操作数,并把它们打包在大型寄存器的一组指令集。
以加法指令为例,单指令单数据(SISD)的CPU对加法指令译码后,执行部件先访问内存,取得第一个操作数;之后再一次访问内存,取得第二个操作数;随后才能进行求和运算。而在SIMD型的CPU中,指令译码后几个执行部件同时访问内存,一次性获得所有操作数进行运算。这个特点使SIMD特别适合于多媒体应用等数据密集型运算。
如:AMD公司引以为豪的3D NOW! 技术实质就是SIMD,这使K6-2、雷鸟、毒龙处理器在音频解码、视频回放、3D游戏等应用中显示出优异的性能。
二、SSE
SSE(Streaming SIMD Extensions)是英特尔在AMD的3D Now!发布一年之后,在其计算机芯片Pentium III中引入的指令集,是继MMX的扩展指令集。SSE指令集提供了70条新指令。AMD后来在Athlon XP中加入了对这个新指令集的支持。
SSE是 “因特网数据流单指令序列扩展 ( Internet Streaming SIMD Extensions)的缩写。SSE除保持原有的MMX指令外,又新增了70条指令,在加快浮点运算的同时,改善了内存的使用效率,使内存速度更快。它对游戏性能的改善十分显著,按Intel的说法,SSE对下述几个领域的影响特别明显:3D几何运算及动画处理、图形处理(如Photoshop)、视频编辑/压缩/解压(如MPEG和DVD)、语音识别以及声音压缩和合成等。
SSE由一组队结构的扩展组成,用以提高先进的媒体和通信应用程序的性能。该扩展(包括新的寄存器、新的数据类型和新的指令)与单指令多数据(SIMD)技术相结合,有利于加速应用程序的运行。这个扩展与MMX技术相结合,将显著地提高多媒体应用程序的效率。
三、编译
1.编译turbojpeg
你需要到turbojpeg
官网去下载源代码,这里使用的是2.0.2版本,其他版本请自行测试。
cd libjpeg-turbo-2.0.2
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install ..
make -j$(nproc)
make install
编译完成之后就安装到install文件夹了,留着后面给opencv用。
1.编译opencv
到opencv
官网下载opencv
的源代码,这里用的是4.5.1,其他版本请自行测试。
cd opencv-4.5.1
mkdir build && cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D INSTALL_C_EXAMPLES=OFF \
-D INSTALL_PYTHON_EXAMPLES=OFF \
-D PYTHON_DEFAULT_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)") \
-D PYTHON3_EXECUTABLE=$(python3 -c "import sys; print(sys.executable)") \
-D PYTHON3_NUMPY_INCLUDE_DIRS=$(python3 -c "import numpy; print (numpy.get_include())") \
-D PYTHON3_PACKAGES_PATH=$(python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())") \
-DENABLE_NEON=ON \
-D WITH_TBB=ON \
-DBUILD_TBB=ON \
-D WITH_V4L=ON \
-DWITH_QT=OFF \
-DWITH_CUDA=OFF \
-DWITH_NVCUVID=OFF \
-D WITH_OPENGL=ON \
-D BUILD_EXAMPLES=OFF \
-D WITH_JPEG=ON \
-D BUILD_JPEG=OFF \
-D JPEG_INCLUDE_DIR=../../libjpeg-turbo-2.0.2/install/include \
-D JPEG_LIBRARY=../../libjpeg-turbo-2.0.2/install/lib/libjpeg.so ..
make -j$(nproc)
sudo make install
opencv
的编译选项根据个人需要编译,和jpeg
相关的必须按照上面的配置。引用的头文件和库就是刚才安装的install
文件夹下面。
1.测试效果
随便找一个jpeg
使用opencv
的imread
或imwrite
都会调用simd
指令,一般速度会有3倍以上的提升,至于4-6倍看设备性能了。
总结
生产力提升还是很明显的,值得一试。