JavaCV (OpenCV) を試していますが、次の動作に混乱しています。私のプログラムは単純です:
- 画像をつかむ
- 画像のグレースケール バージョンを作成します (元の画像はそのままにしておきます)。
- グレースケール イメージのしきい値
- グレースケール画像で輪郭を見つけます (cvFindContours が画像を変更し、そのまま表示したいので、画像を複製します)
- 元のカラー画像に輪郭を描く
問題は、(コメント行を参照) を複製しない限りgrabbedImage
、グレースケール イメージが変更され、輪郭が描画されることです。また、上に複数の輪郭線が描かれているようにも見えますgrabbedImage
。
また、ループにスリープを追加しようとしたところ、問題が修正されました。grabbedImage
同じ(変更された)ものを複数回取得することはできますか?Javaリファレンスを確認しましたが、違いますが、同じバッファでしょうか?
何か案が?
ありがとうございました
package com.mdarveau.opencvtest;
import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import com.googlecode.javacpp.Loader;
import com.googlecode.javacv.CanvasFrame;
import com.googlecode.javacv.FrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.CvContour;
import com.googlecode.javacv.cpp.opencv_core.CvMemStorage;
import com.googlecode.javacv.cpp.opencv_core.CvScalar;
import com.googlecode.javacv.cpp.opencv_core.CvSeq;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import com.googlecode.javacv.cpp.opencv_objdetect;
public class Demo {
public static void main( String[] args ) throws Exception {
// Preload the opencv_objdetect module to work around a known bug.
Loader.load( opencv_objdetect.class );
FrameGrabber grabber = FrameGrabber.createDefault( 1 );
grabber.start();
IplImage grabbedImage = grabber.grab();
int width = grabbedImage.width();
int height = grabbedImage.height();
IplImage grayImage = IplImage.create( width, height, IPL_DEPTH_8U, 1 );
CvMemStorage storage = CvMemStorage.create();
CanvasFrame filterProbe = new CanvasFrame( "Filtered", CanvasFrame.getDefaultGamma() / grabber.getGamma() );
CanvasFrame enhancedProbe = new CanvasFrame( "Enhanced", CanvasFrame.getDefaultGamma() / grabber.getGamma() );
while ( filterProbe.isVisible() && enhancedProbe.isVisible() && (grabbedImage = grabber.grab()) != null ) {
cvClearMemStorage( storage );
// Convert to grayscale image...
cvCvtColor( grabbedImage, grayImage, CV_BGR2GRAY );
// UNCOMMENT FIXES THE PROBLEM grabbedImage = grabbedImage.clone();
// Let's find some contours! but first some thresholding...
cvThreshold( grayImage, grayImage, 128, 255, CV_THRESH_BINARY );
// To check if an output argument is null we may call either isNull() or equals(null).
CvSeq contour = new CvSeq( null );
// cvFindContours modifies the image so clone it first since we want to keep the grayscale version
cvFindContours( grayImage.clone(), storage, contour, Loader.sizeof( CvContour.class ), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE );
while ( contour != null && !contour.isNull() ) {
if ( contour.elem_size() > 0 ) {
CvSeq points = cvApproxPoly( contour, Loader.sizeof( CvContour.class ), storage, CV_POLY_APPROX_DP, cvContourPerimeter( contour ) * 0.02, 0 );
cvDrawContours( grabbedImage, points, CvScalar.BLUE, CvScalar.BLUE, -1, 1 /*CV_FILLED*/, CV_AA );
}
contour = contour.h_next();
}
filterProbe.showImage( grayImage );
enhancedProbe.showImage( grabbedImage );
}
filterProbe.dispose();
enhancedProbe.dispose();
grabber.stop();
}
}