Soporte comercial:
JavaCV utiliza contenedores de los ajustes preestablecidos de JavaCPP de bibliotecas comúnmente utilizadas por investigadores en el campo de la visión por computadora (OpenCV, FFmpeg, libdc1394, FlyCapture, Spinnaker, OpenKinect, librealsense, CL PS3 Eye Driver, videoInput, ARToolKitPlus, flandmark, Leptonica y Tesseract). y proporciona clases de utilidad para hacer que su funcionalidad sea más fácil de usar en la plataforma Java, incluido Android.
JavaCV también viene con visualización de imágenes en pantalla completa acelerada por hardware ( CanvasFrame
y GLCanvasFrame
), métodos fáciles de usar para ejecutar código en paralelo en múltiples núcleos ( Parallel
), calibración geométrica y de color fácil de usar de cámaras y proyectores ( GeometricCalibrator
, ProCamGeometricCalibrator
, ProCamColorCalibrator
), detección y coincidencia de puntos característicos ( ObjectFinder
), un conjunto de clases que implementan la alineación directa de imágenes de sistemas de proyector-cámara (principalmente GNImageAligner
, ProjectiveTransformer
, ProjectiveColorTransformer
, ProCamTransformer
y ReflectanceInitializer
), un paquete de análisis de blobs ( Blobs
), así como funcionalidades diversas en la clase JavaCV
. Algunas de estas clases también tienen una contraparte OpenCL y OpenGL, cuyos nombres terminan en CL
o comienzan con GL
, es decir: JavaCVCL
, GLCanvasFrame
, etc.
Para aprender a usar la API, ya que actualmente falta documentación, consulte la sección Uso de muestra a continuación, así como los programas de muestra, incluidos dos para Android ( FacePreview.java
y RecordActivity.java
), que también se encuentran en el directorio samples
. También puede resultarle útil consultar el código fuente de ProCamCalib y ProCamTracker, así como ejemplos transferidos del OpenCV2 Cookbook y las páginas wiki asociadas.
Mantenme informado sobre cualquier actualización o corrección que realices en el código para que pueda integrarlas en la próxima versión. ¡Gracias! ¡Y no dude en hacer preguntas en la lista de correo o en el foro de discusión si encuentra algún problema con el software! Estoy seguro de que está lejos de ser perfecto...
Los archivos que contienen archivos JAR están disponibles como versiones. El archivo binario contiene compilaciones para Android, iOS, Linux, Mac OS X y Windows. Los archivos JAR para plataformas o módulos secundarios específicos también se pueden obtener individualmente desde el Repositorio Central de Maven.
Para instalar manualmente los archivos JAR, siga las instrucciones de la sección Instalación manual a continuación.
También podremos tener todo descargado e instalado automáticamente con:
pom.xml
) < dependency >
< groupId >org.bytedeco</ groupId >
< artifactId >javacv-platform</ artifactId >
< version >1.5.11</ version >
</ dependency >
build.gradle.kts
o build.gradle
) dependencies {
implementation( " org.bytedeco:javacv-platform:1.5.11 " )
}
project.clj
) :dependencies [
[org.bytedeco/javacv-platform " 1.5.11 " ]
]
build.sbt
) libraryDependencies += " org.bytedeco " % " javacv-platform " % " 1.5.11 "
Esto descarga archivos binarios para todas las plataformas, pero para obtener archivos binarios solo para una plataforma, podemos configurar la propiedad del sistema javacpp.platform
(a través de la opción de línea de comando -D
) en algo como android-arm
, linux-x86_64
, macosx-x86_64
, windows-x86_64
, etc. Consulte el archivo README.md de los ajustes preestablecidos de JavaCPP para obtener más detalles. Otra opción disponible para los usuarios de Gradle es Gradle JavaCPP y, de manera similar, para los usuarios de Scala existe SBT-JavaCV.
Para utilizar JavaCV, primero deberá descargar e instalar el siguiente software:
Además, aunque no siempre es necesario, algunas funciones de JavaCV también dependen de:
Finalmente, asegúrese de que todo tenga el mismo bitness: los módulos de 32 bits y 64 bits no se mezclan bajo ninguna circunstancia .
Simplemente coloque todos los archivos JAR deseados ( opencv*.jar
, ffmpeg*.jar
, etc.), además de javacpp.jar
y javacv.jar
, en algún lugar de su classpath. Aquí hay algunas instrucciones más específicas para casos comunes:
NetBeans (Java SE 7 o posterior):
Eclipse (Java SE 7 o posterior):
Código de Visual Studio (Java SE 7 o posterior):
+
.IntelliJ IDEA (Android 7.0 o posterior):
app/libs
.+
y seleccione "2 Dependencia de archivo".libs
.android:extractNativeLibs="true"
Después de eso, las clases contenedoras para OpenCV y FFmpeg, por ejemplo, pueden acceder automáticamente a todas sus API C/C++:
Las definiciones de clases son básicamente puertos a Java de los archivos de encabezado originales en C/C++, y deliberadamente decidí mantener la mayor cantidad posible de sintaxis original. Por ejemplo, aquí hay un método que intenta cargar un archivo de imagen, suavizarlo y guardarlo nuevamente en el disco:
import org . bytedeco . opencv . opencv_core .*;
import org . bytedeco . opencv . opencv_imgproc .*;
import static org . bytedeco . opencv . global . opencv_core .*;
import static org . bytedeco . opencv . global . opencv_imgproc .*;
import static org . bytedeco . opencv . global . opencv_imgcodecs .*;
public class Smoother {
public static void smooth ( String filename ) {
Mat image = imread ( filename );
if ( image != null ) {
GaussianBlur ( image , image , new Size ( 3 , 3 ), 0 );
imwrite ( filename , image );
}
}
}
JavaCV también viene con clases y métodos auxiliares además de OpenCV y FFmpeg para facilitar su integración a la plataforma Java. Aquí hay un pequeño programa de demostración que muestra las partes más útiles:
import java . io . File ;
import java . net . URL ;
import org . bytedeco . javacv .*;
import org . bytedeco . javacpp .*;
import org . bytedeco . javacpp . indexer .*;
import org . bytedeco . opencv . opencv_core .*;
import org . bytedeco . opencv . opencv_imgproc .*;
import org . bytedeco . opencv . opencv_calib3d .*;
import org . bytedeco . opencv . opencv_objdetect .*;
import static org . bytedeco . opencv . global . opencv_core .*;
import static org . bytedeco . opencv . global . opencv_imgproc .*;
import static org . bytedeco . opencv . global . opencv_calib3d .*;
import static org . bytedeco . opencv . global . opencv_objdetect .*;
public class Demo {
public static void main ( String [] args ) throws Exception {
String classifierName = null ;
if ( args . length > 0 ) {
classifierName = args [ 0 ];
} else {
URL url = new URL ( "https://raw.github.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_alt.xml" );
File file = Loader . cacheResource ( url );
classifierName = file . getAbsolutePath ();
}
// We can "cast" Pointer objects by instantiating a new object of the desired class.
CascadeClassifier classifier = new CascadeClassifier ( classifierName );
if ( classifier == null ) {
System . err . println ( "Error loading classifier file " " + classifierName + " " ." );
System . exit ( 1 );
}
// The available FrameGrabber classes include OpenCVFrameGrabber (opencv_videoio),
// DC1394FrameGrabber, FlyCapture2FrameGrabber, OpenKinectFrameGrabber, OpenKinect2FrameGrabber,
// RealSenseFrameGrabber, RealSense2FrameGrabber, PS3EyeFrameGrabber, VideoInputFrameGrabber, and FFmpegFrameGrabber.
FrameGrabber grabber = FrameGrabber . createDefault ( 0 );
grabber . start ();
// CanvasFrame, FrameGrabber, and FrameRecorder use Frame objects to communicate image data.
// We need a FrameConverter to interface with other APIs (Android, Java 2D, JavaFX, Tesseract, OpenCV, etc).
OpenCVFrameConverter . ToMat converter = new OpenCVFrameConverter . ToMat ();
// FAQ about IplImage and Mat objects from OpenCV:
// - For custom raw processing of data, createBuffer() returns an NIO direct
// buffer wrapped around the memory pointed by imageData, and under Android we can
// also use that Buffer with Bitmap.copyPixelsFromBuffer() and copyPixelsToBuffer().
// - To get a BufferedImage from an IplImage, or vice versa, we can chain calls to
// Java2DFrameConverter and OpenCVFrameConverter, one after the other.
// - Java2DFrameConverter also has static copy() methods that we can use to transfer
// data more directly between BufferedImage and IplImage or Mat via Frame objects.
Mat grabbedImage = converter . convert ( grabber . grab ());
int height = grabbedImage . rows ();
int width = grabbedImage . cols ();
// Objects allocated with `new`, clone(), or a create*() factory method are automatically released
// by the garbage collector, but may still be explicitly released by calling deallocate().
// You shall NOT call cvReleaseImage(), cvReleaseMemStorage(), etc. on objects allocated this way.
Mat grayImage = new Mat ( height , width , CV_8UC1 );
Mat rotatedImage = grabbedImage . clone ();
// The OpenCVFrameRecorder class simply uses the VideoWriter of opencv_videoio,
// but FFmpegFrameRecorder also exists as a more versatile alternative.
FrameRecorder recorder = FrameRecorder . createDefault ( "output.avi" , width , height );
recorder . start ();
// CanvasFrame is a JFrame containing a Canvas component, which is hardware accelerated.
// It can also switch into full-screen mode when called with a screenNumber.
// We should also specify the relative monitor/camera response for proper gamma correction.
CanvasFrame frame = new CanvasFrame ( "Some Title" , CanvasFrame . getDefaultGamma ()/ grabber . getGamma ());
// Let's create some random 3D rotation...
Mat randomR = new Mat ( 3 , 3 , CV_64FC1 ),
randomAxis = new Mat ( 3 , 1 , CV_64FC1 );
// We can easily and efficiently access the elements of matrices and images
// through an Indexer object with the set of get() and put() methods.
DoubleIndexer Ridx = randomR . createIndexer (),
axisIdx = randomAxis . createIndexer ();
axisIdx . put ( 0 , ( Math . random () - 0.5 ) / 4 ,
( Math . random () - 0.5 ) / 4 ,
( Math . random () - 0.5 ) / 4 );
Rodrigues ( randomAxis , randomR );
double f = ( width + height ) / 2.0 ; Ridx . put ( 0 , 2 , Ridx . get ( 0 , 2 ) * f );
Ridx . put ( 1 , 2 , Ridx . get ( 1 , 2 ) * f );
Ridx . put ( 2 , 0 , Ridx . get ( 2 , 0 ) / f ); Ridx . put ( 2 , 1 , Ridx . get ( 2 , 1 ) / f );
System . out . println ( Ridx );
// We can allocate native arrays using constructors taking an integer as argument.
Point hatPoints = new Point ( 3 );
while ( frame . isVisible () && ( grabbedImage = converter . convert ( grabber . grab ())) != null ) {
// Let's try to detect some faces! but we need a grayscale image...
cvtColor ( grabbedImage , grayImage , CV_BGR2GRAY );
RectVector faces = new RectVector ();
classifier . detectMultiScale ( grayImage , faces );
long total = faces . size ();
for ( long i = 0 ; i < total ; i ++) {
Rect r = faces . get ( i );
int x = r . x (), y = r . y (), w = r . width (), h = r . height ();
rectangle ( grabbedImage , new Point ( x , y ), new Point ( x + w , y + h ), Scalar . RED , 1 , CV_AA , 0 );
// To access or pass as argument the elements of a native array, call position() before.
hatPoints . position ( 0 ). x ( x - w / 10 ). y ( y - h / 10 );
hatPoints . position ( 1 ). x ( x + w * 11 / 10 ). y ( y - h / 10 );
hatPoints . position ( 2 ). x ( x + w / 2 ). y ( y - h / 2 );
fillConvexPoly ( grabbedImage , hatPoints . position ( 0 ), 3 , Scalar . GREEN , CV_AA , 0 );
}
// Let's find some contours! but first some thresholding...
threshold ( grayImage , grayImage , 64 , 255 , CV_THRESH_BINARY );
// To check if an output argument is null we may call either isNull() or equals(null).
MatVector contours = new MatVector ();
findContours ( grayImage , contours , CV_RETR_LIST , CV_CHAIN_APPROX_SIMPLE );
long n = contours . size ();
for ( long i = 0 ; i < n ; i ++) {
Mat contour = contours . get ( i );
Mat points = new Mat ();
approxPolyDP ( contour , points , arcLength ( contour , true ) * 0.02 , true );
drawContours ( grabbedImage , new MatVector ( points ), - 1 , Scalar . BLUE );
}
warpPerspective ( grabbedImage , rotatedImage , randomR , rotatedImage . size ());
Frame rotatedFrame = converter . convert ( rotatedImage );
frame . showImage ( rotatedFrame );
recorder . record ( rotatedFrame );
}
frame . dispose ();
recorder . stop ();
grabber . stop ();
}
}
Además, después de crear un archivo pom.xml
con el siguiente contenido:
< project >
< modelVersion >4.0.0</ modelVersion >
< groupId >org.bytedeco.javacv</ groupId >
< artifactId >demo</ artifactId >
< version >1.5.11</ version >
< properties >
< maven .compiler.source>1.7</ maven .compiler.source>
< maven .compiler.target>1.7</ maven .compiler.target>
</ properties >
< dependencies >
< dependency >
< groupId >org.bytedeco</ groupId >
< artifactId >javacv-platform</ artifactId >
< version >1.5.11</ version >
</ dependency >
<!-- Additional dependencies required to use CUDA and cuDNN -->
< dependency >
< groupId >org.bytedeco</ groupId >
< artifactId >opencv-platform-gpu</ artifactId >
< version >4.10.0-1.5.11</ version >
</ dependency >
<!-- Optional GPL builds with (almost) everything enabled -->
< dependency >
< groupId >org.bytedeco</ groupId >
< artifactId >ffmpeg-platform-gpl</ artifactId >
< version >7.1-1.5.11</ version >
</ dependency >
</ dependencies >
< build >
< sourceDirectory >.</ sourceDirectory >
</ build >
</ project >
Y al colocar el código fuente anterior en Demo.java
, o de manera similar para otras clases que se encuentran en los samples
, podemos usar el siguiente comando para que todo primero se instale automáticamente y luego Maven lo ejecute:
$ mvn compile exec:java -Dexec.mainClass=Demo
Nota : En caso de errores, asegúrese de que el artifactId
en el archivo pom.xml
diga javacv-platform
, no solo javacv
, por ejemplo. El artefacto javacv-platform
agrega todas las dependencias binarias necesarias.
Si los archivos binarios disponibles anteriormente no son suficientes para sus necesidades, es posible que deba reconstruirlos a partir del código fuente. Para ello se crearon los archivos de proyecto para:
Una vez instalado, simplemente llame al comando mvn install
habitual para JavaCPP, sus ajustes preestablecidos y JavaCV. De forma predeterminada, no se requieren otras dependencias que un compilador de C++ para JavaCPP. Consulte los comentarios dentro de los archivos pom.xml
para obtener más detalles.
En lugar de crear las bibliotecas nativas manualmente, podemos ejecutar mvn install
solo para JavaCV y confiar en los artefactos instantáneos de las compilaciones de CI:
Líder del proyecto: Samuel Audet samuel.audet at
gmail.com
Sitio del desarrollador: https://github.com/bytedeco/javacv
Grupo de discusión: http://groups.google.com/group/javacv