文章目录
最终代码可以在我的github上找到
出发点
微信向OpenCV_contrib开源的模块wechat_qrcode放在了OpenCV4.5
以上的版本,而很多旧的代码用的都是OpenCV3
,迁移起来很麻烦,因此就想着能不能把这个模块单独拿出来编译使用
1. 编译OpenCV
和OpenCV_contrib
根据官网教程,手动编译OpenCV
和OpenCV_contrib
,这里我编译的版本是3.4.8
2. 下载wechat_qrcode
模块源码
在OpenCV_contrib
官网下载源码,选一个版本高一点的,比如4.8.1
,版本不限,只要包含wechat_qrcode
这个模块就可以了。下载完后解压。
3. 复制wechat_qrcode
模块源码
进入到解压后的opencv_contrib-4.8.1/modules
文件夹,将wechat_qrcode
这个文件夹复制一份
4. 修改CMakeLists.txt
,使其成为一个即插即用的模块
新建一个工程文件夹
文件结构如下
.
├── build
├── CMakeLists.txt
├── main.cpp
└── wechat_qrcode
├── CMakeLists.txt
├── include
├── LICENSE
├── model # 用来存放CNN模型的文件夹
├── perf
├── README.md
├── samples
├── src
└── test
其中
main.cpp
是主文件,在里面使用wechat_qrcode
的功能wechat_qrcode
就是上一节复制的文件夹,将其复制到这里
下载wechat_qrcode
所需的CNN模型
下载地址,并复制到 wechat_qrcode/model
文件夹里面
修改第一层级的CMakeLists.txt
cmake_minimum_required(VERSION 3.0.0)
project(wechat_qrcode VERSION 0.1.0 LANGUAGES C CXX)
set(OpenCV_DIR "/home/lyxichigoichie/3rdparty/opencv3/build") #directory of OpenCVConfig.cmake, the folder where you build opencv
find_package(OpenCV REQUIRED QUIET)
# message(${OpenCV_LIBS})
add_subdirectory(wechat_qrcode)
# include directories
include_directories(
wechat_qrcode/include
)
# message(${sourcelist})
add_executable(main main.cpp)
target_link_libraries(main ${OpenCV_LIBS} wechat_qrcode)
修改wechat_qrcode
文件夹内的CMakeLists.txt
见注释
# 指定OpenCV的搜索路径
set(OpenCV_DIR "/home/username/3rdparty/opencv3/build") #directory of OpenCVConfig.cmake, the folder where you build opencv
find_package(OpenCV REQUIRED QUIET) # 搜索OpenCV
# message(${OpenCV_LIBS})
# include directories
include_directories(
include
${OpenCV_INCLUDE_DIRS}
)
# link directories
link_directories(
include
${OpenCV_LIBRARY_DIRS}
)
file(GLOB_RECURSE sourcelist src/*.cpp) # 递归地查找出该文件夹下所有的cpp文件,见https://www.cnblogs.com/yongdaimi/p/14689417.html
# message(${sourcelist})
add_library(wechat_qrcode SHARED ${sourcelist})
target_link_libraries(wechat_qrcode ${OpenCV_LIBS})
上面做的事其实就是将这个模块里的所有源文件编译成一个动态库
add_library(wechat_qrcode SHARED
src/wechat_qrcode.cpp
src/imgsource.cpp
# ......剩余的cpp文件
)
这样,每次使用这个模块的时候只需要把wechat_qrcode
文件夹拷贝到工程目录下,然后再在第一层级的CMakeLists.txt
中添加subdirectory
即可
main.cpp
参考链接,需要修改里面的几个路径
modelDir
: 存放wechat_qrcode
所需的CNN模型的路径,建议使用绝对路径img = imread("/home/lyxichigoichie/Pictures/qrcode.png");
: 二维码路径
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace std;
using namespace cv;
#include <opencv2/wechat_qrcode.hpp>
int main()
{
const std::string modelDir = "/home/lyxichigoichie/3rdparty/opencv4.8.1/build/downloads/wechat_qrcode/";
// 构造(使用异常捕获构造函数是否正常)
wechat_qrcode::WeChatQRCode detector{
modelDir + "detect.prototxt",
modelDir + "detect.caffemodel",
modelDir + "sr.prototxt",
modelDir + "sr.caffemodel"
};
// 临时变量
Mat img;
vector<Mat> points; // qrcode: Retangle, not RotatedBox
// auto camIdx = 0;
img = imread("/home/lyxichigoichie/Pictures/qrcode.png");
// 检测
auto res = detector.detectAndDecode(img, points);
// 结果叠加
for(size_t idx = 0; idx < res.size(); idx ++){
Point pt1 = points[idx].at<Point2f>(0);
Point pt2 = points[idx].at<Point2f>(2);
Rect rect{pt1, pt2};
Point center = (pt1 + pt2) / 2;
// 绘制矩形框
rectangle(img, rect, {0,0,255}, 2);
circle(img, center, rect.height / 15, {0,0,255}, -1);
// 解码字符串
putText(img, res[idx], {pt1.x, pt2.y + 16}, 1, 1, {0,0,255});
}
imshow("image", img);
waitKey();
}
编译运行即可