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;
}
答案 0 :(得分:2)
您的问题非常一般。您没有说出您要测量的是什么,所以我会回答一般。
在计算机视觉中,您实际上没有使用相机找到任何真实对象的宽度和高度。您正在使用从相机捕获的帧中提取的一些参数对其进行建模,这是一个2D数字图像,由 Mat 在最新的opencv中表示 - 只需put,带有宽度的矩阵,图像的高度,用于表示像素数据和一些元数据的2d数组。因为你抓住那个帧并将处理过的帧返回到android部分(如果需要 - eq你需要流式传输相机) Android 和 OpenCV 是完全单独的东西。您可以使用Google Camera API从相机捕获帧并将其转换为Mat或实现opencv View(这种方式更简单,错误,老实说,很糟糕)。
在此矩阵或其他矩阵(如多边形轮廓点)从图像Mat获取,您应用opencv模块中的方法。其中一些可以在图像的特定区域上绘制/返回矩形(通常是||到图像边界)。 通常,您可以使用方法系列
void findContours(.., List < MatOfPoint> countors, ..)
然后使用
Rect rect = boundingRect(MatOfPoint contour);
在该列表中的一个 r 上(如果有的话),以获得围绕smth的Rect。如果你有轮廓权利,显然Rect会有你想要的宽度和高度。这几乎是像素的高度和宽度&#34;在图像中的2d对象。
要获得真实物理对象的尺寸,您必须拥有一些物理几何模型,并在找到的数字上使用该模型中的公式。 例如,如果你的对象平行到相机(手机),居中你可以
final double realWorldHeight = rect.size().height / imageMat.size().height *
realWorldDistanceToObject * Math.cos( realWorldAngleOfObjectHeight / 2);
物体的角度是物体从相机的外观垂直占据弧度的程度。