Лучшие параметры для определения зрачка с помощью hough? java opencv

----------------------------------------------------------------------------------------------------- Я пытаюсь обнаружить край зрачков и радужной оболочки на различных изображениях. Я изменяю параметры и тому подобное, но мне удается получить только один правильный контур радужной оболочки/зрачка, или получить ненужные контуры на заднем плане, или вообще ничего. Есть некоторые конкретные параметры, которые я должен попробовать и получить правильные очертания. Или есть способ обрезать изображение только по глазам, чтобы система могла сфокусироваться на этой части?

Это мой ОБНОВЛЕННЫЙ метод:

private void findPupilIris() throws IOException {
    //converts and saves image in grayscale

    Mat newimg = Imgcodecs.imread("/Users/.../pic.jpg");
    Mat des = new Mat(newimg.rows(), newimg.cols(), newimg.type());
    Mat norm = new Mat();

    Imgproc.cvtColor(newimg, des, Imgproc.COLOR_BGR2HSV);
    List<Mat> hsv = new ArrayList<Mat>();
    Core.split(des, hsv);
    Mat v = hsv.get(2); //gets the grey scale version

    Imgcodecs.imwrite("/Users/Lisa-Maria/Documents/CapturedImages/B&Wpic.jpg", v); //only writes mats

    CLAHE clahe = Imgproc.createCLAHE(2.0, new Size(8,8) ); //2.0, new Size(8,8) 
    clahe.apply(v,v);
//    Imgproc.GaussianBlur(v, v, new Size(9,9), 3); //adds left pupil boundary and random circle on 'a'
 //   Imgproc.GaussianBlur(v, v, new Size(9,9), 13); //adds right outer iris boundary and random circle on 'a'
    Imgproc.GaussianBlur(v, v, new Size(9,9), 7);  //adds left outer iris boundary and random circle on left by hair
  //  Imgproc.GaussianBlur(v, v, new Size(7,7), 15);
    Core.addWeighted(v, 1.5, v, -0.5, 0, v);


    Imgcodecs.imwrite("/Users/.../after.jpg", v); //only writes mats
    if (v != null) {
        Mat circles = new Mat();

        Imgproc.HoughCircles( v, circles, Imgproc.CV_HOUGH_GRADIENT, 2, v.rows(), 100, 20, 20, 200 );

        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();

        System.out.println("circles.cols() " + circles.cols());
        if(circles.cols() > 0) {
            System.out.println("1");
            for (int x = 0; x < circles.cols(); x++) {
                System.out.println("2");
                double vCircle[] = circles.get(0, x);


                if(vCircle == null) {
                    break;
                }

                Point pt = new Point(Math.round(vCircle[0]), Math.round(vCircle[1]));
                int radius = (int) Math.round(vCircle[2]);

                //draw the found circle




                Imgproc.circle(v, pt, radius, new Scalar(255,0,0),2); //newimg
                //Imgproc.circle(des, pt, radius/3, new Scalar(225,0,0),2); //pupil
                Imgcodecs.imwrite("/Users/.../Houghpic.jpg", v); //newimg

                //draw the mask: white circle on black background
//                  Mat mask = new Mat( new Size( des.cols(), des.rows() ), CvType.CV_8UC1 );
//                  Imgproc.circle(mask, pt, radius, new Scalar(255,0,0),2); 

//                  des.copyTo(des,mask);
//                  Imgcodecs.imwrite("/Users/..../mask.jpg", des); //newimg


                Imgproc.logPolar(des, norm, pt, radius, Imgproc.WARP_FILL_OUTLIERS);
                Imgcodecs.imwrite("/Users/..../Normalised.jpg",norm);
            }
        }
    }
}

Результат: хоть фото


person tgif    schedule 10.04.2017    source источник
comment
Почему вы опубликовали еще вопрос?   -  person Rick M.    schedule 10.04.2017
comment
потому что я изменил его, я собираюсь удалить другой, теперь я могу только иногда обнаруживать края зрачков / радужной оболочки   -  person tgif    schedule 11.04.2017
comment
Так новые фильтры работали для вас? Который из?   -  person Rick M.    schedule 11.04.2017
comment
я сделал правку, которая объясняет, что происходит, спасибо :)   -  person tgif    schedule 11.04.2017
comment
ааа, спасибо, я внес пару правок в свой код, скажите, теперь код правильный? и это определенно улучшило результат, я думаю, мне нужно сделать контур зрачка немного больше, хотя   -  person tgif    schedule 11.04.2017
comment
хм, когда я использую разные изображения, кажется, что это не работает при захвате радужной оболочки   -  person tgif    schedule 11.04.2017
comment
Вы должны попробовать использовать bilateralfilter вместо Гаусса. Может быть адаптивное выравнивание гистограммы. Было бы полезно, если бы вы загрузили наилучший и наихудший случай из набора данных, чтобы лучше понять проблему.   -  person Rick M.    schedule 11.04.2017
comment
Итак, я добавил билатеральный фильтр и получил наилучшее изображение, которого мне удалось достичь. Хуже всего то, что кружков совсем нет или они просто появляются в неправильных местах на заднем плане. Я попытался добавить гистограмму, но, похоже, без нее получился лучший результат. Спасибо.   -  person tgif    schedule 14.04.2017
comment
Можете ли вы выложить изображение в худшем случае тоже? Я постараюсь разобраться и вернуться к вам   -  person Rick M.    schedule 14.04.2017
comment
привет, @RickM. ты случайно ничего не понял?   -  person tgif    schedule 18.04.2017
comment
Привет! Я был занят на работе. Сегодня, наверное, конец :)   -  person Rick M.    schedule 19.04.2017
comment
Хорошо, кое-что понял, но лучше обсудить это в чате, прежде чем я отправлю ответ. Дайте мне знать, когда у вас будет время. тогда постараюсь быть онлайн   -  person Rick M.    schedule 19.04.2017
comment
ладно, круто, теперь я свободен, если еще не поздно? или в любое время завтра   -  person tgif    schedule 19.04.2017
comment
Я онлайн в течение следующих 8 часов   -  person Rick M.    schedule 20.04.2017
comment
хорошо, теперь я свободен   -  person tgif    schedule 20.04.2017
comment
Хорошо, я приглашу вас в чат   -  person Rick M.    schedule 20.04.2017
comment
хорошо, спасибо за помощь   -  person tgif    schedule 20.04.2017
comment
чат   -  person Rick M.    schedule 20.04.2017
comment
эй, извините, я не думаю, что у меня достаточно высокая репутация, чтобы говорить в чате   -  person tgif    schedule 20.04.2017
comment
Аааа ок. Что нам делать тогда? Вы можете читать сообщения в чате? Те, что я публикую?   -  person Rick M.    schedule 20.04.2017
comment
да я умею их читать   -  person tgif    schedule 20.04.2017
comment
спасибо, это было полезно! Я просто загружу изображение   -  person tgif    schedule 20.04.2017
comment
я попробую обновить свою версию позже или завтра, спасибо   -  person tgif    schedule 20.04.2017
comment
Звучит хорошо, я опубликую ответ как можно скорее   -  person Rick M.    schedule 20.04.2017
comment
только что обновил свой ответ :)   -  person tgif    schedule 21.04.2017
comment
Выглядит хорошо, возможно, вам следует сохранить результаты нерезкой маски в другое изображение. Потому что для меня выходное изображение выглядит очень размытым, что на самом деле не помогает. Кроме того, попробуйте использовать разные размеры ядра и сигму для Gaussian Blur перед addWeighted.   -  person Rick M.    schedule 21.04.2017
comment
спасибо, я пробовал с разными размерами/сигма и обнаружил, что все размеры между 7-11 работают одинаково, более низкие значения не работают так хорошо.   -  person tgif    schedule 21.04.2017


Ответы (1)


После обсуждения в комментариях я публикую общий ответ с некоторыми результатами, которые я получил на изображении в худшем случае, загруженном OP.

Примечание. Код, который я публикую, написан на Python, так как мне проще всего писать его.

Шаг 1. Поскольку вы спрашиваете, как обрезать изображение, чтобы сфокусироваться только на глазах, вы можете посмотреть на Распознавание лиц. Так как изображение по сути требует найти только глаза, я сделал следующее:

eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')
eyes = eye_cascade.detectMultiScale(v) // v is the value channel of the HSV image
// The results "eyes" gives you the dimensions of the rectangle where the eyes are detected as [x, y, w, h]
// Just for drawing 
cv2.rectangle(v, (x1, y1), (x1+w1, y1+h1), (0, 255, 0), 2)
cv2.rectangle(v, (x2, y2), (x2+w2, y2+h2), (0, 255, 0), 2)

Результат каскадного классификатора Хаара

Теперь, когда у вас есть ограничивающие прямоугольники, вы можете обрезать прямоугольники из изображения, например:

crop_eye1 = v[y1:y1+h1, x1:x1+w1]
crop_eye2 = v[y2:y2+h2, x2:x2+w2]

После того, как вы получите прямоугольники, я бы предложил изучить разные цветовые пространства вместо RGB/BGR, в частности HSV/Lab/Luv.

Поскольку компоненты R, G и B цвета объекта на цифровом изображении коррелируют с количеством света, падающего на объект, и, следовательно, друг с другом, описание изображения с точки зрения этих компонентов затрудняет различение объектов. Описания в терминах оттенок/яркость/цветность или оттенок/яркость/насыщенность часто более уместны

Затем, когда у вас есть глаза, пришло время выровнять контрастность изображения, однако я предлагаю использовать CLAHE и поэкспериментируйте с параметрами для clipLimit и tileGridSize. Вот код, который я реализовал некоторое время назад на Java:

private static Mat clahe(Mat image, int ClipLimit, Size size){
  CLAHE clahe = Imgproc.createCLAHE();
  clahe.setClipLimit(ClipLimit);
  clahe.setTilesGridSize(size);
  Mat dest_image = new Mat();
  clahe.apply(image, dest_image);
  return dest_image;
}     

Когда вы будете удовлетворены, вы должны повысить резкость изображения, чтобы HoughCircle надежен. Вы должны посмотреть на unsharpMask. Вот код на Java для UnsharpMask, который я реализовал на Java:

private static Mat unsharpMask(Mat input_image, Size size, double sigma){

// Make sure the {input_image} is gray.
  Mat sharpend_image = new Mat(input_image.rows(), input_image.cols(), input_image.type());
  Mat Blurred_image = new Mat(input_image.rows(), input_image.cols(), input_image.type());
  Imgproc.GaussianBlur(input_image, Blurred_image, size, sigma);
  Core.addWeighted(input_image, 2.0D, Blurred_image, -1.0D, 0.0D, sharpened_image);
  return sharpened_image;
}

В качестве альтернативы вы можете использовать двусторонний фильтр, сохраняющий края, или прочитать это для определения пользовательского ядра для повышения резкости изображения. Надеюсь, это поможет и удачи!

person Rick M.    schedule 21.04.2017
comment
Здорово! Дайте мне знать, как это работает, если это сработает, пожалуйста, примите это как ответ для будущих зрителей! - person Rick M.; 21.04.2017