6

Hough Circleアルゴリズムを使用して目の虹彩とその中心を検出したい。

私はこのコードを使用しています:

 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" );

    }

ただし、すべての画像で虹彩を正しく検出するわけではありません。特に、虹彩が茶色のような濃い色の場合。このコードを修正して、虹彩とその中心を正しく検出するにはどうすればよいですか?

編集:アルゴリズムのパフォーマンスを示すサンプル画像(ウェブから取得したもの)を次に示します(赤い四角で表されるランドマークは無視してください):

これらの画像では、アルゴリズムはすべての虹彩を検出していません。

ここに画像の説明を入力

ここに画像の説明を入力

この画像は、アルゴリズムが虹彩をまったく検出できなかったことを示しています。

ここに画像の説明を入力

編集 2: これは Canny エッジ検出を使用するコードですが、アプリがクラッシュする原因となります:

 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)

これは、次の行によって引き起こされます。 Imgproc.cvtColor(originalBitmap,grayMat,Imgproc.COLOR_BGR2GRAY);

このエラーを解決する方法を教えてください。おそらく、巧妙なエッジ検出を追加すると、結果が改善されるでしょう。

4

3 に答える 3

2

ハフ変換(他にもあります)を使用して虹彩を検出したいので、キャニーエッジ検出器とそのパラメーターを調べた方がよいでしょう。 cv::HoughCirclesのキャニー ヒステリシスしきい値を取りますparam1。単独で調査Cannyすると、適切なしきい値範囲の印象が得られます。

おそらく、ガウスぼかしの代わりに、より良いノイズ除去 (たとえばh=32、ウィンドウ サイズ 5 と 15 の非局所的な手段) を適用し、たとえばコントラスト制限適応ヒストグラム均等化 ( cv::CLAHE) を使用して、画像のコントラストを調和させようとします。

ハーモナイゼーションとは、すべての (ハイライトとシャドウの) 目が同じような強度範囲にマッピングされるようにすることです。

于 2016-02-09T17:12:20.947 に答える
1

それらの画像があなたが処理した画像なのか、それとも画面の携帯電話のスナップショットを撮ってここにアップロードしたいのか知りたい. 虹彩は、コードで設定した最大半径よりも大きいためです。そのため、虹彩を見つける方法がまったくわかりません。最初の画像の虹彩の半径は 20 を超えています。したがって、それらを検出することはできません。虹彩が予想される半径範囲に半径を設定する必要があります。

于 2016-02-09T17:13:47.523 に答える