跨平台之用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_corelibopencv_imgcodecs.a ... error: undefined reference to 'opj_image_destroy'	添加 3rdparty\libs\armeabi-v7a 目录,引用 liblibopenjp2.alibopencv_imgcodecs.a ... error: undefined reference to 'Imf_opencv::Chromaticities::Chromaticities	引用 libIlmImf.alibopencv_imgcodecs.a ... undefined reference to 'png_destroy_read_struct'	引用 liblibpng.aerror: undefined reference to 'TIFFSetErrorHandler'	引用 liblibtiff.aerror: undefined reference to 'WebPGetFeaturesInternal'	引用 liblibwebp.aundefined reference to 'carotene_o4t::isSupportedConfiguration()'	引用 libtegra_hal.a 这个可能搞深度学习算法的才熟悉undefined reference to 'tbb::interface7::internal::task_arena_base::internal_terminate()'	引用 libtbb.aundefined reference to 'gzopen'	引用内置的 libz.a 即加一行 zlibopencv_core.a ... undefined reference to 'android_getCpuFeatures'		引用 libcpufeatures.aundefined 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.mzph.cn/news/841374.shtml

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

相关文章

python文件处理之os模块和shutil模块

目录 1.os模块 os.path.exists(path):文件或者目录存在与否判断 os.path.isfile(path):判断是否是文件 os.path.isdir(path):判断是否是文件夹 os.remove(path):尝试删除文件 os.rmdir(path):尝试删除目录 os.m…

vue项目elementui刷新页面弹窗问题

bug:每次刷新页面都有这个鬼弹窗。 刚开始以为是自己的代码问题,于是我翻遍了每一行代码,硬是没找出问题。 后来在网上找了些资料,原来是引入的问题。 解决方案: 改一下引入方式即可。 错误姿势 import Vue from …

美发店服务预约会员小程序的作用是什么

美发店不同于美容美甲,男女都是必需且年龄层几乎不限,商家在市场拓展时只要方法得当相对比较容易,当今客户适应于线上信息获取、咨询及实际内容开展,商家也需要赋能和提升自身服务效率,合理化管理。 运用【雨科】平台…

2024年【高压电工】新版试题及高压电工找解析

题库来源:安全生产模拟考试一点通公众号小程序 高压电工新版试题是安全生产模拟考试一点通生成的,高压电工证模拟考试题库是根据高压电工最新版教材汇编出高压电工仿真模拟考试。2024年【高压电工】新版试题及高压电工找解析 1、【单选题】 110KV及以下…

文件批量重命名利器:一键轻松替换文本间内容,高效管理文件不再是难题!

在信息爆炸的时代,我们的电脑中堆积了无数的文件。这些文件可能包含重要的工作资料、珍贵的个人回忆或是各种学习资料。然而,随着文件的不断增多,如何高效地管理和查找这些文件成为了一个头疼的问题。 文件批量改名高手是一款专业的文件管理…

在IDEA中配置servlet(maven配置完成的基础下)

在IDEA中配置servlet&#xff08;maven配置完成的基础下&#xff09; 1.先新建一个项目 2.选择尾巴是webapp的&#xff0c;名称自定义 3.点击高级设置&#xff0c;修改组id 点击创建&#xff0c;等待jar包下载完成。在pom.xml中配置以下 <dependency><groupId>ja…

docker同步bilibili收藏视频到群晖,可配合emby

作者是amtoaer&#xff0c;在github项目地址&#xff1a;https://github.com/amtoaer/bili-sync 有两个版本&#xff0c;1.0和2.0&#xff0c;我使用的是2.0 PS2&#xff1a;2.0和1.0版本目录结构不兼容&#xff0c;所以部署后会全量重新下载视频。 演示&#xff1a; 依然是…

OpenH264 编解码器介绍

思科 思科系统&#xff08;英语&#xff1a;Cisco Systems, Inc.&#xff09;是一间跨国际综合技术企业&#xff0c;总部设于加州硅谷&#xff1b;思科开发、制作和售卖网络硬件、软件、通信设备等高科技产品及服务&#xff0c;并透过子公司&#xff08;例子有OpenDNS、Webex、…

国赛练习(1)

Unzip 软连接 软连接是linux中一个常用命令&#xff0c;它的功能是为某一个文件在另外一个位置建立一个同步的链接。换句话说&#xff0c;也可以理解成Windows中的快捷方式 注意&#xff1a;在创建软连接的文件的所有目录下不能有重名的文件 打开环境&#xff0c;是文件上传&am…

用实践结果告诉你为啥说 CloudFlare 是赛博菩萨?

最近几天明月都没有更新博客了,主要是接了几个 CloudFlare 代维配置的活儿,有需要加速优化的,有需要排除疑难故障的,有需要提高防御攻击能力的甚至还有纯粹为了体验“打不死”装逼需要的。总之,各种各样的需求,五花八门的,好在 CloudFlare 都能一一满足,最主要的是这些…

Dockerfile使用

1.Dockerfile是什么 官网地址 https://docs.docker.com/reference/dockerfile/概念 是什么 Dockerfile 是用于构建 Docker 镜像的文本文件&#xff0c;它包含一系列的指令&#xff08;instructions&#xff09;和参数&#xff0c;用于描述如何构建和配置镜像。 Dockerfile 是…

解析售后维修服务平台如何助力企业高效运营与决策

随着生活质量的不断提高&#xff0c;人们对于售后服务的要求也越来越多。因此&#xff0c;售后服务已经成为企业竞争力的重要组成部分。售后服务平台作为连接企业与消费者的桥梁&#xff0c;不仅关乎着消费者的满意度&#xff0c;而且直接影响着企业的品牌形象与市场地位。那么…

[7] CUDA之常量内存与纹理内存

CUDA之常量内存与纹理内存 1. 常量内存 NVIDIA GPU卡从逻辑上对用户提供了 64KB 的常量内存空间&#xff0c;可以用来存储内核执行期间所需要的恒定数据常量内存对一些特定情况下的小数据量的访问具有相比全局内存的额外优势&#xff0c;使用常量内存也一定程序上减少了对全局…

使用python对指定文件夹下的pdf文件进行合并

使用python对指定文件夹下的pdf文件进行合并 介绍效果代码 介绍 对指定文件夹下的所有pdf文件进行合并成一个pdf文件。 效果 要合并的pdf文件&#xff0c;共计16个1页的pdf文件。 合并成功的pdf文件&#xff1a;一个16页的pdf文件。 代码 import os from PyPDF2 import …

深入理解 Spring Web 应用程序初始化流程

前言 在构建基于 Spring 的 Web 应用程序时&#xff0c;了解初始化流程是至关重要的。本文将详细介绍 Servlet 容器的初始化过程&#xff0c;并重点探讨 Spring 框架在其中的作用&#xff0c;特别是 ServletContainerInitializer、SpringServletContainerInitializer 和 WebAp…

源码部署ELK

目录 资源列表 基础环境 关闭防护墙 关闭内核安全机制 修改主机名 添加hosts映射 一、部署elasticsearch 修改limit限制 部署elasticsearch 修改配置文件 单节点 集群(3台节点集群为例) 启动 二、部署logstash 部署logstash 添加配置文件 启动 三、部署kiban…

数据清洗操作及众所周知【数据分析】

各位大佬好 &#xff0c;这里是阿川的博客 &#xff0c; 祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 前面的博客 数据分析—技术栈和开发环境搭建 …

Vue3实战笔记(45)—VUE3封装一些echarts常用的组件,附源码

文章目录 前言一、柱状图框选二、折线图堆叠总结 前言 日前使用hooks的方式封装组件&#xff0c;在我使用复杂的图标时候遇到了些问题&#xff0c;预想在onMounted中初始化echarts&#xff0c;在使用hooks的时候&#xff0c;组件没有渲染完&#xff0c;使用实例会出现各种各样…

Qt Creator(1)【概述篇】

阅读导航 引言一、Qt概述1. 什么是Qt2. Qt的发展史3. Qt支持的平台4. Qt的优点5. Qt的应用场景 二、Qt下载安装 引言 在探索编程和软件开发的旅程中&#xff0c;我们已经奠定了坚实的基础&#xff0c;通过学习C语言和C&#xff0c;我们不仅掌握了结构化编程和面向对象编程的核…