JavaCV-学习笔记一

http://blog.csdn.net/kerr1992/article/details/8782778

介绍

JavaCV首先提供了计算机视觉领域研究人员常用的函数库的封装: OpenCVFFmpeglibdc1394PGRFlyCaptureOpenKinectvideoInput, 和 ARToolKitPlus

可以在com.googlecode.javacv.cpp包命名空间中找到的类,暴露了它们完整的API。此外,utility类使得它们的功能更易于在包括android在内的Java平台上使用。

JavaCV还带有硬件加速的全屏幕图像显示(CanvasFrame和 GLCanvasFrame),易于在多个内核中执行并行代码(并行),用户友好的几何和色彩的相机和投影仪校准(GeometricCalibrator, ProCamGeometricCalibrator, ProCamColorCalibrator),特征点的检测和匹配(ObjectFinder),一组实现相机投影仪系统直接图像校准的类(主要有GNImageAligner, ProjectiveTransformer, ProjectiveColorTransformer, ProCamTransformer,和 ReflectanceInitializer),一个blob分析软件包(Blobs),以及JavaCV类中的其它功能。这些类也有一个OpenCLOpenGL的对应副本,它们的名字以CL结尾或者以GL开头,例如JavaCVCL、GLCanvasFrame等等。


由于目前缺少学习如何使用这些API的文档,请参阅下面的#OpenCV和FFmpeg快速入门Quick Start for OpenCV and FFmpeg)部分以及示例程序,包括两个Android程序(FacePreview.javaRecordActivity.java),也可以在示例目录里找到。你可能会发现,参考ProCamCalibProCamTracker的源代码以及从OpenCV2Cookbook书上移植的例子、相关维基页面是很有用的。

所需软件

要使用JavaCV,你将需要下载并安装以下软件:

  • 执行的Java SE 6或7
    • OpenJDK http://openjdk.java.net/install/
    • Sun JDK http://www.oracle.com/technetwork/java/javase/downloads/
    • IBM JDK http://www.ibm.com/developerworks/java/jdk/
    • Java SE for Mac OS X http://developer.apple.com/java/ 等
  • OpenCV 2.4.5 http://sourceforge.net/projects/opencvlibrary/files/
    • 针对Linux, Mac OS X, Windows, and Android预编译和打包好的CPPJAR:
      • http://code.google.com/p/javacv/downloads/list

同时请确保你的Java和OpenCV具有相同的位数: 32位和64位的组件在任何情况下不要混用。另外,尽管并非总是必要的,一些JavaCV的功能还依赖于::

  • FFmpeg 1.2.x http://ffmpeg.org/download.html
  • libdc1394 2.1.x 或 2.2.x http://sourceforge.net/projects/libdc1394/files/
  • PGR FlyCapture 1.7~2.3 (仅Windows平台) http://www.ptgrey.com/products/pgrflycapture/
  • OpenKinect http://openkinect.org/
  • CL Eye Platform SDK (仅Windows平台) http://codelaboratories.com/downloads/
  • Android SDK API 8 或更高版本 http://developer.android.com/sdk/
  • 来自JogAmp的组件JOCL和JOGL http://jogamp.org/
  • ARToolKitPlus 2.1.1t http://code.google.com/p/javacv/downloads/list

要修改源代码,请注意这些已被创建的项目文件:

  • Maven 2 或 3 http://maven.apache.org/download.html
  • JavaCPP 0.5 http://code.google.com/p/javacpp/

要重建的话,只需调用为JavaCPP和JavaCV准备的常用mvn install命令。 默认情况下,所有上面列出的所依赖的东西并不需要,除为了OpenCV和构建JavaCPP的C++编译器(命令行选项可以通过javacpp.options传递,Maven的特性,如那些Android平台需要的)。进一步详情,请参阅pom.xml文件中的注释。

请告诉我你对代码做的更新或修正,让我可以将它们集成到下一版本中。 谢谢!如果您使用软件时遇到任何问题,欢迎在邮件列表页随时提问!我相信它还远远不够完善......

OpenCV和FFmpeg的快速入门

首先,把JavaCVjavacpp.jarjavacv.jarjavacv-*.jar ),OpenCVOpenCV- 2.4.5*.jar ),FFmpeg( ffmpeg-1.2*.jar所有JAR文件路径加到CLASSPATH中。 或把你的pom.xml文件指向Maven仓库http://maven2.javacv.googlecode.com/git/ ,并确保FFmpeg和OpenCV的库文件*.so*.dylib ,或*.dll )可以在无论是他们的默认安装目录还是系统库的路径PATH中找到,在Windows中也包括当前的工作目录。 (获取在Windows平台上经常遇到的与OpenCV相关的问题答案,请参阅在Windows 7中OpenCV的常见问题)。这里是在通常情况下一些更具体的说明:

NetBeans(Java SE的6或7):

  1. 在“项目”窗口中,右键单击您的项目的“库”,然后选择“添加JAR /文件夹...”。
  2. 找到JAR文件,选择它们,然后单击“确定”。

Eclipse(JavaSE 6或7):

  1. 导航项目>属性> Java创建路径>库,然后单击“添加外部JAR...”。
  2. 找到JAR文件,选择它们,然后单击“确定”。

Eclipse(Android2.2或更高版本):

  1. 按照此页面上的指示: http://developer.android.com/training/basics/firstapp/
  2. 转到文件>新建>文件夹,选择你项目的父文件​​夹,输入“libs/armeabi”作为文件夹名,然后单击“完成”。
  3. 复制javacpp.jarjavacv.jar到新创建的“libs”文件夹。
  4. javacv-android-arm.jar,opencv-2.4.5-android-arm.jar和 ffmpeg-1.2-android-arm.jar中的所有*.so文件直接解压到新创建的“libs/armeabi”文件夹,在JAR文件中没有任何创建的子目录。
  5. 导航项目>属性> Java创建路径>“库”,然后单击“添加JAR文件...”。
  6. 从新创建的“libs”文件夹中选择javacpp.jarjavacv.jar

在那之后,OpenCV和FFmpeg的封装类可以自动访问它们的C/C++ API:

  • OpenCV的文档
  • FFmpeg的文档

类的定义基本是在C原始头文件中的Java端口,加上缺少的功能,只能通过暴露的OpenCV的C++ API,我特意决定保持尽可能多的原始语法。例如,这是一个试图加载图像文件,平滑处理后保存到磁盘的方法:

[java]  view plain copy
  1. import static com.googlecode.javacv.cpp.opencv_core.*;  
  2. import static com.googlecode.javacv.cpp.opencv_imgproc.*;  
  3. import static com.googlecode.javacv.cpp.opencv_highgui.*;  
  4.   
  5. public class Smoother {  
  6.     public static void smooth(String filename) {   
  7.         IplImage image = cvLoadImage(filename);  
  8.         if (image != null) {  
  9.             cvSmooth(image, image, CV_GAUSSIAN, 3);  
  10.             cvSaveImage(filename, image);  
  11.             cvReleaseImage(image);  
  12.         }  
  13.     }  
  14. }  

JavaCV还带有建立在OpenCV和FFmpeg之上的辅助类和方法,以方便把他们集成到Java平台。 这里是一个小演示程序来演示最常见的有用部分:

[java]  view plain copy
  1. import java.io.File;  
  2. import java.net.URL;  
  3. import com.googlecode.javacpp.Loader;  
  4. import com.googlecode.javacv.*;  
  5. import com.googlecode.javacv.cpp.*;  
  6. import static com.googlecode.javacv.cpp.opencv_core.*;  
  7. import static com.googlecode.javacv.cpp.opencv_imgproc.*;  
  8. import static com.googlecode.javacv.cpp.opencv_calib3d.*;  
  9. import static com.googlecode.javacv.cpp.opencv_objdetect.*;  
  10.   
  11. public class Demo {  
  12.     public static void main(String[] args) throws Exception {  
  13.         String classifierName = null;  
  14.         if (args.length > 0) {  
  15.             classifierName = args[0];  
  16.         } else {  
  17.             URL url = new URL("https://raw.github.com/Itseez/opencv/master/data/haarcascades/haarcascade_frontalface_alt.xml");  
  18.             File file = Loader.extractResource(url, null"classifier"".xml");  
  19.             file.deleteOnExit();  
  20.             classifierName = file.getAbsolutePath();  
  21.         }  
  22.   
  23.         // Preload the opencv_objdetect module to work around a known bug.  
  24.         Loader.load(opencv_objdetect.class);  
  25.   
  26.         // We can "cast" Pointer objects by instantiating a new object of the desired class.  
  27.         CvHaarClassifierCascade classifier = new CvHaarClassifierCascade(cvLoad(classifierName));  
  28.         if (classifier.isNull()) {  
  29.             System.err.println("Error loading classifier file \"" + classifierName + "\".");  
  30.             System.exit(1);  
  31.         }  
  32.   
  33.         // The available FrameGrabber classes include OpenCVFrameGrabber (opencv_highgui),  
  34.         // DC1394FrameGrabber, FlyCaptureFrameGrabber, OpenKinectFrameGrabber,  
  35.         // PS3EyeFrameGrabber, VideoInputFrameGrabber, and FFmpegFrameGrabber.  
  36.         FrameGrabber grabber = FrameGrabber.createDefault(0);  
  37.         grabber.start();  
  38.   
  39.         // FAQ about IplImage:  
  40.         // - For custom raw processing of data, getByteBuffer() returns an NIO direct  
  41.         //   buffer wrapped around the memory pointed by imageData, and under Android we can  
  42.         //   also use that Buffer with Bitmap.copyPixelsFromBuffer() and copyPixelsToBuffer().  
  43.         // - To get a BufferedImage from an IplImage, we may call getBufferedImage().  
  44.         // - The createFrom() factory method can construct an IplImage from a BufferedImage.  
  45.         // - There are also a few copy*() methods for BufferedImage<->IplImage data transfers.  
  46.         IplImage grabbedImage = grabber.grab();  
  47.         int width  = grabbedImage.width();  
  48.         int height = grabbedImage.height();  
  49.         IplImage grayImage    = IplImage.create(width, height, IPL_DEPTH_8U, 1);  
  50.         IplImage rotatedImage = grabbedImage.clone();  
  51.   
  52.         // Objects allocated with a create*() or clone() factory method are automatically released  
  53.         // by the garbage collector, but may still be explicitly released by calling release().  
  54.         // You shall NOT call cvReleaseImage(), cvReleaseMemStorage(), etc. on objects allocated this way.  
  55.         CvMemStorage storage = CvMemStorage.create();  
  56.   
  57.         // The OpenCVFrameRecorder class simply uses the CvVideoWriter of opencv_highgui,  
  58.         // but FFmpegFrameRecorder also exists as a more versatile alternative.  
  59.         FrameRecorder recorder = FrameRecorder.createDefault("output.avi", width, height);  
  60.         recorder.start();  
  61.   
  62.         // CanvasFrame is a JFrame containing a Canvas component, which is hardware accelerated.  
  63.         // It can also switch into full-screen mode when called with a screenNumber.  
  64.         // We should also specify the relative monitor/camera response for proper gamma correction.  
  65.         CanvasFrame frame = new CanvasFrame("Some Title", CanvasFrame.getDefaultGamma()/grabber.getGamma());  
  66.   
  67.         // Let's create some random 3D rotation...  
  68.         CvMat randomR = CvMat.create(33), randomAxis = CvMat.create(31);  
  69.         // We can easily and efficiently access the elements of CvMat objects  
  70.         // with the set of get() and put() methods.  
  71.         randomAxis.put((Math.random()-0.5)/4, (Math.random()-0.5)/4, (Math.random()-0.5)/4);  
  72.         cvRodrigues2(randomAxis, randomR, null);  
  73.         double f = (width + height)/2.0;        randomR.put(02, randomR.get(02)*f);  
  74.                                                 randomR.put(12, randomR.get(12)*f);  
  75.         randomR.put(20, randomR.get(20)/f); randomR.put(21, randomR.get(21)/f);  
  76.         System.out.println(randomR);  
  77.   
  78.         // We can allocate native arrays using constructors taking an integer as argument.  
  79.         CvPoint hatPoints = new CvPoint(3);  
  80.   
  81.         while (frame.isVisible() && (grabbedImage = grabber.grab()) != null) {  
  82.             cvClearMemStorage(storage);  
  83.   
  84.             // Let's try to detect some faces! but we need a grayscale image...  
  85.             cvCvtColor(grabbedImage, grayImage, CV_BGR2GRAY);  
  86.             CvSeq faces = cvHaarDetectObjects(grayImage, classifier, storage,  
  87.                     1.13, CV_HAAR_DO_CANNY_PRUNING);  
  88.             int total = faces.total();  
  89.             for (int i = 0; i < total; i++) {  
  90.                 CvRect r = new CvRect(cvGetSeqElem(faces, i));  
  91.                 int x = r.x(), y = r.y(), w = r.width(), h = r.height();  
  92.                 cvRectangle(grabbedImage, cvPoint(x, y), cvPoint(x+w, y+h), CvScalar.RED, 1, CV_AA, 0);  
  93.   
  94.                 // To access or pass as argument the elements of a native array, call position() before.  
  95.                 hatPoints.position(0).x(x-w/10)   .y(y-h/10);  
  96.                 hatPoints.position(1).x(x+w*11/10).y(y-h/10);  
  97.                 hatPoints.position(2).x(x+w/2)    .y(y-h/2);  
  98.                 cvFillConvexPoly(grabbedImage, hatPoints.position(0), 3, CvScalar.GREEN, CV_AA, 0);  
  99.             }  
  100.   
  101.             // Let's find some contours! but first some thresholding...  
  102.             cvThreshold(grayImage, grayImage, 64255, CV_THRESH_BINARY);  
  103.   
  104.             // To check if an output argument is null we may call either isNull() or equals(null).  
  105.             CvSeq contour = new CvSeq(null);  
  106.             cvFindContours(grayImage, storage, contour, Loader.sizeof(CvContour.class),  
  107.                     CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);  
  108.             while (contour != null && !contour.isNull()) {  
  109.                 if (contour.elem_size() > 0) {  
  110.                     CvSeq points = cvApproxPoly(contour, Loader.sizeof(CvContour.class),  
  111.                             storage, CV_POLY_APPROX_DP, cvContourPerimeter(contour)*0.020);  
  112.                     cvDrawContours(grabbedImage, points, CvScalar.BLUE, CvScalar.BLUE, -11, CV_AA);  
  113.                 }  
  114.                 contour = contour.h_next();  
  115.             }  
  116.   
  117.             cvWarpPerspective(grabbedImage, rotatedImage, randomR);  
  118.   
  119.             frame.showImage(rotatedImage);  
  120.             recorder.record(rotatedImage);  
  121.         }  
  122.         frame.dispose();  
  123.         recorder.stop();  
  124.         grabber.stop();  
  125.     }  
  126. }  




你可能感兴趣的:(android)