Kommerzielle Unterstützung:
JavaCV verwendet Wrapper aus den JavaCPP-Voreinstellungen häufig verwendeter Bibliotheken von Forschern im Bereich Computer Vision (OpenCV, FFmpeg, libdc1394, FlyCapture, Spinnaker, OpenKinect, librealsense, CL PS3 Eye Driver, videoInput, ARToolKitPlus, flandmark, Leptonica und Tesseract). und stellt Dienstprogrammklassen bereit, um die Verwendung ihrer Funktionalität auf der Java-Plattform, einschließlich Android, zu vereinfachen.
JavaCV verfügt außerdem über eine hardwarebeschleunigte Vollbild-Bildanzeige ( CanvasFrame
und GLCanvasFrame
), benutzerfreundliche Methoden zum parallelen Ausführen von Code auf mehreren Kernen ( Parallel
) und eine benutzerfreundliche geometrische und Farbkalibrierung von Kameras und Projektoren ( GeometricCalibrator
, ProCamGeometricCalibrator
. , ProCamColorCalibrator
), Erkennung und Abgleich von Merkmalspunkten ( ObjectFinder
), eine Reihe von Klassen, die die direkte Bildausrichtung von Projektor-Kamera-Systemen implementieren (hauptsächlich GNImageAligner
, ProjectiveTransformer
, ProjectiveColorTransformer
, ProCamTransformer
und ReflectanceInitializer
), ein Blob-Analysepaket ( Blobs
) sowie verschiedene Funktionen in der JavaCV
Klasse. Einige dieser Klassen haben auch ein OpenCL- und OpenGL-Gegenstück, deren Namen mit CL
enden oder mit GL
beginnen, z. B. JavaCVCL
, GLCanvasFrame
usw.
Um zu erfahren, wie Sie die API verwenden, lesen Sie sich bitte den unten stehenden Abschnitt „Beispielnutzung“ durch, da es derzeit keine Dokumentation gibt, sowie die Beispielprogramme, darunter zwei für Android ( FacePreview.java
und RecordActivity.java
), die sich ebenfalls im samples
befinden. Möglicherweise finden Sie es auch hilfreich, auf den Quellcode von ProCamCalib und ProCamTracker sowie auf Beispiele aus dem OpenCV2 Cookbook und den zugehörigen Wiki-Seiten zu verweisen.
Bitte halten Sie mich über alle Aktualisierungen oder Korrekturen, die Sie am Code vornehmen, auf dem Laufenden, damit ich diese in die nächste Version integrieren kann. Danke schön! Und wenn Sie Probleme mit der Software haben, können Sie gerne Fragen über die Mailingliste oder das Diskussionsforum stellen! Ich bin mir sicher, dass es alles andere als perfekt ist ...
Archive mit JAR-Dateien sind als Releases verfügbar. Das Binärarchiv enthält Builds für Android, iOS, Linux, Mac OS X und Windows. Die JAR-Dateien für bestimmte untergeordnete Module oder Plattformen können auch einzeln aus dem Maven Central Repository bezogen werden.
Um die JAR-Dateien manuell zu installieren, befolgen Sie die Anweisungen im Abschnitt „Manuelle Installation“ unten.
Wir können auch alles automatisch herunterladen und installieren lassen mit:
pom.xml
Datei) < dependency >
< groupId >org.bytedeco</ groupId >
< artifactId >javacv-platform</ artifactId >
< version >1.5.11</ version >
</ dependency >
build.gradle.kts
oder build.gradle
) dependencies {
implementation( " org.bytedeco:javacv-platform:1.5.11 " )
}
project.clj
Datei) :dependencies [
[org.bytedeco/javacv-platform " 1.5.11 " ]
]
build.sbt
) libraryDependencies += " org.bytedeco " % " javacv-platform " % " 1.5.11 "
Dies lädt Binärdateien für alle Plattformen herunter, aber um Binärdateien nur für eine Plattform zu erhalten, können wir die Systemeigenschaft javacpp.platform
(über die Befehlszeilenoption -D
) auf etwas wie android-arm
, linux-x86_64
, macosx-x86_64
, windows-x86_64
festlegen. windows-x86_64
usw. Weitere Informationen finden Sie in der Datei README.md der JavaCPP-Voreinstellungen. Eine weitere für Gradle-Benutzer verfügbare Option ist Gradle JavaCPP, und für Scala-Benutzer gibt es ebenfalls SBT-JavaCV.
Um JavaCV verwenden zu können, müssen Sie zunächst die folgende Software herunterladen und installieren:
Darüber hinaus basieren einige Funktionen von JavaCV, auch wenn dies nicht immer erforderlich ist, auf Folgendem:
Bitte stellen Sie abschließend sicher, dass alles die gleiche Bitanzahl hat: 32-Bit- und 64-Bit-Module dürfen auf keinen Fall gemischt werden .
Legen Sie einfach alle gewünschten JAR-Dateien ( opencv*.jar
, ffmpeg*.jar
usw.) zusätzlich zu javacpp.jar
und javacv.jar
irgendwo in Ihrem Klassenpfad ab. Hier sind einige spezifischere Anweisungen für häufige Fälle:
NetBeans (Java SE 7 oder neuer):
Eclipse (Java SE 7 oder neuer):
Visual Studio Code (Java SE 7 oder neuer):
+
.IntelliJ IDEA (Android 7.0 oder neuer):
app/libs
.+
und wählen Sie „2 Dateiabhängigkeiten“.libs
aus.android:extractNativeLibs="true"
hinzu.Danach können beispielsweise die Wrapper-Klassen für OpenCV und FFmpeg automatisch auf alle ihre C/C++-APIs zugreifen:
Bei den Klassendefinitionen handelt es sich im Wesentlichen um Portierungen der ursprünglichen Header-Dateien in C/C++ nach Java, und ich habe mich bewusst dafür entschieden, so viel wie möglich von der ursprünglichen Syntax beizubehalten. Hier ist beispielsweise eine Methode, die versucht, eine Bilddatei zu laden, sie zu glätten und wieder auf der Festplatte zu speichern:
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 verfügt außerdem über Hilfsklassen und -methoden zusätzlich zu OpenCV und FFmpeg, um deren Integration in die Java-Plattform zu erleichtern. Hier ist ein kleines Demoprogramm, das die am häufigsten nützlichen Teile demonstriert:
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 ();
}
}
Darüber hinaus wird nach dem Erstellen eine pom.xml
Datei mit folgendem Inhalt erstellt:
< 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 >
Und indem wir den obigen Quellcode in Demo.java
oder ähnlich für andere in den samples
gefundene Klassen platzieren, können wir den folgenden Befehl verwenden, um alles zuerst automatisch zu installieren und dann von Maven auszuführen:
$ mvn compile exec:java -Dexec.mainClass=Demo
Hinweis : Stellen Sie im Fehlerfall sicher, dass die artifactId
in der Datei pom.xml
javacv-platform
und nicht beispielsweise nur javacv
lautet. Das Artefakt javacv-platform
fügt alle notwendigen binären Abhängigkeiten hinzu.
Wenn die oben verfügbaren Binärdateien für Ihre Anforderungen nicht ausreichen, müssen Sie sie möglicherweise aus dem Quellcode neu erstellen. Zu diesem Zweck wurden die Projektdateien erstellt für:
Nach der Installation rufen Sie einfach den üblichen mvn install
für JavaCPP, seine Voreinstellungen und JavaCV auf. Standardmäßig sind keine weiteren Abhängigkeiten als ein C++-Compiler für JavaCPP erforderlich. Weitere Einzelheiten finden Sie in den Kommentaren in den pom.xml
Dateien.
Anstatt die nativen Bibliotheken manuell zu erstellen, können wir mvn install
nur für JavaCV ausführen und uns auf die Snapshot-Artefakte aus den CI-Builds verlassen:
Projektleitung: Samuel Audet samuel.audet at
gmail.com
Entwicklerseite: https://github.com/bytedeco/javacv
Diskussionsgruppe: http://groups.google.com/group/javacv