使用 OpenCV 和 Android-Studio 的瞳孔检测项目获取 ArrayIndexOutOfBoundsException
Pupil detection project with OpenCV & Android-Studio gets ArrayIndexOutOfBoundsException
我必须为 Android-studio 做一个项目,其中一个目标是检测一个人的瞳孔。我正在尝试使用 OpenCV。我知道使用 OpenCV 在这个网站上检测圆圈或眼睛有很多问题,但每次我尝试执行我的代码时,应用程序都会因一个没有人报告的特定错误而崩溃,即:
2021-03-30 21:44:08.178 19272-19500/com.android.unipi.camerawifiprova E/AndroidRuntime: FATAL EXCEPTION: Thread-7
Process: com.android.unipi.camerawifiprova, PID: 19272
java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
我在 onCameraViewStarted() 和 onCameraFrame() 方法中分享我的代码。
@Override
public void onCameraViewStarted(int width, int height) {
dst = new Mat();
matGray = new Mat();
circles = new Mat();
}
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
Core.transpose(mRgba,mRgbaT);
Core.flip(mRgbaT, dst,1);
Imgproc.resize(mRgbaT,mRgbaT, mRgba.size());
mRgba.release();
mRgbaT.release();
Bitmap resultBitmap;
resultBitmap = Bitmap.createBitmap(dst.cols(), dst.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dst, resultBitmap);
matGray = new Mat(resultBitmap.getWidth(), resultBitmap.getHeight(), CvType.CV_8UC1);
Utils.bitmapToMat(resultBitmap, matGray);
int colorChannels = (matGray.channels() == 3) ? Imgproc.COLOR_BGR2GRAY
: ((matGray.channels() == 4) ? Imgproc.COLOR_BGRA2GRAY : 1);
Imgproc.cvtColor(matGray, matGray, colorChannels);
circles = new Mat(resultBitmap.getWidth(), resultBitmap.getHeight(), CvType.CV_8UC1);
Imgproc.GaussianBlur(matGray, matGray, new Size(9,9),2,2);
double dp = 1d;
double minDist = 20;
int minRadius = 0, maxRadius = 0;
double param1 = 105;
double param2 = 40;
Imgproc.HoughCircles(matGray, circles, Imgproc.CV_HOUGH_GRADIENT, dp, minDist,
param1, param2, minRadius, maxRadius);
int numCircles = (circles.rows() == 0) ? 0 : circles.cols();
for (int i = 0; i < numCircles; i++) {
double[] circlePar = circles.get(0,i);
int x = (int) circlePar[0], y = (int) circlePar[1]; // -> ArrayIndexOutOfBoundsException!!
Point center = new Point(x,y);
int radius = (int) circlePar[2];
Imgproc.circle(dst,center,radius,new Scalar(0,0,255),4);
}
matGray.release();
circles.release();
return dst;
}
我打印变量 circlePar
:它应该有三个值(中心坐标和半径),但我只有一个 [0.0]。也许程序无法检测到任何圆圈。我尝试了一个简单的任务(检测桌子上的一枚硬币),但由于上述原因,应用程序仍然崩溃。
一段时间后,我自己弄明白了。问题就在下面这行
circles = new Mat(resultBitmap.getWidth(), resultBitmap.getHeight(), CvType.CV_8UC1);
我不必将矩阵的维度circles
定义为图像的维度。取消那行代码后,程序运行正常:我可以实时检测圆圈、硬币甚至眼睛的虹膜。
方法HoughCircles
的结果是一个1xN维的矩阵,其中N是检测到的圆的数量,矩阵的每个元素都是三个数据的向量:中心坐标和半径.
我知道 Hough 不是检测瞳孔位置的最佳方法,但对于我的项目来说很好。
还有一件事。为了获得灰度图像,我们可以使用方法 inputFrame.gray()
但不要忘记也转置该图像。
matGray = inputFrame.gray();
Core.transpose(matGray,matGray);
Core.flip(matGray,matGray,1);
我必须为 Android-studio 做一个项目,其中一个目标是检测一个人的瞳孔。我正在尝试使用 OpenCV。我知道使用 OpenCV 在这个网站上检测圆圈或眼睛有很多问题,但每次我尝试执行我的代码时,应用程序都会因一个没有人报告的特定错误而崩溃,即:
2021-03-30 21:44:08.178 19272-19500/com.android.unipi.camerawifiprova E/AndroidRuntime: FATAL EXCEPTION: Thread-7
Process: com.android.unipi.camerawifiprova, PID: 19272
java.lang.ArrayIndexOutOfBoundsException: length=1; index=1
我在 onCameraViewStarted() 和 onCameraFrame() 方法中分享我的代码。
@Override
public void onCameraViewStarted(int width, int height) {
dst = new Mat();
matGray = new Mat();
circles = new Mat();
}
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
Core.transpose(mRgba,mRgbaT);
Core.flip(mRgbaT, dst,1);
Imgproc.resize(mRgbaT,mRgbaT, mRgba.size());
mRgba.release();
mRgbaT.release();
Bitmap resultBitmap;
resultBitmap = Bitmap.createBitmap(dst.cols(), dst.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dst, resultBitmap);
matGray = new Mat(resultBitmap.getWidth(), resultBitmap.getHeight(), CvType.CV_8UC1);
Utils.bitmapToMat(resultBitmap, matGray);
int colorChannels = (matGray.channels() == 3) ? Imgproc.COLOR_BGR2GRAY
: ((matGray.channels() == 4) ? Imgproc.COLOR_BGRA2GRAY : 1);
Imgproc.cvtColor(matGray, matGray, colorChannels);
circles = new Mat(resultBitmap.getWidth(), resultBitmap.getHeight(), CvType.CV_8UC1);
Imgproc.GaussianBlur(matGray, matGray, new Size(9,9),2,2);
double dp = 1d;
double minDist = 20;
int minRadius = 0, maxRadius = 0;
double param1 = 105;
double param2 = 40;
Imgproc.HoughCircles(matGray, circles, Imgproc.CV_HOUGH_GRADIENT, dp, minDist,
param1, param2, minRadius, maxRadius);
int numCircles = (circles.rows() == 0) ? 0 : circles.cols();
for (int i = 0; i < numCircles; i++) {
double[] circlePar = circles.get(0,i);
int x = (int) circlePar[0], y = (int) circlePar[1]; // -> ArrayIndexOutOfBoundsException!!
Point center = new Point(x,y);
int radius = (int) circlePar[2];
Imgproc.circle(dst,center,radius,new Scalar(0,0,255),4);
}
matGray.release();
circles.release();
return dst;
}
我打印变量 circlePar
:它应该有三个值(中心坐标和半径),但我只有一个 [0.0]。也许程序无法检测到任何圆圈。我尝试了一个简单的任务(检测桌子上的一枚硬币),但由于上述原因,应用程序仍然崩溃。
一段时间后,我自己弄明白了。问题就在下面这行
circles = new Mat(resultBitmap.getWidth(), resultBitmap.getHeight(), CvType.CV_8UC1);
我不必将矩阵的维度circles
定义为图像的维度。取消那行代码后,程序运行正常:我可以实时检测圆圈、硬币甚至眼睛的虹膜。
方法HoughCircles
的结果是一个1xN维的矩阵,其中N是检测到的圆的数量,矩阵的每个元素都是三个数据的向量:中心坐标和半径.
我知道 Hough 不是检测瞳孔位置的最佳方法,但对于我的项目来说很好。
还有一件事。为了获得灰度图像,我们可以使用方法 inputFrame.gray()
但不要忘记也转置该图像。
matGray = inputFrame.gray();
Core.transpose(matGray,matGray);
Core.flip(matGray,matGray,1);