상업적 지원:
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
), Blob 분석 패키지( Blobs
) 및 JavaCV
클래스의 기타 기능. 이러한 클래스 중 일부에는 OpenCL 및 OpenGL 대응 항목도 있으며 이름은 CL
로 끝나거나 GL
로 시작합니다(예: JavaCVCL
, GLCanvasFrame
등).
현재 문서가 부족하므로 API 사용 방법을 알아보려면 아래의 샘플 사용법 섹션과 samples
디렉터리에 있는 Android용 두 가지( FacePreview.java
및 RecordActivity.java
)를 포함한 샘플 프로그램을 참조하세요. 또한 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
와 같은 것으로 설정할 수 있습니다. windows-x86_64
등 자세한 내용은 JavaCPP Presets의 README.md 파일을 참조하세요. Gradle 사용자가 사용할 수 있는 또 다른 옵션은 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 Code(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 gmail.com at
samuel.audet
개발자 사이트: https://github.com/bytedeco/javacv
토론 그룹: http://groups.google.com/group/javacv