четверг, 26 июля 2012 г.

Как работать с JavaCV (OpenCV + Netbeans)

Используемая IDE - Netbeans 7.1JavaCV - отличная обёртка (англ. - wrapper) для сишной библиотеки OpenCV.
Рассказывать что это такое - только впустую тратить время, лучше отослать на сайт разработчиков. Что нам нужно: установить библиотеку и начать с ней быстро работать.
У нас есть Windows 7 Professional и Netbeans 7.1, для которых и будет описана установка.
Первое, и самое главное, о чём стоит помнить - JavaCV как таковая не содержит средств для обработки изображений. Это всего лишь обёртка, которая, через "прослойку" (Java Native Interfase, JNI - подробнее можно почитать здесь) позволяет обращаться к функциям OpenCV, написанной на C++. Достоинством такого подхода определенно является скорость: она, конечно, заметно меньше, чем при написании программы изначально на С++, но  и не в пример выше, чем при использовании аналогичных классов в того же ImageJ.

Итак, установка JavaCV. Для того, чтобы начать работать нам нужно сделать всего пару шагов:

1. Идём на сайт JavaCV (на момент написания статьи он хостится на code.google.com), и внимательно смотрим абзац "Required Software", где написано, какая версия OpenCV поддерживается в настоящий момент. Сейчас это OpenCV 2.4.2.
Скачиваем OpenCV нужной версии. После этого необходимо открыть самораспаковывающийся архив и указать ему адекватный путь (чтобы вы потом сами могли найти его) для библиотек и примеров. Далее идём в "выбранная_папка/opencv/build/x86/vc10/bin/", копируем все .dll в папку Windows/System32. В случае использования 64-разрядной версии Windows (Пуск → ПКМ по "Компьютер" → Свойства, там глядим "Тип системы") .dll-ки надо класть в папку SysWOW64.



2. Скачиваем саму JavaCV. После распаковки архива будут доступны несколько   .jar-сборок основной библиотеки. Так как мы выбрали 32-битные библиотеки OpenCV, то и файл нам нужен соответствующий: javacv-windows-x86.jar. Также нам нужны файлы javacpp.jar  и javacv.jar. Не забудьте включить их в свой проект, иначе, естесственно, ничего не заработает.

Я бы рекомендовал создать где-нибудь под рукой папку навроде "JavaLibraries" (если у вас до сих пор такой нет), и скопировать туда во-первых всю скачанную библиотеку JavaCV, а во-вторых все .dll-ки, с которыми текущая версия работает. Вы избежите проблем в будущем, когда вам понадобится запустить вашу программку на другом компьютере, а вы не будете помнить с какой версией той или иной библиотеки она написана.


Теперь осталось лишь написать код. Ограничимся самым простым примером - откроем файл и покажем его на экране, используя только функционал JavaCV. Создадим исполняемый класс:


import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_highgui.*;

public class TestClass {
    public static void open(String filename) { 
        IplImage image = cvLoadImage(filename);
        if (image != null) {
            cvShowImage(filename, image);
            cvWaitKey();
        }
    }
 
    public static void main(String[] args) {
        open("image.jpg");
    }
}

Вот и все. Нажимаем Shift+F6 (или в диспетчере: ПКМ → Выполнить файл). Результат тут же высветится.

9 комментариев:

Анонимный комментирует...

"Я бы рекомендовал создать где-нибудь под рукой папку навроде "JavaLibraries" (если у вас до сих пор такой нет), и скопировать туда во-первых всю скачанную библиотеку JavaCV, а во-вторых все .dll-ки, с которыми текущая версия работает"
Поподробней можете объяснить какие dll файлы скопировать. И как потом запускать приложение на компьютере где openCv не установлено. Я пытался это сделать, но java машина постоянно не находит dll файлы. установка -Djava.library.path = .\lib не помогает.

Мария комментирует...

Спасибо за материал!
К сожалению, никак не могу избавиться от ошибки:

java.lang.NoClassDefFoundError: com/googlecode/javacpp/Pointer
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2442)
at java.lang.Class.getMethod0(Class.java:2685)
at java.lang.Class.getMethod(Class.java:1620)
at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:494)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:486)
Caused by: java.lang.ClassNotFoundException: com.googlecode.javacpp.Pointer
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
... 18 more
Exception in thread "main" Java Result: 1

Может, знаете, что с этим можно поделать?

Unknown комментирует...

Всем привет кто попал в эту тему, у меня были подобные проблемы, на русском ничего что решило бы проблему не нашел (проблема была в том что он у меня не находил саму библиотеку на C++) отображалось так:java.lang.UnsatisfiedLinkError: C:\Users\Why We\AppData\Local\Temp\javacpp270039669094\jniopencv_core.dll: Can't find dependent libraries
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(Unknown Source)
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.load0(Unknown Source)
at java.lang.System.load(Unknown Source)
at com.googlecode.javacpp.Loader.loadLibrary(Loader.java:418)
at com.googlecode.javacpp.Loader.load(Loader.java:368)
at com.googlecode.javacpp.Loader.load(Loader.java:315)
at com.googlecode.javacv.cpp.opencv_core.(opencv_core.java:131)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at com.googlecode.javacpp.Loader.load(Loader.java:334)
at com.googlecode.javacv.cpp.opencv_imgproc.(opencv_imgproc.java:96)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at com.googlecode.javacpp.Loader.load(Loader.java:334)
at com.googlecode.javacpp.Loader.load(Loader.java:315)
at com.googlecode.javacv.cpp.opencv_imgproc$CvMoments.(opencv_imgproc.java:381)
at com.googlecode.javacv.JavaCV.(JavaCV.java:61)
Exception in thread "main"

вот ссылка если знаете язык http://opencvlover.blogspot.ru/2012/04/javacv-setup-with-eclipse-on-windows-7.html

Решил вот так:
1)(Windows 7) мой компьютер>свойства системы(вверху если кто не знает)>дополнительные параметры системы(слева)>переменные среды(в самом низу над кнопкой "отмена")>в графе системные переменные находим переменную под именем "Path", жмем изменить, в графе "значение переменной" пишете полный путь к библиотеке OpenCV примеру: "C:\Програмирование\java\Библиотеки\opencv\build\x64\vc10\bin", если у вас 32bit, то "C:\Програмирование\java\Библиотеки\opencv\build\x86\vc10\bin",
жмете "ОК" перезагружаете компьютер, запускаете программу и вуаля! Все работает!
Но есть небольшая проблемка в том как показать именно ту картинку, я не знаю куда ее сувать или как сделать на нее ссылку, узнаю напишу.
Если есть вопросы-обращайтесь.

Дмитрий комментирует...

непонятно....
чтобы не делал все равно не работает, выкидывает ошибку "java.lang.UnsatisfiedLinkError: Can't find dependent libraries"
все стоит 64-х битное, версии javacv - 2.4.0, jar - 0.2 (не последние, но точно совместимые). в переменной path записываю "C:\opencv\build\x86\vc10\bin". Все извлек к корень диска C.

уже хз, что еще сделать

Unknown комментирует...

Дима Ничик, вы судя по всему забыли установить C++ redistributable. Это указание есть при скачивании JavaCV библиотеки, я забыл добавить его в статью. Вот они - минусы отключенного автоматического обновления Windows 7 :)
Ссылка (на 64-битный!): http://www.microsoft.com/ru-ru/download/details.aspx?id=14632

А вот 32-битный: http://www.microsoft.com/ru-ru/download/details.aspx?id=5555

Дмитрий комментирует...

Если б было так просто(
C++ redistributable у меня и был установлен. Но я все же снес и поставил заново - результат все тот же

Unknown комментирует...

Хм... А dll-ки закинули в Windows/SysWOW64?

Дмитрий комментирует...

Да, и даже пытался предварительно загрузить через System.load();
Тоже самое:(

Анонимный комментирует...

При запуске программы пишет:
Error: Could not find or load main class facedetection.FaceDetection
Java Result: 1