在Android平台上使用Ceres求解器,官方教程不明确,且编译过程遇到了很多问题。

环境

Ubuntu 18.04

源代码

https://github.com/Great-Keith/ceres-android

准备工作

Eigen 3.3.7(最新):在编译Ceres的时候需要使用。

NDK r20(最新):NDK r14b版本无法使用,建议使用高于14的版本。

Ceres 1.14.0(最新)已经附带在仓库中。

[NOTE] Ceres其他依赖项按照官方教程进行配置,建议先检验Linux系统下是否能够安装成功。

# 官方安装指导 http://ceres-solver.org/installation.html

# CMake
sudo apt-get install cmake
# google-glog + gflags
sudo apt-get install libgoogle-glog-dev
# BLAS & LAPACK
sudo apt-get install libatlas-base-dev
# Eigen3
sudo apt-get install libeigen3-dev
# SuiteSparse and CXSparse (optional)
# - If you want to build Ceres as a *static* library (the default)
# you can use the SuiteSparse package in the main Ubuntu package
# repository:
sudo apt-get install libsuitesparse-dev
# - However, if you want to build Ceres as a *shared* library, you must
# add the following PPA:
sudo add-apt-repository ppa:bzindovic/suitesparse-bugfix-1319687
sudo apt-get update
sudo apt-get install libsuitesparse-dev mkdir ceres-bin
cd ceres-bin
cmake ../ceres-solver-1.14.0
make -j3
make test
# Optionally install Ceres, it can also be exported using CMake which
# allows Ceres to be used without requiring installation, see the documentation
# for the EXPORT_BUILD_DIR option for more information.
make install

Android Studio 3.4.1:需要配置CMake, LLDB, ndk(在SDK Tools中点击安装)

官方Android指南

来源一:官方网站

原文

下载版本高于r9dAndroid NDK版本,在jni目录下使用ndk-build进行编译,你会得到libceres.a

解释

具体使用方法:

cd ceres-solver-1.14.0/jni
EIGEN_PATH=/path/to/eigen/header ndk-build

随后libceres.a便会出现在ceres-solver-1.14.0/obj/local/${ABI}目录下。

${ABI}的值通过修改Application.mk中的APP_ABI := arm64-v8a一行,可.以换armeabi-7va, x86_64等等。

至于动态库(*.so)的生成,根据网上的一些教程进行修改Android.mkApplication.mk,都无法正常编译,官方GitHub里的issue中对于这些报错,建议使用CMake进行编译。

[NOTE] 如果从GitHub上clone的版本是不带jni目录的,只能使用CMake进行编译。

来源二:代码内的文档

原文

编译需要使用NDK r15或者更高版本。

需要使用CMake寻找NDK当中的toolchain来替换本身的自带toolchain。假设你已经设置了变量$NDK_DIR,你可以使用如下命令编译:

cmake \
-DCMAKE_TOOLCHAIN_FILE=\
$NDK_DIR/build/cmake/android.toolchain.cmake \
-DEIGEN_INCLUDE_DIR=/path/to/eigen/header \
-DANDROID_ABI=armeabi-v7a \
-DANDROID_STL=c++_shared \
-DANDROID_NATIVE_API_LEVEL=android-24 \
-DBUILD_SHARED_LIBS=ON \
-DMINIGLOG=ON \
<PATH_TO_CERES_SOURCE>

你可以为各种安卓STL或ABI进行编译,但是最推荐使用c++_shared STL和armeabi-v7a(对于32位机)或arm64-v8a(对于64位机) ABI。许多API的版本都可以进行支持,但是推荐使用你安卓项目所支持的最高版本。

对于你的安卓项目和Ceres二进制文件,你需要使用相同的API版本和STL进行编译。

编译完成之后,你会得到一份libceres.so的库,你可以在编译的脚本中通过使用PREBUILT_SHARED_LIBRARY将它链接到你的安卓项目当中。

如果你正在编译Ceres的例子,想要验证你的库能否使,你需要将他们和libceres.so放在安卓设备上一个可执行的公共目录下(比如/data/local/tmp),并且确保NDK的STL也在同一个目录下。

需要注意的是,所有的求解器或者其他被你包含在项目中的共享依赖项,都需要出现在你安卓的编译配置和你的测试目录当中。

解释

最好采用CMake编译这种方法,后面解释如何修改这个命令。

编译命令

参考资料:https://github.com/qiu-yongheng/cerestest

根据官方材料和参考资料得出如下命令:

rm -rf CMake*

/path/to/sdk/cmake/[version]/bin/cmake \
-DCMAKE_TOOLCHAIN_FILE=/path/to/sdk/ndk-bundle/build/cmake/android.toolchain.cmake \
-DEIGEN_INCLUDE_DIR=/path/to/eigen/header \
-DANDROID_ABI=[ABI]] \
-DANDROID_STL=[c++_shared | c++_static] \
-DANDROID_NATIVE_API_LEVEL=android-24 \
-DBUILD_SHARED_LIBS=ON \
-DMINIGLOG=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_FLAGS="-s" \
-DCMAKE_C_FLAGS=-std=c99 -Os -fvisibility=hidden \
/path/to/ceres make clean
make
make install

执行如上命令后,首先会遇到如下错误:undefined reference to '__android_log_write'

解决方法:打开[ceres]/internal/ceres/minglog/glog/logging.h,搜索__android_log_write,将带有这个函数的几行注释掉。

重新编译,最后会报错误:'libc++_shared.so' no found

解决方法:这个错误无关紧要,可以看到当前目录下的lib目录已经生成了我们想要的库文件。从ndk-bundle中复制我们所需要的该文件到安卓项目中即可,该文件目录可能是ndk-bundle/sources/cxx-stl/llvm-libc++/libs/[ABI]。无需继续进行编译。

[NOTE] /path/to/eigen/header这个地址,不能使用安装eigen时候放置到的比如/usr/include地址,否则编译的时候会出现冲突,应该直接使用下载解压后的位置。

[NOTE] 每次cmake后,重新编译需要提前先删除当前目录下的CMakeFiles, CMakeCache等中间文件,否则CMake的配置不会发生改变。

测试结果

Android平台使用Ceres Solver的更多相关文章

  1. Ceres Solver for android

        最近开发中,需要对图片做一些处理与线性技术,这时就用到了Ceres Solver.如何把Ceres Solver集成到Android里呢? 官网给了一个解决方案,简洁明了:   Downloa ...

  2. [译]:Xamarin.Android平台功能——位置服务

    返回索引目录 原文链接:Location Services. 译文链接:Xamarin.Android平台功能--位置服务 本部分介绍位置服务以及与如何使用位置提供商服务 Location Servi ...

  3. Cocos2d-x 3.2 学习笔记(四)学习打包Android平台APK!

    从cocos2dx 3.2项目打包成apk安卓应用文件,搭建安卓环境的步骤有点繁琐,但搭建一次之后,以后就会非常快捷! (涉及到3.1.1版本的,请自动对应3.2版本,3.x版本的环境搭建都是一样的) ...

  4. (转)android平台phonegap框架实现原理

    (原文)http://blog.csdn.net/wuruixn/article/details/7405175 android平台phonegap框架实现原理 分类: Android2012-03- ...

  5. Android平台免Root无侵入AOP框架Dexposed使用详解

    Dexposed是基于久负盛名的开源Xposed框架实现的一个Android平台上功能强大的无侵入式运行时AOP框架. Dexposed的AOP实现是完全非侵入式的,没有使用任何注解处理器,编织器或者 ...

  6. Cocos2dx-3.0版本 从开发环境搭建(Win32)到项目移植Android平台过程详解

    作为重量级的跨平台开发的游戏引擎,Cocos2d-x在现今的手游开发领域占有重要地位.那么问题来了,作为Cocos2dx的学习者,它的可移植特性我们就需要掌握,要不然总觉得少一门技能.然而这个时候各种 ...

  7. 基于android平台的斗地主AI

    本软件是基于android平台的斗地主AI,我们在源代码的基础之上,旨在改进AI的算法,使玩家具有更丰富的体验感,让NPC可以更为智能. (一)玩法解析: (1)发牌和叫牌:一副扑克54张,先为每个人 ...

  8. 4412开发板Android教程——Android平台简介

    本文转自迅为开发板论坛:http://www.topeetboard.com Android和IOS Android的历史 Android公司 2005年Google收购成立22个月的Android公 ...

  9. Android平台的开发环境的发展演变

    因为之前学习java语言的时候安装过了eclipse,所以想在eclipse上搭建android平台,在参照知乎上大神们的意见,发现了AS强大的代码提示.实时预览和搜索匹配等出色功能,最后还是选择在A ...

随机推荐

  1. Python 爬虫从入门到进阶之路(十二)

    之前的文章我们介绍了 re 模块和 lxml 模块来做爬虫,本章我们再来看一个 bs4 模块来做爬虫. 和 lxml 一样,Beautiful Soup 也是一个HTML/XML的解析器,主要的功能也 ...

  2. Hackbar再次更新后的破解思路 v2.2.6

    不得不说在日常测试和渗透测试中hackbar这一插件给我带来了很大的便利 Hackbar在2.1.3之后的版本就开始收费了虽说价格不是很贵,但我们还是本着学习研究的心态来看看怎么绕过收费验证. 谷歌: ...

  3. MYSQL Got error 28 from storage engine

    网络查找该异常信息,发现 Got error 28 from storage engine 查了一下,数据库文件所在的盘应该没事,应该是数据库用的临时目录空间不够 引用 磁盘临时空间不够导致. 解决办 ...

  4. python接口自动化(三十一)--html测试报告通过邮件发出去——下(详解)

    简介 本篇总结了 QQ (SSL)邮箱和 163(非SSL) 邮箱发送邮件,专治各种不行,总之看完这篇以后麻麻再也不用担心我的邮件收不到了.以下代码兼容 python2 和 python3,运行无异常 ...

  5. python无网安装psycopg2

    1. 问题描述 ​ python项目要获取greenplum数据库数据,gp底层是postgresql,需要使用python的第三方工具包psycopg2操作数据库,但是问题是服务器上没有网络,无法在 ...

  6. 零基础ASP.NET Core WebAPI团队协作开发

    零基础ASP.NET Core WebAPI团队协作开发 相信大家对“前后端分离”和“微服务”这两个词应该是耳熟能详了.网上也有很多介绍这方面的文章,写的都很好.我这里提这个是因为接下来我要分享的内容 ...

  7. Promise原理探究及实现

    前言 作为ES6处理异步操作的新规范,Promise一经出现就广受欢迎.面试中也是如此,当然此时对前端的要求就不仅仅局限会用这个阶段了.下面就一起看下Promise相关的内容. Promise用法及实 ...

  8. BZOJ4152 The Captain(dijkstra+巧妙建图)

    BZOJ4152 The Captain 题面很简洁: 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. 很明显 ...

  9. py+selenium遇见IE,元素只有name属性【神奇解决】

    问题:当需要自动化测试某系统,而该系统只兼容IE8,怎么办? IE8的问题:IE8不支持getElementByName,而属性中又没有ID,定位难度较大. IE8以下不兼容getElementByN ...

  10. [Spring-Cloud-Alibaba] Sentinel 整合RestTemplate & Feign

    Sentinel API Github : WIKI Sphu (指明要保护的资源名称) Tracer (指明调用来源,异常统计接口) ContextUtil(标示进入调用链入口) 流控规则(针对来源 ...