虹软人脸识别——官方 Qt Demo 移植到 Linux

摘要:
打开Linux版本的SDK里面没有发现Demo,于是想着把Windows的Demo移植到Linux。将所有包含的qDebug改为QDebug。将原来使用OpenCV2的接口迁移到目前的OpenCV3。

一、前言

最近需要在 Linux 平台下开发一个人脸识别相关的应用,用到了虹软的人脸识别 SDK。之前在 Windows 平台用过,感觉不错,SDK 里面还带了 Demo 可以快速看到效果。打开 Linux 版本的 SDK 里面没有发现 Demo,于是想着把 Windows 的 Demo 移植到 Linux。这篇文章记录了移植的过程,Linux 用的是 Ubuntu 20.04(使用虚拟机 VMware Workstation 15 Player)。

二、配置依赖

2.1 ArcFace SDK

到虹软官网下载人脸识别 SDK 3.1 Linux 增值版本 解压到合适的目录,并从官网获取 APP_ID、SDK_KEY 和 ACTIVE_KEY,用于写到配置文件用来激活 SDK。

2.2 OpenCV

到 OpenCV 官网下载源码,我用的版本是 3.4.9。可以按照官网的教程 Installation in Linux 自行编译,我参考官网教程使用下面的这些命令在 GCC 9.3.0(Ubuntu 20.04 自带的编译器) 上编译成功。

sudo apt update
sudo apt install build-essential
sudo apt install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
cd <OpenCV 源码目录>
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=<自定义目录> ..
make -j3    # 可以使用核心数 - 1 个线程来编译
sudo make install

2.3 Qt

Qt 使用的是 5.14.2 版本。

三、项目文件

3.1 .pro 文件

原 Windows Demo 使用的是 Visual Studio 2015,在 Linux 下我这里用到了 Qt Creator 进行开发,因此需要编写 .pro 文件,包括以下几个方面:

  • 用到的 Qt 模块
  • 编译出来的程序名
  • 用到的头文件、源文件和资源文件
  • 依赖库的头文件及库名

虹软人脸识别——官方 Qt Demo 移植到 Linux第1张

更具体的内容查看文末提供的源码。

3.2 文件编码

原源码文件使用的是 GBK 编码,需要转换为 UTF-8 编码。将下面的命令保存到 convert.sh 文件中并用 chmod u+x convert.sh 赋予可执行权限。

#!/bin/bash

for i in "$@"; do
    desc=$(file "$i")
    if $(echo $desc | grep -i "UTF-8 Unicode" > /dev/null); then
        if $(echo $desc | grep -i "(with BOM)" > /dev/null); then
            echo "Remove UTF-8 BOM: " $i
            sed -i "1s/^xefxbbxbf//" "$i"
        fi
    elif $(echo $desc | grep -i "ISO-8859" > /dev/null); then
        echo     "GBK --> UTF-8   : " $i
        temp=temp.txt
        iconv -f gbk -t utf-8 -o "$temp" "$i"
        mv "$temp" "$i"
    fi
done

在源码根目录下运行 find . -type f ( -name "*.h" -o -name "*.cpp" ) | xargs -I{} ./convert.sh "{}" 将所有的文件的编码从 GBK 转为 UTF-8,并去除现有 UTF-8 文件的 BOM 头。

四、代码修改

到这里已经可以用 Qt Creator 打开项目了,但在代码中还存在一些问题,一方面是原代码使用了一些 Windows 平台特有的 API,一方面是有些代码在 Linux 有兼容性问题。先去除 Windows 特有的依赖到编译通过,再补充必要的依赖,最后解决兼容性问题。

4.1 修改报错直至编译通过

直接进行编译,逐步解决编译错误,通过下面的方式可以解决编译错误:

  • 删除 Utils.cpp 中报错的头文件、GUID 宏、listDevices 函数的主体、UTF8_To_string 和 string_To_UTF8 函数。
  • 将所有包含的 qDebug 改为 QDebug
  • Sleep(milli) 改为 std::this_thread::sleep_for(std::chrono::milliseconds(milli))
  • 删除 MSVC 的链接库的编译指令 #pragma comment ...
  • 将原来使用 OpenCV 2 的接口迁移到目前的 OpenCV 3。
    • IplImage 到 cv::Mat 的转换由 cv::Mat mat(ipl, false) 改成 cv::Mat mat = cv::cvarrToMat(ipl)
    • cv::Mat 到 IplImage 的转换由 IplImage(mat) 改成 cvIplImage(mat),在原来的代码里 cv::Mat 转为 IplImage 后有个取地址,对右值取地址是不安全的,需要用一个变量保存转换后的值再对这个变量取地址。
    • 在调用 cvRectangle 时将 CV_RGB 改成 cvScalar
    • 使用 cv::cvtColor 需要额外包含头文件 opencv2/imgproc.hpp
    • 使用 cv::VideoCapture 需要额外包含头文件 opencv2/videoio.hpp
  • strcpy_s 改成 strncpy,仅有参数位置上的改变。
  • TRUE 改为 true,将 FALSE 改为 false

改了编译错误后,忽略警告已经可以编译通过了,接下来是补充刚才删除的一些必要依赖及解决兼容性问题。

因为环境差异,可能出现错误的顺序不一致,但基本上是上面提到的错误之一。

4.2 重新实现获取摄像头列表的函数

原 Windows Demo 使用了 Windows 特有的 dshow 来查找摄像头,在这里直接用 cv::VideoCapture 尝试打开来获取摄像头的索引:

auto list = std::vector<int>();
for (auto i = 0; i != 10; ++i)
{
    auto cap = cv::VideoCapture(i);
    if (cap.isOpened()) { list.emplace_back(i); }
    cap.release();
}

Demo 可以只打开一个RGB摄像头,也可以同时打开一个RGB摄像头和一个IR摄像头。原代码保存获取摄像头的名称,仅用来统计数量,具体打开哪个摄像头是通过settings.ini文件来配置的。在改变探测摄像头存在的数量的方式后,顺带改变了打开摄像头的逻辑,仅一个摄像头就认为是仅打开普通摄像头。在settings.ini文件中配置两种摄像头的索引,如果索引为 -1,则自动把小的索引认为是普通摄像头,大的索引认为是红外摄像头,如果和真实情况不一致可手动指定摄像头索引。

settings.ini文件在后面运行 Demo 时会有更多的说明。

4.3 修复弹出文件选择框失败的兼容性问题

在 Ubuntu 20.04 下,Qt 的 QFileDialog::getOpenFileName 和 QFileDialog::getExistingDirectory 存在一些问题,在打开时会卡死界面,通过将最后一个参数设置为 QFileDialog::DontUseNativeDialog 可以解决这个问题。

五、运行 Demo

5.1 界面预览

虹软人脸识别——官方 Qt Demo 移植到 Linux第2张

5.2 配置

  1. 配置文件已经随源码打包好了,在运行时需要移动到可执行程序所在的同级目录下。
  2. 在配置文件中填入官网获取的 APP_ID、SDK_KEY 和 ACTIVE_KEY。
  3. 编译并运行。

六、源码下载

基于官方windows Qt Demo修改后的源码

免责声明:文章转载自《虹软人脸识别——官方 Qt Demo 移植到 Linux》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Proxy详解pytorch中nn.RNN()总结下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Linux操作系统的curl命令的基本使用

Linux操作系统的curl命令的基本使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任。 一.curl工具概述   curl是基于URL语法在命令行方式下工作的文件传输工具,它支持FTP,FTPS,HTTP,HTTPS,GOPHER,TELNET,DICT,FILE及LDAP等协议;curl支持HTTPS认证,并且支持HTTP的POS...

GCC编译器原理(一)------交叉编译器制作和GCC组件及命令

1.1 交叉编译器制作 默认安装的 GCC 编译系统所产生的代码适用于本机,即运行 GCC 的机器,但也可将 GCC 安装成能够生成其他的机器代码。安装一些必须的模块,就可产生多种目标机器代码,而且可通过命令行选择一种希望使用的代码。 1.1.1 目标机 从网站 http://gcc.gnu.org/install/specific.html 可以得到有可...

Linux 之不同运维人员共用root 账户权限审计

一、为什么?   在中小型企业,公司不同运维人员基本都是以root 账户进行服务器的登陆管理,缺少了账户权限审计制度。不出问题还好,出了问题,就很难找出源头。   这里介绍下,如何利用编译bash 使不同的客户端在使用root 登陆服务器使,记录各自的操作,并且可以在结合ELK 日志分析系统,来收集登陆操作日志 二、环境   服务器:centos 6.5...

linux 查询管道过滤,带上标题字段

linux查询过滤, 带上标题字段例: 一个简单的查询 ps -e | grep httpd 上面经过grep 过滤后, 标题没了, 但是为了看上去更方便,有标题字段看起来更方便一些, 那么可以按下面的写法来实现 命令: ps -e | head -1;ps -e | grep httpd 看一下效果吧: 说明: head -1 就是取第一行 其...

Linux清理磁盘空间

1、首先确定是否是磁盘满了 命令:   df -h 参数说明: -a:列出所有的文件系统,包括系统特有的/proc等文件系统 -k:以KB的容量显示各文件系统 -m:以MB的容量显示各文件系统 -h:以人们较易阅读的GB,MB,KB等格式自行显示 -H:以M=1000K替代M=1024K的进位方式 -T:连同该分区的文件系统名称(例如ext3)也列出 -i...

linux安装unzip及使用

安装完linux ,发现没有UNZIP,没办法,重新安装。 1、获取unzip源码 sudo wget http://downloads.sourceforge.net/infozip/unzip552.tar.gz 2、解压 tar zxvf unzip552.tar.gz 3、进入目录 cd unzip-5.52/ 4、将Makefile从unix子...