الدعم التجاري:
يستخدم JavaCV أغلفة من إعدادات JavaCPP المسبقة للمكتبات شائعة الاستخدام من قبل الباحثين في مجال رؤية الكمبيوتر (OpenCV، FFmpeg، libdc1394، FlyCapture، Spinnaker، OpenKinect، librealsense، CL PS3 Eye Driver، videoInput، ARToolKitPlus، flandmark، Leptonica، وTesseract) ويوفر فئات أدوات مساعدة لتسهيل استخدام وظائفها على نظام Java الأساسي، بما في ذلك أندرويد.
يأتي JavaCV أيضًا مزودًا بأجهزة عرض الصور بملء الشاشة ( CanvasFrame
و GLCanvasFrame
) وطرق سهلة الاستخدام لتنفيذ التعليمات البرمجية بالتوازي على مراكز متعددة ( Parallel
) ومعايرة هندسية وألوانية سهلة الاستخدام للكاميرات وأجهزة العرض ( GeometricCalibrator
و ProCamGeometricCalibrator
، ProCamColorCalibrator
)، اكتشاف ومطابقة نقاط الميزات ( ObjectFinder
)، مجموعة من الفئات التي تنفذ الصورة المباشرة محاذاة أنظمة كاميرا جهاز العرض (بشكل أساسي GNImageAligner
و ProjectiveTransformer
و ProjectiveColorTransformer
و ProCamTransformer
و ReflectanceInitializer
)، وحزمة تحليل النقطة ( Blobs
)، بالإضافة إلى وظائف متنوعة في فئة JavaCV
. تحتوي بعض هذه الفئات أيضًا على نظير OpenCL وOpenGL، وتنتهي أسماؤها بـ CL
أو تبدأ بـ GL
، على سبيل المثال: JavaCVCL
، GLCanvasFrame
، إلخ.
لمعرفة كيفية استخدام واجهة برمجة التطبيقات (API)، نظرًا لعدم وجود وثائق حاليًا، يرجى الرجوع إلى قسم نموذج الاستخدام أدناه بالإضافة إلى نماذج البرامج، بما في ذلك برنامجان لنظام Android ( FacePreview.java
و RecordActivity.java
)، الموجودان أيضًا في دليل samples
. قد تجد أيضًا أنه من المفيد الرجوع إلى الكود المصدري لـ ProCamCalib وProCamTracker بالإضافة إلى الأمثلة المنقولة من OpenCV2 Cookbook وصفحات wiki المرتبطة بها.
يرجى إطلاعي على أي تحديثات أو إصلاحات تجريها على الكود حتى أتمكن من دمجها في الإصدار التالي. شكرًا لك! ولا تتردد في طرح الأسئلة على القائمة البريدية أو منتدى المناقشة إذا واجهت أي مشاكل مع البرنامج! أنا متأكد من أنها بعيدة عن الكمال ...
تتوفر الأرشيفات التي تحتوي على ملفات JAR كإصدارات. يحتوي الأرشيف الثنائي على إصدارات Android وiOS وLinux وMac OS X وWindows. يمكن أيضًا الحصول على ملفات JAR الخاصة بوحدات فرعية أو منصات محددة بشكل فردي من مستودع Maven المركزي.
لتثبيت ملفات 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 المسبقة للحصول على التفاصيل. هناك خيار آخر متاح لمستخدمي 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 تبعيات الملف".libs
.android:extractNativeLibs="true"
بعد ذلك، يمكن لفئات التغليف الخاصة بـ OpenCV وFFmpeg، على سبيل المثال، الوصول تلقائيًا إلى جميع واجهات برمجة تطبيقات C/C++ الخاصة بها:
تعريفات الفئة هي في الأساس منافذ إلى 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 وإعداداته المسبقة وJavaCV. بشكل افتراضي، لا توجد تبعيات أخرى غير مترجم C++ لـ JavaCPP مطلوبة. يرجى الرجوع إلى التعليقات الموجودة داخل ملفات pom.xml
لمزيد من التفاصيل.
بدلاً من إنشاء المكتبات الأصلية يدويًا، يمكننا تشغيل mvn install
لـ JavaCV فقط والاعتماد على عناصر اللقطة من إصدارات CI:
قائد المشروع: صامويل أوديت samuel.audet at
gmail.com
موقع المطور: https://github.com/bytedeco/javacv
مجموعة المناقشة: http://groups.google.com/group/javacv