javacvで顔検出+画像合成
やってみた。
package jp.ne.hatena.d.matasaburou; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import com.googlecode.javacv.CanvasFrame; import com.googlecode.javacv.OpenCVFrameGrabber; import static com.googlecode.javacv.cpp.opencv_core.*; import static com.googlecode.javacv.cpp.opencv_objdetect.*; import static com.googlecode.javacv.cpp.opencv_highgui.*; public class Main { static CanvasFrame canvas; static BufferedImage bufImage; static OpenCVFrameGrabber grabber; public static void main(String[] args) { canvas = new CanvasFrame("Test"); canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); try{ bufImage = ImageIO.read(new File("C:\\image.jpg")); }catch(IOException e){ e.printStackTrace(); } grabber = new OpenCVFrameGrabber(0); new Main().loop(); } private void loop() { try { grabber.start(); double frameRate = grabber.getFrameRate(); long wait = (long) (1000 / (frameRate == 0 ? 20 : frameRate)); while (true) { Thread.sleep(wait); IplImage image = grabber.grab(); if (image != null) { canvas.showImage(switchFace(image, bufImage)); } } } catch (Exception e) { e.printStackTrace(); } } private static final String XML = "C:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontface_default.xml"; private static CvHaarClassifierCascade cascade = new CvHaarClassifierCascade(cvLoad(XML)); private static BufferedImage combinedImage; public BufferedImage switchFace(IplImage src, BufferedImage target){ CvMemStorage storage = CvMemStorage.create(); combinedImage = src.getBufferedImage(); cvClearMemStorage(storage); CvSeq sign = cvHaarDetectObjects( src, cascade, storage, 1.2, 3, CV_HAAR_DO_CANNY_PRUNING ); if(sign.total() > 0){ CvRect r = new CvRect(cvGetSeqElem(sign, 0)); combinedImage.getGraphics().drawImage(target, r.x(), r.y(), r.width(), r.height(), null); } return combinedImage; } }
デフォルトの検出器では、横顔をうまく認識できない模様。
検出器をどこかから見つけてこよう。