Dukungan komersial:
JavaCV menggunakan wrapper dari JavaCPP Presets perpustakaan yang umum digunakan oleh para peneliti di bidang computer vision (OpenCV, FFmpeg, libdc1394, FlyCapture, Spinnaker, OpenKinect, librealsense, CL PS3 Eye Driver, videoInput, ARToolKitPlus, flandmark, Leptonica, dan Tesseract) dan menyediakan kelas utilitas untuk membuat fungsinya lebih mudah digunakan pada platform Java, termasuk Android.
JavaCV juga dilengkapi dengan tampilan gambar layar penuh yang dipercepat perangkat keras ( CanvasFrame
dan GLCanvasFrame
), metode yang mudah digunakan untuk mengeksekusi kode secara paralel pada beberapa inti ( Parallel
), kalibrasi geometris dan warna kamera dan proyektor yang mudah digunakan ( GeometricCalibrator
, ProCamGeometricCalibrator
, ProCamColorCalibrator
), deteksi dan pencocokan titik fitur ( ObjectFinder
), sekumpulan kelas yang mengimplementasikan penyelarasan gambar langsung pada sistem proyektor-kamera (terutama GNImageAligner
, ProjectiveTransformer
, ProjectiveColorTransformer
, ProCamTransformer
, dan ReflectanceInitializer
), paket analisis blob ( Blobs
), serta fungsi lain-lain di kelas JavaCV
. Beberapa kelas ini juga memiliki mitra OpenCL dan OpenGL, namanya diakhiri dengan CL
atau dimulai dengan GL
, yaitu: JavaCVCL
, GLCanvasFrame
, dll.
Untuk mempelajari cara menggunakan API, karena dokumentasi saat ini kurang, silakan lihat bagian Contoh Penggunaan di bawah serta contoh program, termasuk dua untuk Android ( FacePreview.java
dan RecordActivity.java
), juga ditemukan di direktori samples
. Anda mungkin juga merasa berguna untuk merujuk pada kode sumber ProCamCalib dan ProCamTracker serta contoh-contoh yang di-porting dari OpenCV2 Cookbook dan halaman wiki terkait.
Harap terus beri tahu saya tentang pembaruan atau perbaikan apa pun yang Anda lakukan pada kode sehingga saya dapat mengintegrasikannya ke rilis berikutnya. Terima kasih! Dan jangan ragu untuk mengajukan pertanyaan di milis atau forum diskusi jika Anda mengalami masalah dengan perangkat lunak! Saya yakin ini jauh dari sempurna...
Arsip yang berisi file JAR tersedia sebagai rilis. Arsip biner berisi build untuk Android, iOS, Linux, Mac OS X, dan Windows. File JAR untuk modul atau platform anak tertentu juga dapat diperoleh secara individual dari Repositori Pusat Maven.
Untuk menginstal file JAR secara manual, ikuti petunjuk di bagian Instalasi Manual di bawah.
Kami juga dapat mengunduh dan menginstal semuanya secara otomatis dengan:
pom.xml
) < dependency >
< groupId >org.bytedeco</ groupId >
< artifactId >javacv-platform</ artifactId >
< version >1.5.11</ version >
</ dependency >
build.gradle.kts
atau 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 "
Ini mengunduh binari untuk semua platform, tetapi untuk mendapatkan binari hanya untuk satu platform kita dapat mengatur properti sistem javacpp.platform
(melalui opsi baris perintah -D
) menjadi sesuatu seperti android-arm
, linux-x86_64
, macosx-x86_64
, windows-x86_64
, dll. Silakan merujuk ke file README.md dari Preset JavaCPP untuk detailnya. Opsi lain yang tersedia untuk pengguna Gradle adalah Gradle JavaCPP, dan demikian pula untuk pengguna Scala, ada SBT-JavaCV.
Untuk menggunakan JavaCV, Anda perlu mengunduh dan menginstal perangkat lunak berikut terlebih dahulu:
Lebih lanjut, meskipun tidak selalu diperlukan, beberapa fungsi JavaCV juga bergantung pada:
Terakhir, pastikan semuanya memiliki bitness yang sama: modul 32-bit dan 64-bit tidak tercampur dalam keadaan apa pun .
Sederhananya semua file JAR yang diinginkan ( opencv*.jar
, ffmpeg*.jar
, dll.), selain javacpp.jar
dan javacv.jar
, di suatu tempat di jalur kelas Anda. Berikut adalah beberapa instruksi yang lebih spesifik untuk kasus umum:
NetBeans (Java SE 7 atau lebih baru):
Eclipse (Java SE 7 atau lebih baru):
Kode Visual Studio (Java SE 7 atau lebih baru):
+
.IntelliJ IDEA (Android 7.0 atau lebih baru):
app/libs
.+
, dan pilih "2 Ketergantungan file".libs
.android:extractNativeLibs="true"
Setelah itu, kelas wrapper untuk OpenCV dan FFmpeg, misalnya, dapat secara otomatis mengakses semua API C/C++ mereka:
Definisi kelas pada dasarnya adalah port ke Java dari file header asli di C/C++, dan saya sengaja memutuskan untuk mempertahankan sintaksis asli sebanyak mungkin. Misalnya, berikut adalah metode yang mencoba memuat file gambar, memuluskannya, dan menyimpannya kembali ke disk:
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 juga dilengkapi dengan kelas dan metode pembantu di atas OpenCV dan FFmpeg untuk memfasilitasi integrasinya ke platform Java. Berikut adalah program demo kecil yang menunjukkan bagian-bagian yang paling sering berguna:
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 ();
}
}
Selanjutnya setelah membuat file pom.xml
dengan isi sebagai berikut:
< 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 >
Dan dengan menempatkan kode sumber di atas di Demo.java
, atau serupa untuk kelas lain yang ditemukan di samples
, kita dapat menggunakan perintah berikut agar semuanya diinstal terlebih dahulu secara otomatis dan kemudian dijalankan oleh Maven:
$ mvn compile exec:java -Dexec.mainClass=Demo
Catatan : Jika terjadi kesalahan, harap pastikan bahwa artifactId
dalam file pom.xml
terbaca javacv-platform
, bukan javacv
saja, misalnya. javacv-platform
artefak menambahkan semua dependensi biner yang diperlukan.
Jika file biner yang tersedia di atas tidak cukup untuk kebutuhan Anda, Anda mungkin perlu membangunnya kembali dari kode sumber. Untuk tujuan ini, file proyek dibuat untuk:
Setelah terinstal, cukup panggil perintah mvn install
yang biasa untuk JavaCPP, Presetnya, dan JavaCV. Secara default, tidak diperlukan dependensi lain selain kompiler C++ untuk JavaCPP. Silakan merujuk ke komentar di dalam file pom.xml
untuk rincian lebih lanjut.
Daripada membangun perpustakaan asli secara manual, kita dapat menjalankan mvn install
hanya untuk JavaCV dan mengandalkan artefak snapshot dari build CI:
Pimpinan proyek: Samuel Audet samuel.audet at
gmail.com
Situs pengembang: https://github.com/bytedeco/javacv
Grup diskusi: http://groups.google.com/group/javacv