El círculo de Hough no detecta los ojos del iris
Quiero detectar los iris de los ojos y sus centros usando el algoritmo del Hough Circle
.
Estoy usando este código:
- Convertir un mapa de bits en GrayScale en Android
- Cómo devolver una imagen de opencv y mostrar en código androide java?
- Incluir OpenCV en el paquete de aplicaciones de Android
- Android Yuv420sp a ARGB en OpenCV
- Viñeta en Android
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" ); }
Pero no detecta el iris en todas las imágenes correctamente. Especialmente, si el iris tiene un color oscuro como el marrón. ¿Cómo puedo corregir este código para detectar correctamente los iris y sus centros?
EDIT: Aquí hay algunas imágenes de muestra (que obtuve de la web) que muestra el rendimiento del algoritmo (Por favor, ignore los puntos de referencia que están representados por los cuadrados rojos):
En estas imágenes el algoritmo no detecta todos los iris:
Esta imagen muestra cómo el algoritmo no pudo detectar los iris en absoluto:
EDIT 2: Aquí hay un código que utiliza la detección Canny borde, pero hace que la aplicación se bloquee:
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" ); }
Este es el error que recibo en el registro
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)
Que es causada por esta línea: Imgproc.cvtColor(originalBitmap,grayMat,Imgproc.COLOR_BGR2GRAY);
¿Puede cualquier persona por favor decirme cómo este error puede solucionado? Tal vez la adición de una detección canny edge mejorará los resultados.
- Android OpenCV - detectar curvas de Houghlines
- Ajuste de saturación y ColorFilter a la imagen simultáneamente
- ¿Cómo deformar imágenes en Android?
- ¿Cuál es la mejor manera de enviar una imagen desde un dispositivo Android a un servidor para su procesamiento y enviar los resultados?
- Android: creación de un mapa de bits con contenido de SurfaceView
- Reconocimiento y seguimiento de objetos en movimiento más rápido en Android
- Error: No se puede obtener un lockedBuffer, el cliente muy probable intenta bloquear más de buffers maxImages
- Obtener el color del píxel tocado desde la vista previa de la cámara
Como usted desea detectar el iris usando la transformación del hough (hay otros), usted tenía mejor el estudiar el detector de borde de Canny y sus parámetros. cv::HoughCircles
toma el umbral de Canny-histéresis en param1
. Al investigar a Canny
solo, se obtiene la impresión de un buen rango de umbral.
Tal vez en lugar de gaussian blur, se aplica un mejor denoising (no local con decir h=32
y ventana tamaños 5 y 15), y también tratar de armonizar el contraste de la imagen, por ejemplo, utilizando el contraste limitada histograma adaptativo ecualización ( cv::CLAHE
).
La armonización es asegurarse de que todos los ojos (resaltados y sombreados) se asignen a un rango de intensidad similar.
Quise saber si esas imágenes son las imágenes que usted procesó o si usted tuvo gusto tomó una foto del teléfono celular de su pantalla para cargarlas aquí. Porque los irises son más grandes que el radio máximo que usted fija en su código. Por lo tanto, no entiendo cómo se puede encontrar ningún iris en absoluto. Los iris en la primera imagen tienen un radio de más de 20. Así que no debería ser capaz de detectarlos. Usted debe fijar los radios al radio que usted espera que sus iris sean.
Los círculos de Hough funcionan mejor en círculos bien definidos. No son buenos con cosas como el iris.
Después de un umbral, las operaciones morfológicas o detección canny borde, métodos de detección de características como MSER trabajar mucho mejor para la detección de iris.
Aquí hay una pregunta similar con una solución si estás buscando algún código.
- "Algo mal aquí, no esperaba que el paquete se reanude" error en android Logcat
- Android: Desplazamiento de problemas con recyclerview dentro de un viewpager