OpenCV, вариация лапласиана (Java)

Я пытаюсь найти вариацию для лапласиана на основе изображения с целью получения числового значения, основанного на размытости изображения.

Это полезный пост http://www.pyimagesearch.com/2015/09/07/blur-detection-with-opencv/

cv2.Laplacian(image, cv2.CV_64F).var()

Я пытался реализовать то же самое без удачи. Моя отправная точка - байт [], представляющий изображение (img):

Mat mat = new Mat(img.getImageHeight(), img.getImageWidth(), CvType.CV_8UC3);
Imgproc.cvtColor(mat, mat, Imgproc.COLOR_BGR2GRAY);
mat.put(0, 0, putData.getFileContents());
Imgproc.Laplacian(mat,mat, CvType.CV_64F);

Любая помощь будет оценена.

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

2 ответа

Преобразование Лапласа можно заменить ядром, примененным методом filter2D. Я выполнял тот же пример Python в Java-программе, как это:

    Mat destination = new Mat();
    Mat matGray=new Mat();  
    Mat kernel = new Mat(3,3, CvType.CV_32F){
       {
          put(0,0,0);
          put(0,1,-1);
          put(0,2,0);

          put(1,0-1);
          put(1,1,4);
          put(1,2,-1);

          put(2,0,0);
          put(2,1,-1);
          put(2,2,0);
       }
    };        
    Imgproc.cvtColor(image, matGray, Imgproc.COLOR_BGR2GRAY);          
    Imgproc.filter2D(matGray, destination, -1, kernel); 
    MatOfDouble median = new MatOfDouble();
    MatOfDouble std= new MatOfDouble();        
    Core.meanStdDev(destination, median , std);

    Math.pow(std.get(0,0)[0],2);

Надеюсь, это поможет вашему кодированию.

Примечание: значения, которые я получаю из программ на Python и Java, отличаются, и я до сих пор не понял, почему. Во всяком случае, Java-код работает хорошо.

Выяснил, почему значения не были одинаковыми. Использование метода Imgproc.Laplacian вместо Imgproc.filter2D приводит к точно таким же значениям в python и java.

Новый код становится:

Mat destination = new Mat();
Mat matGray=new Mat();  

Imgproc.cvtColor(image, matGray, Imgproc.COLOR_BGR2GRAY);          
Imgproc.Laplacian(matGray, destination, 3); 
MatOfDouble median = new MatOfDouble();
MatOfDouble std= new MatOfDouble();        
Core.meanStdDev(destination, median , std);

Math.pow(std.get(0,0)[0],2);

Гораздо проще и с такими же результатами, как Python.

Я не нашел никакой прямой функции для вычисления дисперсии изображения в OpenCV. Но я нашел кое-что, чтобы вычислить среднее стандартное отклонение. А из математики дисперсия - это просто квадрат среднего стандартного отклонения.

Вот как я вычисляю среднее стандартное отклонение изображения

Mat im = Imgcodecs.imread("relative/path/to/file");
Imgproc.cvtColor(im, im, Imgproc.COLOR_BGR2GRAY);
MatOfDouble mu = new MatOfDouble(); // mean
MatOfDouble sigma = new MatOfDouble(); // standard deviation
Core.meanStdDev(d, mu, sigma);
double variance = Math.pow(mu.get(0,0)[0], 2);

Я запустил это на приблизительно 37 JPG, которые я конвертировал из RAW (каждый около 8 МБ), и он работал, хотя и медленно. Я попытался сделать это для своих 340 фотографий, и мой ноутбук выключился. Должны быть способы оптимизировать это.

Другие вопросы по тегам