如何使用 android 相机找到物体的真实宽度和高度?

How to find real width and height of objects using android camera?

    I want to find object's real height and width using android camera, I am using OpenCv library for Image Processing. I can get height and width in the Image by finding contour , but it is not real height and width it changes when the object's move far from the device. My main purpose is to measure actual width and height of wounds. 

使用下面的代码我可以使用下面的代码标记伤口位置。我可以很容易地标记伤口,但是我从处理过的图像中得到的宽度和高度是错误的。它不是标记位置的实际宽度和高度。我想我需要更多的图像细节和与相机的距离等。

@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
    mRgba = inputFrame.rgba();
    contours = new ArrayList<MatOfPoint>();
    hierarchy = new Mat();
    Imgproc.GaussianBlur(mRgba,mIntermediateMat,new Size(9,9),2,2);
    Imgproc.Canny(mRgba, mIntermediateMat, 80, 100);
    Imgproc.findContours(mIntermediateMat, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));
/* Mat drawing = Mat.zeros( mIntermediateMat.size(), CvType.CV_8UC3 );
 for( int i = 0; i< contours.size(); i++ )
 {
Scalar color =new Scalar(Math.random()*255, Math.random()*255, Math.random()*255);
 Imgproc.drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, new Point() );
 }*/
    hierarchy.release();
            // Imgproc.cvtColor(mIntermediateMat, mRgba, Imgproc.COLOR_GRAY2RGBA, 4)
/* Mat drawing = Mat.zeros( mIntermediateMat.size(), CvType.CV_8UC3 );
 for( int i = 0; i< contours.size(); i++ )
 {`enter code here`
Scalar color =new Scalar(Math.random()*255, Math.random()*255, Math.random()*255);
 Imgproc.drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, new Point() );
 }*/
    for ( int contourIdx=0; contourIdx < contours.size(); contourIdx++ )
    {
        // Minimum size allowed for consideration
        MatOfPoint2f approxCurve = new MatOfPoint2f();
        MatOfPoint2f contour2f = new MatOfPoint2f( contours.get(contourIdx).toArray() );
        //Processing on mMOP2f1 which is in type MatOfPoint2f
        double approxDistance = Imgproc.arcLength(contour2f, true)*0.02;
        Imgproc.approxPolyDP(contour2f, approxCurve, approxDistance, true);

        //Convert back to MatOfPoint
        MatOfPoint points = new MatOfPoint( approxCurve.toArray() );

        // Get bounding rect of contour
        Rect rect = Imgproc.boundingRect(points);

            Core.rectangle(mRgba, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(255, 0, 0, 255), 3);



    }
    return mRgba;
}

你的问题很笼统。你没有说明你想衡量的是什么,所以我会笼统地回答。

您实际上并没有在计算机视觉中使用相机找到任何真实物体的宽度和高度。您正在使用从相机捕获的 frame 中提取的一些参数对它们进行建模,这是一个二维数字图像,在最新的 opencv 中由 Mat 表示- 简单地说,矩阵的宽度,图像的高度为代表像素数据和一些元数据的二维数字数组。由于您捕获了该帧并且 return 处理后的帧返回到 android 部分(如果 需要 - e.q。您需要流式传输相机)AndroidOpenCV 完全是不同的东西。您可以使用 Google Camera API 从相机捕获帧并将其转换为 Mat 或实现 opencv View(这种方式更简单,有缺陷,老实说,很烂)。
在此矩阵或从图像 Mat 获取的其他矩阵(如多边形轮廓点)上,您应用来自 opencv 模块的方法。其中一些可以 draw/return 矩形(通常 || 到图像边界)在图像的特定区域。 一般,你可以使用方法族

找到smth的轮廓
 void findContours(.., List < MatOfPoint> countors, ..)  

然后使用

Rect rect = boundingRect(MatOfPoint contour);

从该列表(如果有的话)的连续r 上得到 Rect around smth。显然,如果您拥有等高线权利,那么 Rect 将具有您正在寻找的宽度和高度。这些几乎是 "pixel height and width" 图像中的 2d-object


要获得真实物理对象的尺寸,您必须有一些物理几何模型,并在找到的数字上使用该模型的公式。 例如, 如果您的对象 平行于 相机 (phone) 并且 居中 你可以

  final double realWorldHeight = rect.size().height / imageMat.size().height *
  realWorldDistanceToObject * Math.cos( realWorldAngleOfObjectHeight / 2);

物体的角度是弧度物体从相机的观察点垂直占据的角度。