การสนับสนุนเชิงพาณิชย์:
JavaCV ใช้ wrappers จาก JavaCPP Presets ของไลบรารีที่ใช้กันทั่วไปโดยนักวิจัยในสาขาคอมพิวเตอร์วิทัศน์ (OpenCV, FFmpeg, libdc1394, FlyCapture, Spinnaker, OpenKinect, librealsense, CL PS3 Eye Driver, videoInput, ARToolKitPlus, flandmark, Leptonica และ Tesseract) และจัดเตรียมคลาสยูทิลิตี้เพื่อทำให้ฟังก์ชันการใช้งานง่ายขึ้นบนแพลตฟอร์ม Java รวมถึง Android
JavaCV ยังมาพร้อมกับการแสดงภาพเต็มหน้าจอแบบเร่งด้วยฮาร์ดแวร์ ( CanvasFrame
และ GLCanvasFrame
) วิธีการที่ใช้งานง่ายในการรันโค้ดแบบขนานบนหลายคอร์ ( Parallel
) การปรับเทียบทางเรขาคณิตและสีของกล้องและโปรเจ็กเตอร์ที่ใช้งานง่าย ( GeometricCalibrator
, ProCamGeometricCalibrator
, ProCamColorCalibrator
) การตรวจจับและการจับคู่จุดคุณสมบัติ ( ObjectFinder
) ชุดของคลาสที่ใช้การจัดตำแหน่งภาพโดยตรงของระบบกล้องโปรเจ็กเตอร์ (ส่วนใหญ่ GNImageAligner
, ProjectiveTransformer
, ProjectiveColorTransformer
, ProCamTransformer
และ ReflectanceInitializer
) แพ็คเกจการวิเคราะห์ blob ( Blobs
) รวมถึงฟังก์ชันเบ็ดเตล็ดในคลาส JavaCV
คลาสเหล่านี้บางคลาสยังมีคู่ของ OpenCL และ OpenGL ชื่อที่ลงท้ายด้วย CL
หรือขึ้นต้นด้วย GL
เช่น JavaCVCL
, GLCanvasFrame
เป็นต้น
หากต้องการเรียนรู้วิธีใช้ API เนื่องจากขณะนี้ยังไม่มีเอกสารประกอบ โปรดดูส่วนการใช้งานตัวอย่างด้านล่าง รวมถึงโปรแกรมตัวอย่าง รวมถึงสองโปรแกรมสำหรับ Android ( FacePreview.java
และ RecordActivity.java
) ที่พบในไดเร็กทอรี samples
ด้วย คุณอาจพบว่ามีประโยชน์ในการอ้างอิงซอร์สโค้ดของ ProCamCalib และ ProCamTracker รวมถึงตัวอย่างที่ย้ายจาก OpenCV2 Cookbook และหน้าวิกิที่เกี่ยวข้อง
โปรดแจ้งให้ฉันทราบถึงการอัปเดตหรือการแก้ไขใดๆ ที่คุณทำกับโค้ด เพื่อที่ฉันจะได้รวมเข้ากับรุ่นถัดไป ขอบคุณ! และอย่าลังเลที่จะถามคำถามในรายชื่ออีเมลหรือกระดานสนทนาหากคุณประสบปัญหากับซอฟต์แวร์! ฉันแน่ใจว่ามันยังห่างไกลจากความสมบูรณ์แบบ...
ไฟล์เก็บถาวรที่มีไฟล์ JAR พร้อมใช้งานในรูปแบบรีลีส ไฟล์เก็บถาวรไบนารีประกอบด้วยบิลด์สำหรับ Android, iOS, Linux, Mac OS X และ Windows ไฟล์ JAR สำหรับโมดูลหรือแพลตฟอร์มย่อยเฉพาะสามารถรับแยกจาก Maven Central Repository
หากต้องการติดตั้งไฟล์ JAR ด้วยตนเอง ให้ทำตามคำแนะนำในส่วนการติดตั้งด้วยตนเองด้านล่าง
เรายังสามารถดาวน์โหลดและติดตั้งทุกสิ่งโดยอัตโนมัติด้วย:
pom.xml
) < dependency >
< groupId >org.bytedeco</ groupId >
< artifactId >javacv-platform</ artifactId >
< version >1.5.11</ version >
</ dependency >
build.gradle.kts
หรือ 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 "
การดำเนินการนี้จะดาวน์โหลดไบนารีสำหรับทุกแพลตฟอร์ม แต่เพื่อให้ได้ไบนารีสำหรับแพลตฟอร์มเดียวเท่านั้น เราสามารถตั้งค่าคุณสมบัติระบบ javacpp.platform
(ผ่านตัวเลือกบรรทัดคำสั่ง -D
) เป็นบางอย่างเช่น android-arm
, linux-x86_64
, macosx-x86_64
, windows-x86_64
ฯลฯ โปรดดูรายละเอียดที่ไฟล์ README.md ของ JavaCPP Presets ตัวเลือกอื่นสำหรับผู้ใช้ Gradle คือ Gradle JavaCPP และในทำนองเดียวกันสำหรับผู้ใช้ Scala ก็มี SBT-JavaCV
หากต้องการใช้ JavaCV คุณจะต้องดาวน์โหลดและติดตั้งซอฟต์แวร์ต่อไปนี้ก่อน:
นอกจากนี้ แม้ว่าจะไม่จำเป็นเสมอไป แต่ฟังก์ชันการทำงานบางอย่างของ JavaCV ยังขึ้นอยู่กับ:
สุดท้ายนี้ โปรดตรวจสอบให้แน่ใจว่าทุกอย่างมีบิตเนสเท่ากัน: โมดูล 32 บิตและ 64 บิตจะไม่ปะปนกันในทุกสถานการณ์
เพียงใส่ไฟล์ JAR ที่ต้องการทั้งหมด ( opencv*.jar
, ffmpeg*.jar
ฯลฯ ) นอกเหนือจาก javacpp.jar
และ javacv.jar
ที่ใดที่หนึ่งในคลาสพาธของคุณ ต่อไปนี้เป็นคำแนะนำเฉพาะเพิ่มเติมสำหรับกรณีทั่วไป:
NetBeans (Java SE 7 หรือใหม่กว่า):
Eclipse (Java SE 7 หรือใหม่กว่า):
รหัส Visual Studio (Java SE 7 หรือใหม่กว่า):
+
IntelliJ IDEA (Android 7.0 หรือใหม่กว่า):
app/libs
+
และเลือก "2 File dependency"libs
android:extractNativeLibs="true"
หลังจากนั้น คลาส wrapper สำหรับ OpenCV และ FFmpeg จะสามารถเข้าถึง C/C++ API ทั้งหมดได้โดยอัตโนมัติ:
โดยพื้นฐานแล้วคำจำกัดความของคลาสนั้นเป็นพอร์ตไปยัง Java ของไฟล์ส่วนหัวดั้งเดิมใน C/C++ และฉันตั้งใจตัดสินใจที่จะเก็บไวยากรณ์ดั้งเดิมไว้ให้มากที่สุดเท่าที่จะเป็นไปได้ ตัวอย่างเช่น ต่อไปนี้เป็นวิธีการที่พยายามโหลดไฟล์รูปภาพ ปรับให้เรียบ และบันทึกกลับไปยังดิสก์:
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 ยังมาพร้อมกับคลาสตัวช่วยและวิธีการที่อยู่ด้านบนของ OpenCV และ FFmpeg เพื่ออำนวยความสะดวกในการรวมเข้ากับแพลตฟอร์ม Java นี่คือโปรแกรมสาธิตขนาดเล็กที่สาธิตส่วนที่มีประโยชน์บ่อยที่สุด:
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 ();
}
}
นอกจากนี้ หลังจากสร้างไฟล์ pom.xml
โดยมีเนื้อหาดังต่อไปนี้:
< 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 >
และโดยการวางซอร์สโค้ดด้านบนใน Demo.java
หรือในทำนองเดียวกันสำหรับคลาสอื่น ๆ ที่พบใน samples
เราสามารถใช้คำสั่งต่อไปนี้เพื่อติดตั้งทุกอย่างโดยอัตโนมัติก่อนแล้วจึงรันโดย Maven:
$ mvn compile exec:java -Dexec.mainClass=Demo
หมายเหตุ : ในกรณีที่มีข้อผิดพลาด โปรดตรวจสอบให้แน่ใจว่า artifactId
ในไฟล์ pom.xml
อ่าน javacv-platform
ไม่ใช่ javacv
เท่านั้น เป็นต้น javacv-platform
สิ่งประดิษฐ์เพิ่มการพึ่งพาไบนารีที่จำเป็นทั้งหมด
หากไฟล์ไบนารีที่มีอยู่ด้านบนไม่เพียงพอต่อความต้องการของคุณ คุณอาจต้องสร้างไฟล์เหล่านั้นใหม่จากซอร์สโค้ด ด้วยเหตุนี้ ไฟล์โครงการจึงถูกสร้างขึ้นสำหรับ:
เมื่อติดตั้งแล้ว เพียงเรียกคำสั่ง mvn install
ตามปกติสำหรับ JavaCPP, Presets และ JavaCV ตามค่าเริ่มต้น ไม่จำเป็นต้องมีการพึ่งพาอื่นใดนอกจากคอมไพเลอร์ C++ สำหรับ JavaCPP โปรดดูความคิดเห็นภายในไฟล์ pom.xml
สำหรับรายละเอียดเพิ่มเติม
แทนที่จะสร้างไลบรารีดั้งเดิมด้วยตนเอง เราสามารถรัน mvn install
สำหรับ JavaCV เท่านั้น และใช้ส่วนสแน็ปช็อตจากบิวด์ CI:
หัวหน้าโครงการ: Samuel Audet samuel.audet at
gmail.com
เว็บไซต์ผู้พัฒนา: https://github.com/bytedeco/javacv
กลุ่มสนทนา: http://groups.google.com/group/javacv