嵌入式开发之Opencv(二)JPEG解码加速

参考文档

  1. libjpeg-turbo官网
  2. libjpeg-turbo github主页
  3. JPEG高速低画质选项设置
  4. Speed-Up JPEG Encode/Decode Processing for OpenCV using libjpeg-turbo
  5. libjpeg-turbo性能报告与建议
  6. libjpeg对于(I)DCT Scale的支持和快速实现

开发环境介绍

  • 主机操作系统:Ubuntu14.04 64位
  • 目标平台:BoxV3 全志H8
  • 交叉工具链:arm-linux-gnueabihf,gcc4.8.5
  • opencv版本:3.2.0
  • libjpeg-turbo:1.5.90
  • 编译时间:2018.7.26

libjpeg-turbo介绍

libjpeg-turbo是一个使用SIMD技术(MMX、SSE2、AVX2、NEON)进行加速的JPEG编码解码器,能够在基于x86、x86_64、arm的系统上使用。相对于标准版libjpeg能够提供2-6x的性能提升。

libjpeg-turbo交叉编译

设置本地编译链和交叉编译链

# 在/etc/bash.bashrc的最后增加如下指令
# Native Compiler
export AR_host="ar"
export CC_host="gcc"
export CXX_host="g++"
export LINK_host="g++"

# Allwinner H8 BoxV3 cross compiler, Qt 5.8.0 SDK
export ARCH=arm
export PATH=/home/root/CQA83TLinux_Qt5.8.0_bv3/buildroot-2017.02.3/output/host/usr/bin/:$PATH
export CROSS_COMPILE=arm-buildroot-linux-gnueabihf-
export CC=/home/root/CQA83TLinux_Qt5.8.0_bv3/buildroot-2017.02.3/output/host/usr/bin/arm-buildroot-linux-gnueabihf-gcc    
export CXX=/home/root/CQA83TLinux_Qt5.8.0_bv3/buildroot-2017.02.3/output/host/usr/bin/arm-buildroot-linux-gnueabihf-g++    
export LD=/home/root/CQA83TLinux_Qt5.8.0_bv3/buildroot-2017.02.3/output/host/usr/bin/arm-buildroot-linux-gnueabihf-ld
export AR=/home/root/CQA83TLinux_Qt5.8.0_bv3/buildroot-2017.02.3/output/host/usr/bin/arm-buildroot-linux-gnueabihf-ar
export AS=/home/root/CQA83TLinux_Qt5.8.0_bv3/buildroot-2017.02.3/output/host/usr/bin/arm-buildroot-linux-gnueabihf-as
export RANLIB=/home/root/CQA83TLinux_Qt5.8.0_bv3/buildroot-2017.02.3/output/host/usr/bin/arm-buildroot-linux-gnueabihf-ranlib
# 修改完成之后需要重启命令行才能生效
# 你可以通过如下指令来确认交叉编译链是否已经设置好
echo $CC 
# 当显示/home/root/CQA83TLinux_Qt5.8.0_bv3/buildroot-2017.02.3/output/host/usr/bin/arm-buildroot-linux-gnueabihf-gcc时表示交叉编译链
# 已经设置好
# 当需要更换为本机编译时屏蔽上面的指令即可

这里选择最新的1.5.90版本(时间点为2018-6-1)

修改CmakeLists.txt

# 当在配置cmake时出现了找不到system和cpu时,在cmake文件开头手动指定
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

新建cmake Build目录

cd libjpeg-turbo-1.5.90
mkdir _build

打开cmake-gui进行交叉编译链配置

这里写图片描述

选择Specify options for cross-compiling,进入交叉编译链设置界面

这里写图片描述

点击Configure

再次修改设置选项:

# 指定安装类型和目录
CMAKE_BUILD_TYPE                  Release
CMAKE_INSTALL_PREFIX              /usr/local/BoxV3/libjpeg-turbo-1.5.90

CMAKE_C_FLAGS                     -mfpu=neon -march=armv7-a -fPIC
CMAKE_CXX_FLAGS                   -mfpu=neon -march=armv7-a -fPIC
WITH_JPEG8                        TRUE # 勾选JPEG8接口仿真,因为opencv只能使用标准JPEG的接口

点击Configure

点击Generate生成Makefile

进入_install目录&编译

cd _build
make -j8 
make install

opencv替换JPEG解码库

在实用cmake-gui配置opencv时手动添加JPEG相关库的信息

JPEG_INCLUDE_DIR   /usr/local/H3/libjpeg-turbo-1.5.90/include # 值为上面编译libjpeg-turbo的目标位置  
JPEG_LIBRARY       /usr/local/H3/libjpeg-turbo-1.5.90/lib/libjpeg.so

BUILD_JPEG         # 这里必须关闭编译3rd_party目录下的jpeg源代码
WITH_JPEG          # 开启 

JPEG解码加速手段

图像局部解码

参考libjpeg.txt的Partial image decompression章节。这个技术适用于性能敏感型的应用场景,在这个场景下我们只需要查看一个大尺寸图像的一部分内容而不需要解码整幅图像。libjpeg提供了两个接口来实现这个功能:

  1. jpeg_skip_scanlines(y方向)
  2. jpeg_crop_scanline(x方向)

IDCT Scale

参考libjpeg.txt的scale_num, scale_denom部分。

这个方法可以通过控制IDCT的Scale功能来实现缩放操作,并且可以大幅减少解码时间。而且如果针对的是深度学习算法,本身网络输入的尺寸一般会小于高清视频的分辨率,这样还可以减少解码之后再次进行缩放的耗时。

Fast Upsampling & Fast IDCT

Multi-Thread

修改Opencv解码设置

代码文件:opencv-3.2.0/modules/imgcodecs/src/grfmt_jpeg.cpp
函数:JpegDecoder::readHeader()
行数:243行

jpeg_read_header( &state->cinfo, TRUE );

// 设置加速解码相关选项
state->cinfo.do_fancy_upsampling = FALSE;
state->cinfo.do_block_smoothing = FALSE;
state->cinfo.dct_method = JDCT_FASTEST;
state->cinfo.dither_mode = JDITHER_NONE;

state->cinfo.scale_num=1;
state->cinfo.scale_denom = m_scale_denom;

性能加速统计

测试芯片:全志H8
opencv版本:3.2.0
libjpeg-turbo版本:1.5.90
解码图片尺寸:1600 x 1200

jpeg版本 解码时间 加速比
opencv自带jpeg 240ms
libjpeg-turbo 118ms
libjpeg-turbo修改设置 91ms
libjpeg-turbo修改设置 + DCT 1/2缩放 55ms

猜你喜欢

转载自blog.csdn.net/sanallen/article/details/80513031