基于一款开源应用 Rtabmap https://github.com/introlab/rtabmap
是基于 Google 的 Tango 手机使用的
通过摄像头和红外摄像头扫描立体空间,并实时显示在手机上,扫描后可保存所扫描的点云数据, .ply文件或.ob文件。
下图是扫描中截得图
3D Builder软件打开 .obj 文件是这样(和上图不是一个文件)
Android studio 打开 .obj 文件如下图
我这里只需要平面图 就是v顶点 其余的不需要
下面开始:
首先是读取.obj文件 文件在手机内
public void startRead(final String uri) {
mRootView.showLoading();
new Thread(new Runnable() {
@Override
public void run() {
KLog.e("start read");
long start = System.currentTimeMillis();
getObjXy(uri);
long end = System.currentTimeMillis();
KLog.e("用时:" + ((end - start) / 1000) + " s");
//画点
drawpoint();
}
}).start();
}
/**
* 读取 obj 的 xy点
*
* @param uri
*/
private void getObjXy(String uri) {
String fileStr = uri.replace("file://", "");
KLog.e(fileStr);
BufferedReader mBufferedReader = null;
try {
mBufferedReader = new BufferedReader(new FileReader(fileStr));
} catch (FileNotFoundException e) {
KLog.e(e);
e.printStackTrace();
}
String line;
String[] lineArr;
int j = 0;
try {
while ((line = mBufferedReader.readLine()) != null) {
lineArr = line.split(" ");
if (lineArr.length > 3 && lineArr[0].equals("v")) {
float x = Float.parseFloat(lineArr[1]);
float y = Float.parseFloat(lineArr[2]);
vX.add(x);
vY.add(y);
//获取最大最小的 x y 点
adjustMaxMin(x, y);
j++;
} else if (lineArr.length > 3 && lineArr[0].equals("vn") || lineArr.length > 3 && lineArr[0].equals("vt")) {
KLog.e("break");
break;
}
if (j % 100 == 0)
KLog.e(j);
}
} catch (IOException e) {
e.printStackTrace();
KLog.e(e);
}
}
private float maxX, maxY, minX, minY;
/**
* 拿到最大最小 x y
*
* @param x
* @param y
*/
protected void adjustMaxMin(float x, float y) {
if (x > maxX) {
maxX = x;
}
if (y > maxY) {
maxY = y;
}
if (x < minX) {
minX = x;
}
if (y < minY) {
minY = y;
}
}
现在所有点已经读到了(拿到了所有点的 x y的值) 开始画点
private float pxI = 100;//用户指定 像素
private float mI = 1;//用户指定 米
public static float width, height;//宽高
//obj文件中 的v xy点
private List<Float> vX = new ArrayList<>();
private List<Float> vY = new ArrayList<>();
private Paint paint;
/**
* 画点
*/
private void drawpoint() {
width = (maxX - minX) / mI * pxI;
height = (maxY - minY) / mI * pxI;
_bitmap = Bitmap.createBitmap((int) width, (int) height, Bitmap.Config.RGB_565);
mCanvas = new Canvas(_bitmap);
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);//设置空心
paint.setColor(colorP);
paint.setStrokeWidth(paintSize);
paint.setStrokeCap(Paint.Cap.ROUND);
//制定0点坐标
int x = 0;
int y = 0;
mCanvas.translate(x, y);
//画点
drawP(mCanvas, x, y);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
mRootView.setBitmap(_bitmap);
mRootView.hideLoading();
}
});
}
点的x y的值可能会不在手机屏幕上 比如 -1 等 所以需要考虑平移
private void drawP(Canvas canvas, int x, int y) {
//起始的偏移量 有负数的坐标存在
float xP = 0, yP = 0;
if ((minX / mI * pxI + x) < 0) {
xP = Math.abs(minX / mI * pxI + x);
}
if (minY / mI * pxI + y < 0) {
yP = minY / mI * pxI + y;
}
if (maxX / mI * pxI + x > width) {
xP = width - (maxX / mI * pxI + x);
}
if (maxY / mI * pxI + y > height) {
yP = maxY / mI * pxI + y - height;
}
for (int i = 0; i < vX.size(); i++) {
canvas.drawPoint((vX.get(i) / mI * pxI + x + xP), (vY.get(i) / mI * pxI + y - yP), paint);
}
}
最后效果图