[Artoolkit] Android Sample of nftSimple
结合:[Artoolkit] ARToolKit's SDK Structure on Android
重难点:aRBaseLib/, nftSimple/, libcpufeatures.a
- aRBaseLib/
如果摄像头控制只能在android层操作,那么ARBaseLib中的摄像头控制部分就是重点之一。
unsw@unsw-UX303UB$ _cmd-wc-java
./AndroidUtils.java
./NativeInterface.java
./ARToolKit.java
./camera/CaptureCameraPreview.java
./camera/CameraPreferencesActivity.java
./camera/CameraWrapper.java
./camera/CameraEventListener.java
./rendering/gles20/ARRendererGLES20.java
./rendering/gles20/LineGLES20.java
./rendering/gles20/BaseFragmentShader.java
./rendering/gles20/ShaderProgram.java
./rendering/gles20/BaseShaderProgram.java
./rendering/gles20/CubeGLES20.java
./rendering/gles20/OpenGLShader.java
./rendering/gles20/ARDrawableOpenGLES20.java
./rendering/gles20/BaseVertexShader.java
./rendering/Cube.java
./rendering/ARRenderer.java
./rendering/RenderUtils.java
./rendering/Line.java
./assets/AssetFileTransferException.java
./assets/HashComputationException.java
./assets/AssetFileTransfer.java
./assets/Hasher.java
./assets/AssetHelper.java
./FPSCounter.java
./ARActivity.java
total
unsw@unsw-UX303UB$
4000行代码,从摄像头控制开始。(Replaced with opencv4android)
01. rendering.ARActivity是main(),其中:
CameraEventListener接口可替换为opencv4android提供的CameraBridgeViewBase.CvCameraViewListener2接口。
02. 处理每一帧
@Override
public void cameraPreviewFrame(byte[] frame) { if (firstUpdate) {
// ARToolKit has been initialised. The renderer can now add markers, etc...
if (renderer.configureARScene()) {
Log.i(TAG, "Scene configured successfully");
} else {
// Error
Log.e(TAG, "Error configuring scene. Cannot continue.");
finish();
}
firstUpdate = false;
} if (ARToolKit.getInstance().convertAndDetect(frame)) { // Update the renderer as the frame has changed
if (glView != null) glView.requestRender(); onFrameProcessed();
} }
03. ARToolKit处理帧,然后调用native(NDK)
public boolean convertAndDetect(byte[] frame) { if (!initedNative) return false;
if (frame == null) return false; if (!NativeInterface.arwAcceptVideoImage(frame, frameWidth, frameHeight, cameraIndex, cameraIsFrontFacing)) return false;
if (!NativeInterface.arwCapture()) return false;
return NativeInterface.arwUpdateAR();
}
libARWrapper.so的native代码在哪里?
nftSimple没有使用Wrapper技术,而是直接调用native: "AR and Rendering Code in Native C/C++ Using Android NDK"
怎么感觉 aRBaseLib 没有大用 ?
@Override
public void onPreviewFrame(byte[] data, Camera cam) { nftSimpleActivity.nativeVideoFrame(data);
cam.addCallbackBuffer(data);
}
04. 一帧的处理
JNIEXPORT void JNICALL JNIFUNCTION_NATIVE(nativeVideoFrame(JNIEnv* env, jobject obj, jbyteArray pinArray))
{
int i, j, k;
jbyte* inArray; if (!videoInited) {
#ifdef DEBUG
LOGD("nativeVideoFrame !VIDEO\n");
#endif
return; // No point in trying to track until video is inited.
}
if (!nftDataLoaded) {
if (!nftDataLoadingThreadHandle || threadGetStatus(nftDataLoadingThreadHandle) < ) {
#ifdef DEBUG
LOGD("nativeVideoFrame !NFTDATA\n");
#endif
return;
} else {
nftDataLoaded = true;
threadWaitQuit(nftDataLoadingThreadHandle);
threadFree(&nftDataLoadingThreadHandle); // Clean up.
}
}
if (!gARViewInited) {
return; // Also, we won't track until the ARView has been inited.
#ifdef DEBUG
LOGD("nativeVideoFrame !ARVIEW\n");
#endif
}
#ifdef DEBUG
LOGD("nativeVideoFrame\n");
#endif // Copy the incoming YUV420 image in pinArray.
env->GetByteArrayRegion(pinArray, , gVideoFrameSize, (jbyte *)gVideoFrame); // As of ARToolKit v5.0, NV21 format video frames are handled natively,
// and no longer require colour conversion to RGBA.
// If you still require RGBA format information from the video,
// here is where you'd do the conversion:
// color_convert_common(gVideoFrame, gVideoFrame + videoWidth*videoHeight, videoWidth, videoHeight, myRGBABuffer); videoFrameNeedsPixelBufferDataUpload = true; // Note that buffer needs uploading. (Upload must be done on OpenGL context's thread.) // Run marker detection on frame
if (trackingThreadHandle) {
// Perform NFT tracking.
float err;
int ret;
int pageNo;
// 又到了熟悉的地方:)
if( detectedPage == - ) {
trackingInitStart( trackingThreadHandle, gVideoFrame );
detectedPage = -;
}
if( detectedPage == - ) {
ret = trackingInitGetResult( trackingThreadHandle, trackingTrans, &pageNo);
if( ret == ) {
if (pageNo >= && pageNo < surfaceSetCount) {
#ifdef DEBUG
LOGE("Detected page %d.\n", pageNo);
#endif
detectedPage = pageNo;
ar2SetInitTrans(surfaceSet[detectedPage], trackingTrans);
} else {
LOGE("Detected bad page %d.\n", pageNo);
detectedPage = -;
}
} else if( ret < ) {
#ifdef DEBUG
LOGE("No page detected.\n");
#endif
detectedPage = -;
}
}
if( detectedPage >= && detectedPage < surfaceSetCount) {
if( ar2Tracking(ar2Handle, surfaceSet[detectedPage], gVideoFrame, trackingTrans, &err) < ) {
#ifdef DEBUG
LOGE("Tracking lost.\n");
#endif
detectedPage = -;
} else {
#ifdef DEBUG
LOGE("Tracked page %d (max %d).\n", detectedPage, surfaceSetCount - );
#endif
}
}
} else {
LOGE("Error: trackingThreadHandle\n");
detectedPage = -;
} // Update markers.
94 for (i = ; i < markersNFTCount; i++) {
markersNFT[i].validPrev = markersNFT[i].valid;
if (markersNFT[i].pageNo >= && markersNFT[i].pageNo == detectedPage) {
markersNFT[i].valid = TRUE;
for (j = ; j < ; j++) for (k = ; k < ; k++) markersNFT[i].trans[j][k] = trackingTrans[j][k];
}
else markersNFT[i].valid = FALSE;
if (markersNFT[i].valid) { // Filter the pose estimate.
if (markersNFT[i].ftmi) {
if (arFilterTransMat(markersNFT[i].ftmi, markersNFT[i].trans, !markersNFT[i].validPrev) < ) {
LOGE("arFilterTransMat error with marker %d.\n", i);
}
} if (!markersNFT[i].validPrev) {
// Marker has become visible, tell any dependent objects.
//ARMarkerAppearedNotification
} // We have a new pose, so set that.
arglCameraViewRHf(markersNFT[i].trans, markersNFT[i].pose.T, 1.0f /*VIEW_SCALEFACTOR*/);
// Tell any dependent objects about the update.
//ARMarkerUpdatedPoseNotification } else { if (markersNFT[i].validPrev) {
// Marker has ceased to be visible, tell any dependent objects.
//ARMarkerDisappearedNotification
}
}
127 }
}
由原来的 mainloop 变为了android preview 一帧来调用,其他native部分都相同。
- libcpufeatures.a
Link: https://developer.android.com/ndk/guides/cpu-features.html
Android 官方提供的读取cpu信息的一个库。我们这里主要对应于线程相关的部分。
Android Studio 2.2.3直接加载Android example出现的问题:
@PN1019, this is a tough nut. Let me try summarize and hopefully that'll help you. So there's two ways to get around this. Use the JDK that is embedded with Android Studio 2.2.+. Or, tell Android Studio to use the Oracle Corp JDK installed on your devbox but have it run in such a way to regress in compiling an older version of the Java language creating an older version of runtime Java classes. I recommend the former, please see my entry above now labeled with "Recommended JDK to use:". |
and Android Studio 2.1.1 is better.
unsw@unsw-UX303UB$ sudo update-alternatives --config javac
There are choices for the alternative javac (providing /usr/bin/javac). Selection Path Priority Status
------------------------------------------------------------
/usr/lib/jvm/java--oracle/bin/javac auto mode
* /usr/lib/jvm/java--oracle/bin/javac manual mode
/usr/lib/jvm/java--openjdk-amd64/bin/javac manual mode
/usr/lib/jvm/java--oracle/bin/javac manual mode Press enter to keep the current choice[*], or type selection number: unsw@unsw-UX303UB$ sudo update-alternatives --config java
There are choices for the alternative java (providing /usr/bin/java). Selection Path Priority Status
------------------------------------------------------------
/usr/lib/jvm/java--oracle/jre/bin/java auto mode
* /usr/lib/jvm/java--openjdk-amd64/jre/bin/java manual mode
/usr/lib/jvm/java--oracle/jre/bin/java manual mode
/usr/lib/jvm/java--openjdk-amd64/jre/bin/java manual mode
/usr/lib/jvm/java--oracle/jre/bin/java manual mode Press enter to keep the current choice[*], or type selection number: unsw@unsw-UX303UB$ javac -version
javac 1.7.0_80 unsw@unsw-UX303UB$ java -version
java version "1.7.0_121"
OpenJDK Runtime Environment (IcedTea 2.6.) (7u121-2.6.-1ubuntu0.14.04.)
OpenJDK -Bit Server VM (build 24.121-b00, mixed mode)
ubuntu14.14, jdk 1.7.x
Next: how to implement multi-nft,start with linux verison.
[Artoolkit] Android Sample of nftSimple的更多相关文章
- [Artoolkit] Framework Analysis of nftSimple
What is nftSimple? Loads NFT dataset names from a configuration file. The example uses the “Pinball. ...
- opencv for android sample导入有误
我们下载好opencv for android 后导入eclipse的时候发现人脸检测还有一个sample项目会有小叉,但是好像没有文件有问题.这时我们该怎么办呢? 在window中: 我们右键选择p ...
- Android sample 之模拟重力感应,加速度
class SimulationView extends View implements SensorEventListener { // diameter of the balls in meter ...
- [Artoolkit] kpmMatching & Tracking of nftSimple
1. kpmMatching thread main() --> loadNFTData() --> trackingInitInit() --> In static void *t ...
- xe5 android sample 中的 SimpleList 是怎样绑定的
C:\Users\Public\Documents\RAD Studio\12.0\Samples\FireMonkeyMobile 例子中的绑定方式如下图: 1.拖拽一个listview到界面上,然 ...
- delphi xe5 android sample 中的 SimpleList 是怎样绑定的
C:\Users\Public\Documents\RAD Studio\12.0\Samples\FireMonkeyMobile 例子中的绑定方式如下图: 1.拖拽一个listview到界面上,然 ...
- delphi xe5 android sample
安装xe5以后demo存放的路径在 C:\users\Public\Documents\RAD Studio\12.0\Samples 另外易博龙在sourceforget上也有 svn地址为:sv ...
- 虹软人脸识别Android Sample Code
AFR_FSDKInterface engine = new AFR_FSDKEngine(); //用来存放提取到的人脸信息, face_1 是注册的人脸,face_2 是要识别的人脸 AFR_FS ...
- xe5 android sample 中的 SimpleList 是怎样绑定的 [转]
C:\Users\Public\Documents\RAD Studio\12.0\Samples\FireMonkeyMobile 例子中的绑定方式如下图: 1.拖拽一个listview到界面上,然 ...
随机推荐
- U3D面试题
直接上新.... 什么是协同程序?答:在主线程运行时同时开启另一段逻辑处理,来协助当前程序的执行.换句话说,开启协程就是开启一个可以与程序并行的逻辑.可以用来控制运动.序列以及对象的行为. Unity ...
- oracle case when 用法
原文:http://www.cnblogs.com/eshizhan/archive/2012/04/06/2435493.html 1. CASE WHEN 表达式有两种形式 --简单Case函数 ...
- CentOS 7下简单的Ansible使用入门
1.配置hosts文件,Ansible依赖hosts文件进行主机通讯,不能直接在命令行上直接输入IP. vi /etc/ansible/hosts hosts文件格式如下: [servers] hos ...
- C#编程(七十九)---------- 反射
反射 在介绍翻着之前,先说两个小案例 B超:什么叫B超呢?就是透过肚皮能看到你内脏的情况,不用打开肚子才能看.这是什么样的一种技术呢?B超是B型超声波,它可以透过肚皮通过向你体内发射B型超声波,当超声 ...
- 使用BFG移除git库中的大文件或污点提交
- [Python设计模式] 第10章 怎么出试卷?——模版方法模式
github地址:https://github.com/cheesezh/python_design_patterns 题目 小时候数学老师的随堂测验,都是老师在黑板上写题目,学生在下边抄,然后再做题 ...
- ROS actionlib学习(二)
在ROS actionlib学习(一)中的例子展示了actionlib最基本的用法,下面我们看一个稍微实际一点的例子,用actionlib计算斐波那契数列,并发布反馈(feedback)和结果(res ...
- 编写SHELL脚本--编写简单脚本
1.简单脚本文件hello.sh,内容如下 #!/bin/bash pwd ls -al 执行脚本:bash hello.sh 或者使用root命令: ./hello.sh 2.接受用户参数 $0 ...
- unity, 在image effect shader中用_CameraDepthTexture重建世界坐标
--------------更新 更简单的方法: //depth: raw depth, nonlinear, 0 at near plane, 1 at far plan float4 scre ...
- 我对android开发的一点小感悟小看法
“Android”,“Android开发”等等这些词成了时下最热的词,也是时下大众最关注最吸引人眼球的话题,当然,最热门的行业也意味着高薪,好的就业环境,但同时也意味着强大的竞争力! Android系 ...