Android 霍夫圆不';无法检测眼睛虹膜
我想用Android 霍夫圆不';无法检测眼睛虹膜,android,opencv,image-processing,hough-transform,eye-detection,Android,Opencv,Image Processing,Hough Transform,Eye Detection,我想用Hough圆算法检测眼睛虹膜及其中心 我正在使用以下代码: private void houghCircle() { Bitmap obtainedBitmap = imagesList.getFirst(); /* convert bitmap to mat */ Mat mat = new Mat(obtainedBitmap.getWidth(),obtainedBitmap.getHeight(),
Hough圆
算法检测眼睛虹膜及其中心
我正在使用以下代码:
private void houghCircle()
{
Bitmap obtainedBitmap = imagesList.getFirst();
/* convert bitmap to mat */
Mat mat = new Mat(obtainedBitmap.getWidth(),obtainedBitmap.getHeight(),
CvType.CV_8UC1);
Mat grayMat = new Mat(obtainedBitmap.getWidth(), obtainedBitmap.getHeight(),
CvType.CV_8UC1);
Utils.bitmapToMat(obtainedBitmap, mat);
/* convert to grayscale */
int colorChannels = (mat.channels() == 3) ? Imgproc.COLOR_BGR2GRAY : ((mat.channels() == 4) ? Imgproc.COLOR_BGRA2GRAY : 1);
Imgproc.cvtColor(mat, grayMat, colorChannels);
/* reduce the noise so we avoid false circle detection */
Imgproc.GaussianBlur(grayMat, grayMat, new Size(9, 9), 2, 2);
// accumulator value
double dp = 1.2d;
// minimum distance between the center coordinates of detected circles in pixels
double minDist = 100;
// min and max radii (set these values as you desire)
int minRadius = 0, maxRadius = 1000;
// param1 = gradient value used to handle edge detection
// param2 = Accumulator threshold value for the
// cv2.CV_HOUGH_GRADIENT method.
// The smaller the threshold is, the more circles will be
// detected (including false circles).
// The larger the threshold is, the more circles will
// potentially be returned.
double param1 = 70, param2 = 72;
/* create a Mat object to store the circles detected */
Mat circles = new Mat(obtainedBitmap.getWidth(), obtainedBitmap.getHeight(), CvType.CV_8UC1);
/* find the circle in the image */
Imgproc.HoughCircles(grayMat, circles, Imgproc.CV_HOUGH_GRADIENT, dp, minDist, param1, param2, minRadius, maxRadius);
/* get the number of circles detected */
int numberOfCircles = (circles.rows() == 0) ? 0 : circles.cols();
/* draw the circles found on the image */
for (int i=0; i<numberOfCircles; i++) {
/* get the circle details, circleCoordinates[0, 1, 2] = (x,y,r)
* (x,y) are the coordinates of the circle's center
*/
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];
/* circle's outline */
Core.circle(mat, center, radius, new Scalar(0,
255, 0), 4);
/* circle's center outline */
Core.rectangle(mat, new Point(x - 5, y - 5),
new Point(x + 5, y + 5),
new Scalar(0, 128, 255), -1);
}
/* convert back to bitmap */
Utils.matToBitmap(mat, obtainedBitmap);
MediaStore.Images.Media.insertImage(getContentResolver(),obtainedBitmap, "testgray", "gray" );
}
这是由此行引起的:Imgproc.cvtColor(originalBitmap,grayMat,Imgproc.COLOR\u bgr2 gray)代码>
有人能告诉我如何解决这个错误吗?也许添加一个精明的边缘检测将改善结果 由于您希望使用hough变换检测虹膜(还有其他方法),因此最好研究Canny边缘检测器及其参数。
cv::HoughCircles
采用param1
中的Canny滞后阈值。单独调查Canny
,您会得到良好阈值范围的印象
也许可以使用更好的去噪(非局部平均值,例如h=32
和窗口大小5和15),而不是高斯模糊,并尝试协调图像对比度,例如使用对比度受限的自适应直方图均衡化(cv::CLAHE
)
协调是为了确保所有(高光和阴影)眼睛都映射到类似的强度范围。我想知道这些图像是否是您处理的图像,或者您是否愿意拍摄屏幕的手机快照以上传到这里。因为虹膜大于您在代码中设置的最大半径。所以我不明白你怎么能找到虹膜。第一幅图像中的虹膜半径超过20。所以你不应该发现它们。
您应该将半径设置为您期望的虹膜半径范围。Hough圆在定义良好的圆上效果更好。他们不擅长像iris这样的东西
经过阈值分割、形态学运算或canny边缘检测后,MSER等特征检测方法对虹膜检测效果更好
如果您正在寻找一些代码,这是一个类似的问题和解决方案。您至少应该共享一些图像。@guneykayim谢谢,请检查我更新的问题。这些只是快照吗?因为虹膜与maxRadius参数不匹配?我对你发现的最大半径为10的东西感到困惑。@Pigger谢谢,对不起,但我不理解你关于这些图片是真实的还是快照的问题,你能详细说明一下吗?我将这些图片输入到应用程序中,它给出了问题的结果。我直接在应用程序中输入了第一个和第三个,但第二个是从设备的前摄像头捕获的。你的意思是最大半径应该是10?在代码中设置为10,什么值适合我的情况?您的错误来自这样一个事实,即cvtColor
的输入已经是单通道(CV_8UC1
)。是的,第一个和第三个是快照,因为我的应用程序布局设置为输出带有检测到的虹膜的输入图像。第二个是应用程序在处理前摄像头输入的图像后存储在my mobile gallery中的图像。抱歉,我想我已经发布了一个关于半径的修改版本的代码,因为我正在尝试更改它。我想是1000。虹膜半径的通常值是多少?我试过100种,但都不管用。谢谢。我更新了问题,在那里我添加了一个使用canny检测的代码,你能检查一下吗,它给了我一个例外。谢谢,我试着读了一些关于canny的内容,甚至我也试过使用它的代码,但是当我使用包含canny的代码时,应用程序立即崩溃,日志中没有错误消息。我试过medianBlur,但没有解决问题。什么是协调对比?还有,这会有什么帮助?你能详细说明一下吗?谢谢。我可以找到导致应用程序崩溃的异常,但我不知道如何解决它。我更新了问题,请检查一下。谢谢
private void houghCircle()
{
Mat grayMat = new Mat();
Mat cannyEdges = new Mat();
Mat circles = new Mat();
Bitmap obtainedBitmap = imagesList.getFirst();
/* convert bitmap to mat */
Mat originalBitmap = new Mat(obtainedBitmap.getWidth(),obtainedBitmap.getHeight(),
CvType.CV_8UC1);
//Converting the image to grayscale
Imgproc.cvtColor(originalBitmap,grayMat,Imgproc.COLOR_BGR2GRAY);
Imgproc.Canny(grayMat, cannyEdges,10, 100);
Imgproc.HoughCircles(cannyEdges, circles,
Imgproc.CV_HOUGH_GRADIENT,1, cannyEdges.rows() / 15); //now circles is filled with detected circles.
//, grayMat.rows() / 8);
Mat houghCircles = new Mat();
houghCircles.create(cannyEdges.rows(),cannyEdges.cols()
,CvType.CV_8UC1);
//Drawing lines on the image
for(int i = 0 ; i < circles.cols() ; i++)
{
double[] parameters = circles.get(0,i);
double x, y;
int r;
x = parameters[0];
y = parameters[1];
r = (int)parameters[2];
Point center = new Point(x, y);
//Drawing circles on an image
Core.circle(houghCircles,center,r,
new Scalar(255,0,0),1);
}
//Converting Mat back to Bitmap
Utils.matToBitmap(houghCircles, obtainedBitmap);
MediaStore.Images.Media.insertImage(getContentResolver(),obtainedBitmap, "testgray", "gray" );
}
FATAL EXCEPTION: Thread-28685
CvException [org.opencv.core.CvException: cv::Exception: /hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/imgproc/src/color.cpp:3739: error: (-215) scn == 3 || scn == 4 in function void cv::cvtColor(cv::InputArray, cv::OutputArray, int, int)
]
at org.opencv.imgproc.Imgproc.cvtColor_1(Native Method)
at org.opencv.imgproc.Imgproc.cvtColor(Imgproc.java:4598)