跨平台之用VisualStudio开发APK嵌入OpenCV(二)

开始干

新建解决方案,新建动态库(Android)项目

功能随便选一个吧,就模仿PS(Photoshop)的透视裁切功能,一个物体(比如扑克牌)透视图,选4个顶点,转换为平面正视图,毕竟Xamarin很难实现这一类的功能(当然它最大的意义是让Android能够运行C#编写的代码)

下图来源网络

Visual Studio 2019的安装应该都会了吧

运行

然后过滤选择“所有语言”、“所有平台”、“其它”,选择空白解决方案(你可以直接新建项目,我不喜欢一串文件夹都是一个名称,辨识度太低)

我就默认Solution1了,位置我直接放桌面

然后桌面应该创建了这样子的文件夹

新建一个项目

过滤“C++”、“所有平台”、“移动”,选择“共享动态库(Android)”

名称就设为“PerspectiveTransformer”

还记得上文说到,你想要的吗,OpenCV已经编译好的静态库在这里

注意libs文件夹是给Java用的,也就是折腾Android Studio的那帮人,严格说那才是Android正统的开发环境(如果你刚开始学,现在折腾Java也不迟,它跟C#很像,或者应该说C#是跟大多数语言都很像),而静态库又分成几个这个

关于ABI(安卓二进制接口,你可以理解为CPU不一样)还有ARM RISC、x86 CISC指令集以后有空随缘更新再说吧(自认为老手的程序员骂骂咧咧关闭了浏览器选项卡)

如果你折腾的是源码,你会发现OpenCV没有include所需的.h/.hpp文件

因为需要编译(makefile)以后才把那些文件集中起来(你又想骗我自己编译OpenCV)

上文说到OpenCV那帮人已经帮你编译好了,在这里

现在打开cpp文件自己定义这样一个函数

实现代码为:

void TransformFile(const char* src, float* src_xys, const char* dst, float* dst_size)
{
	static float default_xy[] = { 8, 190, 151, 56, 139, 249, 276, 103 };
	if (src_xys == nullptr) { src_xys = default_xy; }
	cv::Point2f src_marks[4] = {
		cv::Point2f(src_xys[0], src_xys[1]),
		cv::Point2f(src_xys[2], src_xys[3]),
		cv::Point2f(src_xys[4], src_xys[5]),
		cv::Point2f(src_xys[6], src_xys[7])
	};
	static float default_size[] = { 513, 328 };
	if (dst_size == nullptr) { dst_size = default_size; }
	cv::Size z(dst_size[0], dst_size[1]);
	cv::Point2f dst_marks[4] = {
		cv::Point2f(0, 0),
		cv::Point2f(z.width, 0),
		cv::Point2f(0, z.height),
		cv::Point2f(z.width, z.height)
	};
	auto m = cv::getPerspectiveTransform(src_marks, dst_marks);
	cv::Mat src1 = cv::imread(src);
	cv::Mat dst1;
	cv::warpPerspective(src1, dst1, m, z);
	cv::imwrite(dst, dst1);
}

作为入门文章,精简即是要诀,直接通过文件传递数据即可(搭配示例图片可以不需要坐标参数

函数功能是读取一个文件,根据提供的关键点截取、摆正、保存

你可以使用这样的硬编码包含opencv.hpp文件

也可以给项目添加include路径(就好像C++初恋一样)

点添加图标

选择上面提到的文件夹即可

打开或者编译,你就直到opencv.hpp包含了其它的hpp文件,但是没有使用相对路径,所以简易还是设置include目录,否则你就要修改很多hpp文件

设置好应该是

对于ARM64以及x86(常见是模拟器,以及双系统平板)等同样设置,此外还有Debug和Release模式(一个是调试版,一个是发行版)

因为OpenCV带有很多C++模板,里面有try-catch异常捕捉,所以要打开相关的参数

接下来是库设置,也是导入OpenCV编译好的静态库的关键

共有2个位置(不同平台不同,比如x86用的是x86文件夹

然后是依赖项,也就是静态库列表

所需的静态库列表为:

opencv_imgcodecs
opencv_imgproc
opencv_core
libwebp
ittnotify
tbb
tegra_hal
cpufeatures
libjpeg-turbo
libopenjp2
IlmImf
libtiff
libpng
z
m
stdc++

我建议还是尝试一次自己折腾的痛苦,那样你的进步会很快(怎么说呢,玄学)

cv::initInterTab2D(int, bool): error: undefined reference to 'sincos'	加一行 m 使用数学库(导入静态库不包含 前缀 lib 和 扩展名 .a否则只能硬编码全路径)

error: undefined reference to '__cxa_guard_acquire'	加一行stdc++

libopencv_imgcodecs.a ... error: undefined reference to 'cv::resize	opencv_imgcodecs 放在 opencv_imgproc 前面(被依赖的库放后面)

error: undefined reference to 'cv::utils::trace::details::Region	添加 opencv_core

libopencv_imgcodecs.a ... error: undefined reference to 'opj_image_destroy'	添加 3rdparty\libs\armeabi-v7a 目录,引用 liblibopenjp2.a

libopencv_imgcodecs.a ... error: undefined reference to 'Imf_opencv::Chromaticities::Chromaticities	引用 libIlmImf.a

libopencv_imgcodecs.a ... undefined reference to 'png_destroy_read_struct'	引用 liblibpng.a

error: undefined reference to 'TIFFSetErrorHandler'	引用 liblibtiff.a

error: undefined reference to 'WebPGetFeaturesInternal'	引用 liblibwebp.a

undefined reference to 'carotene_o4t::isSupportedConfiguration()'	引用 libtegra_hal.a 这个可能搞深度学习算法的才熟悉

undefined reference to 'tbb::interface7::internal::task_arena_base::internal_terminate()'	引用 libtbb.a

undefined reference to 'gzopen'	引用内置的 libz.a 即加一行 z

libopencv_core.a ... undefined reference to 'android_getCpuFeatures'		引用 libcpufeatures.a

undefined reference to '__itt_thread_set_name_ptr__3_0'	libittnotify.a

已启动生成…
1>------ 已启动生成: 项目: PerspectiveTransformer, 配置: Debug ARM ------
1>ANDROID_HOME=D:\\Microsoft\AndroidSDK\25
1>ANT_HOME=D:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Apps\apache-ant-1.9.3
1>JAVA_HOME=C:\Program Files\Android\jdk\microsoft_dist_openjdk_1.8.0.25
1>NDK_ROOT=D:\\Microsoft\AndroidNDK64\android-ndk-r16b
1>PerspectiveTransformer.vcxproj -> C:\Users\Administrator\Desktop\Solution1\ARM\Debug\libPerspectiveTransformer.so
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========

编译成功,就得到了libPerspectiveTransformer.so动态库

下一篇,外面在安卓的App开发项目中使用它

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/645456.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2000 年至 2015 年中国(即水稻、小麦和玉米1km 网格)三种主要作物年收获面积的时空变化

摘要 可靠、连续的主要作物收获面积信息对于研究地表动态和制定影响农业生产、土地利用和可持续发展的政策至关重要。然而,中国目前还没有高分辨率的空间明确和时间连续的作物收获面积信息。全国范围内主要农作物收获面积的时空格局也鲜有研究。在本研究中&#xf…

【深度学习】第1章

概论: 机器学习是对研究问题进行模型假设,利用计算机从训练数据中学习得到模型参数,并最终对数据进行预测和分析,其基础主要是归纳和统计。 深度学习是一种实现机器学习的技术,是机器学习重要的分支。其源于人工神经网络的研究。深度学习的模型结构是一种含多隐层的神经…

长安链使用Golang编写智能合约教程(一)

编写前的注意事项: 1、运行一条带有Doker_GoVM的链 2、建议直接用官方的在线IDE去写合约,因为写完可以直接测,缺点只是调试不方便。 3、自己拉环境在本地写合约,编译时注意编译环境,官方有提醒你去Linux下去编译。 …

【2024.5.26 软件设计师】记录第一次参加软考(附资料)

🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux 😘欢迎 ❤️关注 👍点赞 🙌收藏 ✍️留言 文章目录 前言考试分析选择题案例分析题话外 软考总结资料 前言 这是我第一次参加软考,其实我并…

到底该用英文括号还是中文括号?

这篇博客写的还挺详细的,不错。

如何使用多种算法解决LeetCode第135题——分发糖果问题

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容,和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣! 推荐:数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航: LeetCode解锁100…

美甲店会员预约系统管理小程序的作用是什么

女性爱美体现在方方面面,美丽好看的指甲也不能少,市场中美甲店、小摊不少,也跑出了不少连锁品牌,70后到00后,每个层级都有不少潜在客户,商家需要获取和完善转化路径,不断提高品牌影响力与自身内…

【图解IO与Netty系列】IO的同步与异步、阻塞与非阻塞,Linux五种IO模型

IO的同步与异步、阻塞与非阻塞,Linux五种IO模型 IO的同步与异步,阻塞与非阻塞阻塞IO与非阻塞IO同步IO与异步IO Linux五种IO模型BIONIOIO多路复用信号驱动IOAIO IO的同步与异步,阻塞与非阻塞 我们有时会看到类似于同步阻塞式IO、同步非阻塞式…

【二叉树算法题记录】236. 二叉树的最近公共祖先

题目链接 题目描述 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个…

STL---unordered set和unordered multiset【无序集合】

1.1 定义及初始化&#x1f357; 下面列出常用的初始化方式 #include <unordered_set> #include <iostream> using namespace std; //输出s中的所有元素 template<typename T> void Show(const T& s) {for (auto& x : s) …

操作系统实验四:多线程与信号量编程

操作系统实验上机 更多技术请访问&#xff1a;www.xuanworld.top 部分审核不通过的文章将发至个人博客&#xff1a;www.xuanworld.top 欢迎来52破解论坛阅读帖子&#xff1a;https://www.52pojie.cn/thread-1891208-1-1.html 实验名称实验序号实验日期实验人多线程与信号量…

信号量——多线程

信号量的本质就是一个计数器 在多线程访问临界资源的时候&#xff0c;如果临界资源中又有很多份分好的资源&#xff0c;那么就可以通过信号量来表示里面还有多少份资源&#xff0c;且每份资源只有一个线程可以访问 线程申请信号量成功&#xff0c;就一定有一份资源是你的&…

Golang并发编程-协程goroutine的信道(channel)

文章目录 前言一、信道的定义与使用信道的声明信道的使用 二、信道的容量与长度三、缓冲信道与无缓冲信道缓冲信道无缓冲信道 四、信道的初体验信道关闭的广播机制 总结 前言 Goroutine的开发&#xff0c;当遇到生产者消费者场景的时候&#xff0c;离不开 channel&#xff08;…

基于Matplotlib包实现可视化①——折线图绘制

Matplotlib 是一个用于创建静态、动画、 和交互式可视化的第三方库&#xff0c;也是我们在借助Python进行数据可视化时经常使用到的库&#xff0c;具有较强的可视化能力。 为让大家有一个更为直观的认识&#xff0c;这里我随机从其官方网页中摘取了几张图片。 按照惯例&#x…

【安装笔记-20240523-Windows-安装测试 ShareX】

安装笔记-系列文章目录 安装笔记-20240523-Windows-安装测试 ShareX 文章目录 安装笔记-系列文章目录安装笔记-20240523-Windows-安装测试 ShareX 前言一、软件介绍名称&#xff1a;ShareX主页官方介绍 二、安装步骤测试版本&#xff1a;16.1.0下载链接功能界面 三、应用场景屏…

2024年【危险化学品经营单位安全管理人员】考试及危险化学品经营单位安全管理人员考试资料

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品经营单位安全管理人员考试考前必练&#xff01;安全生产模拟考试一点通每个月更新危险化学品经营单位安全管理人员考试资料题目及答案&#xff01;多做几遍&#xff0c;其实通过危险化学品经营单位安全管理…

强化学习4:DQN 算法

看这篇文章之前&#xff0c;建议先了解一下&#xff1a;Q-Learning 算法。 1. 算法介绍 DQN 算法全称为 Deep Q-Network&#xff0c;即深度Q网络。它将 Q-Learning 与 Deep Learning 结合在了一起。 1.1 Q-Network Q-Learning 是使用 Q-table 才存储决策信息的&#xff0c;…

【Python001】python批量下载、插入与读取Oracle中图片数据(已更新)

1.熟悉、梳理、总结数据分析实战中的python、oracle研发知识体系 2.欢迎点赞、关注、批评、指正,互三走起来,小手动起来! 文章目录 1.背景说明2.环境搭建2.1 参考链接2.2 `oracle`查询测试代码3.数据请求与插入3.1 `Oracle`建表语句3.2 `Python`代码实现3.3 效果示例4.问题链…