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

news2024/9/19 21:21:45

开始干

新建解决方案,新建动态库(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开发项目中使用它

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

上位机图像处理和嵌入式模块部署(f103 mcu和Qt上位机联动)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 之前我们写过一篇文章​​​​​​​,上面说的是如何利用串口对mcu进行控制,即如果利用串口实现mcu led灯的点亮和熄灭。输…

小程序迁移主体变更流程全攻略

小程序迁移变更主体有什么作用?有些小程序开发者,因为业务调整,或者公司更换,需要更换小程序主体!但是很多开发者对于小程序更换主体的操作流程并不熟悉,于是我们专门准备了这篇,关于小程序更换…

性能测试学习(一)

一、概念 1.性能测试:使用自动化工具,模拟不同场景,对软件各项性能指标进行测试和评估的过程 2.包括:a.后台处理程序的性能;b.应用服务器、数据库、架构设计是否存在瓶颈;c.服务器资源消耗(CPU、内存、磁…

ISCC——AI

得到一个T4.pyc 回编译一下 得到下面代码 import base64def encrypt_and_compare(user_input, offset_str, target_base64):if len(user_input) ! 24:return Please enter a string with a length of 24encrypted Nonefor i, char in enumerate(user_input):offset int(off…

二元关系表示

一、二元关系的定义和表示 什么是二元关系?对集合A和B,A\timesB的任意子集R为A到B的一个二元关系。当AB时,A\timesA的任一子集R称为A上的一个二元关系。在不引起误解的情况下,二元关系可简称关系。 若|A|m,|B|n,则A到…

浅谈网络安全态势感知

前言 网络空间环境日趋复杂,随着网络攻击种类和频次的增加,自建强有力的网络安全防御系统成为一个国家发展战略的一部分,而网络态势感知是实现网络安全主动防御的重要基础和前提。 什么是网络安全态势感知? 态势感知一词来源于对…

MySQL数据库中的多表查询/连接查询操作

类型:内连接 ,外连接{左外连接,右外连接} 之所以要使用连接查询的意义就是为了,借助数据库可以避免大量的数据重复。 进行连接查询的前提是要求多张表之间存在相关联的字段。 这里指的相关联的字段就是表与表之间存在着关系&am…

0元入驻抖音小店,真的是好事吗?

大家好,我是喷火龙。 抖音小店去年推出0元入驻抖音小店个人店的政策,简而言之就是只要一张身份证就可以开店,不需要营业执照,也不需要交保证金。 很多人一听很心动,因为没有任何成本就可以开店,于是纷纷跑…

二叉树的遍历(前序遍历,中序遍历,后序,层序遍历)和一些简单操作(由浅入深绝对能看懂)

欢迎大佬们的关顾能给个赞就更好啦QWQ 目录 二叉树的逻辑结构与物理结构 一.二叉树的遍历 (1)二叉树的前序遍历 (2)二叉树的中序遍历 (3)二叉树的后序遍历 (4)二叉树的层序遍历…

在PyCharm中import包标红

在程序头引入包,有时会出现标红 像上面的引入,在没有解决之前 sklearn.metrics 等都是标红的。因为缺少一些包,所以引入不了包中的一些函数 可以在左侧找到终端用命令安装包,用镜像可以加快下载速度 pip install 包名 -i https…

借助Kong记录接口的请求和响应内容

和APISIX类似,Kong也是一个Api GateWay。 运行在调用Api之前,以插件的扩展方式为Api提供管理, 如 鉴权、限流、监控、健康检查等. Kong是基于Lua语言、Nginx以及OpenResty开发的,拥有动态路由、负载均衡、高可用、高性能、熔断(基…

基于STM32+NBIOT(BC26)设计的物联网观赏鱼缸

文章目录 一、前言1.1 项目介绍【1】开发背景【2】项目实现的功能【3】项目模块组成 1.2 设计思路 二、(硬件控制端)硬件选型2.1 STM32开发板2.2 PCB板2.3 USB下载线2.4 NBIOT模块2.5 杜邦线(2排)2.6 稳压模块2.7 电源插头2.8 水温检测传感器2.9 水质检测…

20232801 2023-2024-2 《网络攻防实践》实践十一报告

#20232801 2023-2024-2 《网络攻防实践》实践十一报告 1.实践内容 (1)web浏览器渗透攻击 使用攻击机和Windows靶机进行浏览器渗透攻击实验,体验网页木马构造及实施浏览器攻击的实际过程。 (2)取证分析实践—网页木马…

WIFI国家码设置的影响

记录下工作中关于国家码设置对WIFI的影响,以SKYLAB的SKW99和SDZ202模组为例进行说明。对应到日常,就是我们经常提及手机是“美版”“港版”等,它们的wifi国家码是不同的,各版本在wifi使用中遇到的各种情况与下面所述是吻合的。 现…

【二叉树】力扣OJ题

文章目录 前言1. 翻转二叉树1.1 题目1.2 解题思路1.3 代码实现1.4 时空复杂度 2. 对称二叉树2.1 题目2.2 解题思路2.3 代码实现2.4 时空复杂度 3. 平衡二叉树3.1 题目3.2 解题思路3.3 代码实现3.4 时空复杂度 结语 前言 本篇博客主要介绍二叉树的经典 OJ 题,题目主…

Scala 入门介绍和环境搭建

一、简介 Scala 是一门以 Java 虚拟机(JVM)为运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言 (静态语言需要提前编译,如:Java、c、c 等,动态语言如:js)Scala 是一门多范式的编程…

Spring中@Component注解

Component注解 在Spring框架中,Component是一个通用的注解,用于标识一个类作为Spring容器管理的组件。当Spring扫描到被Component注解的类时,会自动创建一个该类的实例并将其纳入Spring容器中管理。 使用方式 1、基本用法: Co…

MySQL:表的约束

文章目录 0.小知识,数据转化1.空属性(非空约束)2.默认值(default)3.comment(列描述)4.zerofill(显示约束)5.primary key(主键约束)6.auto_increment(自增长)7.unique(唯一键)8.foreign key (外键)9.综合表结构的设计 表…

【运维】Linux 端口管理实用指南,扫描端口占用

在 Linux 系统中,你可以使用以下几种方法来查看当前被占用的端口,并检查 7860 到 7870 之间的端口: 推荐命令: sudo lsof -i :7860-7870方法一:使用 netstat 命令 sudo netstat -tuln | grep :78[6-7][0-9]这个命令…

Java+Spring Boot +MySQL + MyBatis Plus一款数字化管理平台源码:云MES系统

JavaSpring Boot MySQL MyBatis Plus一款数字化管理平台源码:云MES系统 MES是为企业提供制造全过程的信息化产品,支持企业智能制造。MES可实现与企业的ERP、PDM等其他信息化系统进行无缝连接,也可与现场生产设备进行连接、数据采集&#xff…