商用サポート:
JavaCV は、コンピュータ ビジョンの分野の研究者によって一般的に使用されるライブラリ (OpenCV、FFmpeg、libdc1394、FlyCapture、Spinnaker、OpenKinect、librealsense、CL PS3 Eye Driver、videoInput、ARToolKitPlus、flandmark、Leptonica、および Tesseract) の JavaCPP プリセットのラッパーを使用します。また、Android を含む Java プラットフォームでその機能を簡単に使用できるようにするユーティリティ クラスを提供します。
JavaCV には、ハードウェアで高速化された全画面画像表示 ( CanvasFrame
およびGLCanvasFrame
)、複数のコアでコードを並行して実行する使いやすいメソッド ( Parallel
)、カメラとプロジェクターのユーザーフレンドリーな幾何学および色のキャリブレーション ( GeometricCalibrator
、 ProCamGeometricCalibrator
も付属しています。 、 ProCamColorCalibrator
)、特徴点の検出とマッチング ( ObjectFinder
)、画像の直接位置合わせを実装するクラスのセットプロジェクター カメラ システム (主にGNImageAligner
、 ProjectiveTransformer
、 ProjectiveColorTransformer
、 ProCamTransformer
、およびReflectanceInitializer
)、ブロブ分析パッケージ ( Blobs
)、およびJavaCV
クラスのその他の機能。これらのクラスの中には、対応する OpenCL および OpenGL もあり、その名前はCL
で終わるかGL
で始まります (つまり、 JavaCVCL
、 GLCanvasFrame
など)。
現在ドキュメントが不足しているため、API の使用方法を学ぶには、以下のサンプル使用法セクションと、 samples
ディレクトリにある Android 用の 2 つのサンプル プログラム ( FacePreview.java
とRecordActivity.java
) を含むサンプル プログラムを参照してください。 ProCamCalib および ProCamTracker のソース コード、OpenCV2 Cookbook および関連する Wiki ページから移植された例を参照することも役立つ場合があります。
次のリリースに統合できるように、コードに加えた更新や修正については常にお知らせください。ありがとう!ソフトウェアで問題が発生した場合は、メーリング リストまたはディスカッション フォーラムでお気軽に質問してください。確かに完璧にはほど遠いと思います...
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 "
これにより、すべてのプラットフォームのバイナリがダウンロードされますが、1 つのプラットフォームのみのバイナリを取得するには、 javacpp.platform
システム プロパティを ( -D
コマンド ライン オプション経由で) android-arm
、 linux-x86_64
、 macosx-x86_64
、 windows-x86_64
などに設定できます。 windows-x86_64
など。詳細はJavaCPP PresetsのREADME.mdファイルを参照してください。 Gradle ユーザーが利用できるもう 1 つのオプションは Gradle JavaCPP で、同様に Scala ユーザーには SBT-JavaCV があります。
JavaCV を使用するには、まず次のソフトウェアをダウンロードしてインストールする必要があります。
さらに、常に必須ではありませんが、JavaCV の一部の機能は以下にも依存します。
最後に、すべてのビット数が同じであることを確認してください。32ビット モジュールと 64 ビット モジュールは、いかなる状況でも混在しないでください。
javacpp.jar
とjavacv.jar
に加えて、必要なすべての JAR ファイル ( opencv*.jar
、 ffmpeg*.jar
など) をクラスパスのどこかに置くだけです。一般的なケースに対するより具体的な手順を次に示します。
NetBeans (Java SE 7 以降):
Eclipse (Java SE 7 以降):
Visual Studio コード (Java SE 7 以降):
+
をクリックします。IntelliJ IDEA (Android 7.0 以降):
app/libs
サブディレクトリにコピーします。+
クリックして、「2 ファイルの依存関係」を選択します。libs
サブディレクトリからすべての JAR ファイルを選択します。android:extractNativeLibs="true"
を追加します。その後、たとえば OpenCV や FFmpeg のラッパー クラスは、すべての C/C++ API に自動的にアクセスできるようになります。
クラス定義は基本的に、C/C++ の元のヘッダー ファイルを Java に移植したものであり、元の構文を可能な限り維持することに意図的に決めました。たとえば、次のメソッドは、画像ファイルをロードし、滑らかにして、ディスクに保存し直そうとします。
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
注: エラーが発生した場合は、 pom.xml
ファイル内のartifactId
javacv
のみではなく、 javacv-platform
読み取ることを確認してください。アーティファクトjavacv-platform
必要なバイナリ依存関係をすべて追加します。
上記で入手可能なバイナリ ファイルがニーズを満たさない場合は、ソース コードからバイナリ ファイルを再構築する必要がある場合があります。この目的のために、次のプロジェクト ファイルが作成されました。
インストールしたら、JavaCPP、そのプリセット、および JavaCV に対して通常のmvn install
コマンドを呼び出すだけです。デフォルトでは、JavaCPP の C++ コンパイラ以外の依存関係は必要ありません。詳細については、 pom.xml
ファイル内のコメントを参照してください。
ネイティブ ライブラリを手動で構築する代わりに、JavaCV に対してのみmvn install
実行し、CI ビルドからのスナップショット アーティファクトに依存できます。
プロジェクトリーダー: Samuel Audet samuel.audet at
gmail.com)
開発者サイト: https://github.com/bytedeco/javacv
ディスカッション グループ: http://groups.google.com/group/javacv