背景:需要识别物体,并且测量物体的尺寸
思路:
识别物体
1、百度云,阿里云等有很多识别,如果有API识别,就用吧,比较容易,具体接入可以看官方文档
2、另外一种方式就是opencv分析了。这一点我也在研究,我现在识别的代码就不贴了。
物体尺寸测量
由于我们是根据图片识别物体,所以返回的是某一帧的图片上的像素点A(x1,y1)到B(x2,y2)。要转换成空间坐标系的点。再计算距离。这里我用的基于安卓的Arcore来实现的。
好吧,废话不多说,上代码,获取某一帧图,然后发送给识别检测的服务器
在Activity中
arFragment.getArSceneView().getScene().addOnUpdateListener(this::onUpdateFrame);
onUpdataFrame:
发送请求用的是okhttputil,在github上面搜一下就知道了 第一步:frame.acquireCameraImage();获得某一帧图片 第二步:OkHttpUtils.post()发送请求 第三步:ListhitResults1 = arFragment.getArSceneView().getArFrame().hitTest(positionResults.getPositionResults().get(0).getX(), positionResults.getPositionResults().get(0).getY()); 根据返回的像素点得到空间碰撞的HitResults 第四步: showDistance(hitResults1.get(0), hitResults2.get(0));展示距离吧 private void onUpdateFrame(FrameTime frameTime) { Frame frame = arFragment.getArSceneView().getArFrame(); // If there is no frame, just return. if (frame == null) { return; }
Image image = null; try { image = frame.acquireCameraImage(); Bitmap bitmap = imageToBitmap(image); if (bitmap != null) { File file = getFile(bitmap); OkHttpUtils.post() .addFile("file", "pic" + imageIndex + ".png", file)// .url("xxxxx") .build() .execute(new Callback() { @Override public Object parseNetworkResponse(Response response, int id) throws Exception { try { String str = response.body().string(); positionResults = new Gson().fromJson(str, PositionResults.class); return positionResults; } catch (Exception e) { e.printStackTrace(); } return null; } @Override public void onError(Call call, Exception e, int id) { System.out.println("error!!!!!"); } @Override public void onResponse(Object response, int id) { System.out.println("response"); } }); ListhitResults1 = arFragment.getArSceneView().getArFrame().hitTest(positionResults.getPositionResults().get(0).getX(), positionResults.getPositionResults().get(0).getY()); List hitResults2 = arFragment.getArSceneView().getArFrame().hitTest(positionResults.getPositionResults().get(1).getX(), positionResults.getPositionResults().get(1).getY()); if (hitResults1.size() > 0 && hitResults2.size() > 0) { showDistance(hitResults1.get(0), hitResults2.get(0)); } } } } catch (Exception e) { e.printStackTrace(); } finally { // sendFlag=true; if (null != image) { image.close(); } }
showDistance:
private void showDistance(HitResult hitResult1, HitResult hitResult2) { Anchor anchor1 = hitResult1.createAnchor(); AnchorNode firstAnchorNode = new AnchorNode(anchor1); Anchor anchor2 = hitResult2.createAnchor(); AnchorNode secondAnchorNode = new AnchorNode(anchor2); secondAnchorNode.setParent(arFragment.getArSceneView().getScene()); double ddx = (firstAnchorNode.getWorldPosition().x - secondAnchorNode.getWorldPosition().x); double ddy = (firstAnchorNode.getWorldPosition().y - secondAnchorNode.getWorldPosition().y); double ddz = (firstAnchorNode.getWorldPosition().z - secondAnchorNode.getWorldPosition().z); float ndl = (float) Math.sqrt(ddx * ddx + ddy * ddy + ddz * ddz);
Toast toast1 = Toast.makeText(this, "dl is" + dl + "M,firstV:(" + firstV.x + "," + firstV.y + "," + firstV.z + "),secendV:(" + secondV.x + "," + secondV.y + "," + secondV.z + ")", Toast.LENGTH_LONG); toast1.setGravity(Gravity.CENTER, 0, 0); toast1.show();
」
但是这样还是不够直观,所以在两点之间画根直线吧
private void addLineBetweenPoints(Scene scene, Vector3 from, Vector3 to) { // prepare an anchor position Quaternion camQ = scene.getCamera().getWorldRotation(); float[] f1 = new float[]{to.x, to.y, to.z}; float[] f2 = new float[]{camQ.x, camQ.y, camQ.z, camQ.w}; Pose anchorPose = new Pose(f1, f2); // make an ARCore Anchor Anchor anchor = arFragment.getArSceneView().getSession().createAnchor(anchorPose); // Node that is automatically positioned in world space based on the ARCore Anchor. AnchorNode anchorNode = new AnchorNode(anchor); anchorNode.setParent(scene); // Compute a line's length float lineLength = Vector3.subtract(from, to).length(); // Prepare a color Color colorOrange = new Color(android.graphics.Color.parseColor("#ffa71c")); // 1. make a material by the color MaterialFactory.makeOpaqueWithColor(this, colorOrange) .thenAccept(material -> { // 2. make a model by the material ModelRenderable model = ShapeFactory.makeCylinder(0.0025f, lineLength, new Vector3(0f, lineLength / 2, 0f), material); model.setShadowReceiver(false); model.setShadowCaster(false); // 3. make node Node node = new Node(); node.setRenderable(model); node.setParent(anchorNode); // 4. set rotation final Vector3 difference = Vector3.subtract(to, from); final Vector3 directionFromTopToBottom = difference.normalized(); final Quaternion rotationFromAToB = Quaternion.lookRotation(directionFromTopToBottom, Vector3.up()); node.setWorldRotation(Quaternion.multiply(rotationFromAToB, Quaternion.axisAngle(new Vector3(1.0f, 0.0f, 0.0f), 90))); }); }
完成!