我一直在关注Android上使用OpenCV 3.1.0跟踪圆形/椭圆形对象的教程,我需要一些代码优化方面的帮助并提高识别准确性。目前,代码尝试查找每个帧中的所有圆圈并在其周围绘制轮廓。由于我是OpenCV的新手,我希望有人可以帮我解决以下问题:
- 当相机识别出圆形物体并绘制轮廓时,帧速率降至1-2fps。否则,帧率是不错的。如何优化我的代码来解决这个问题?
- 我想跟踪一个非常特殊的对象,这个对象也恰好是一个不完美的圆圈。那个,我的意思是圆周围有微小的凹痕。此外,如果可能,我希望能够从侧面跟踪对象(对象是圆柱形),这意味着绘图圆(顶视图)和绘制椭圆/矩形(圆角/侧视图)之间的平滑过渡。
- 我得到了许多误报以及对其他圆形物体的识别。我已经考虑过根据我想要跟踪的对象(白色)的特定颜色对帧进行阈值处理,但我不确定如何实现它。
public class MainActivity extends Activity implements CvCameraViewListener2 {
private static final String TAG = "OCVSample::Activity";
private CameraBridgeViewBase mOpenCvCameraView;
private boolean mIsJavaCamera = true;
private MenuItem mItemSwitchCamera = null;
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:
{
Log.i(TAG, "OpenCV loaded successfully");
mOpenCvCameraView.enableView();
mOpenCvCameraView.setMaxFrameSize(640,480);
} break;
default:
{
super.onManagerConnected(status);
} break;
}
}
};
public MainActivity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_main);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.activity_main);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
}
@Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
public void onResume()
{
super.onResume();
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
public void onCameraViewStarted(int width, int height) {
}
public void onCameraViewStopped() {
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
Mat rgba = inputFrame.rgba();
Core.flip(rgba, rgba, 1);
Mat greyMat = new Mat();
Imgproc.cvtColor(rgba, greyMat,Imgproc.COLOR_RGBA2GRAY , 0);
Imgproc.GaussianBlur(greyMat, greyMat, new Size(9, 9), 2,2);
double dp = 1.2d;
double minDist = 100;
int minRadius = 0;
int maxRadius = 0;
double param1 = 70, param2 = 72;
Mat circles = new Mat();
Imgproc.HoughCircles(greyMat, circles, Imgproc.HOUGH_GRADIENT, dp, minDist, param1, param2, minRadius, maxRadius);
int numCircles = (circles.rows()==0) ? 0: circles.cols();
for (int i = 0; i < numCircles; i++) {
double[] circleCoordinates = circles.get(0, i);
int x = (int) circleCoordinates[0], y = (int)circleCoordinates[1];
Point center = new Point(x,y);
int radius = (int) circleCoordinates[2];
Imgproc.circle(rgba, center, radius, new Scalar(0, 255, 0), 4);
}
return rgba;
}
}