2013-06-29 78 views
2

我想將OpenCV CascadeClassifier tutorial從C++翻譯成Java。在C++中運行良好。此java tutorial工作正常。Java中的CascadeClassifier沒有找到與網絡攝像頭的臉

但翻譯根本沒有檢測到臉。我沒有明確的錯誤。我可以看到來自網絡攝像頭的視頻輸入(灰色/直方圖...)和視頻顯示的處理。級聯加載不會導致錯誤。但CascadeClassifier調用只是不返回任何面...所以,你可能會跳過所有的代碼,然後去我的CascadeClassifier調用,到公共Mat檢測(Mat輸入幀)。由於我是Java和OpenCV的新手,我粘貼其餘的(我刪除了任何我覺得可能不重要的東西),以防萬一,但並不意味着你要調試那個...

我也嘗試過這個電話(和其他部分)以許多不同的方式,並沒有什麼...用盡想法...

謝謝!

import java.awt.*; 
import java.awt.image.BufferedImage; 
import javax.swing.*; 

import org.opencv.core.Mat; 
import org.opencv.core.MatOfRect; 
import org.opencv.highgui.VideoCapture; 
import org.opencv.imgproc.Imgproc; 
import org.opencv.objdetect.CascadeClassifier; 

class My_Panel extends JPanel{ 

    private static final long serialVersionUID = 1L; 
    private BufferedImage image; 
    private CascadeClassifier face_cascade; 

    // Create a constructor method 
    public My_Panel(){ 
     super(); 
     String face_cascade_name = "/haarcascade_frontalface_alt.xml"; 
     //String face_cascade_name = "/lbpcascade_frontalface.xml"; 
     //-- 1. Load the cascades 

     String str; 
     str = getClass().getResource(face_cascade_name).getPath(); 
     str = str.replace("/C:","C:"); 
     face_cascade_name=str; 

     face_cascade=new CascadeClassifier(face_cascade_name); 
     if(!face_cascade.empty()) 
     { 
      System.out.println("--(!)Error loading A\n"); 
      return; 
     } 
     else 
     { 
       System.out.println("Face classifier loooaaaaaded up"); 
     } 
    } 

    private BufferedImage getimage(){ 
     return image; 
    } 

    public void setimage(BufferedImage newimage){ 
     image=newimage; 
     return; 
    } 

    /** 
    * Converts/writes a Mat into a BufferedImage. 
    * 
    * @param matrix Mat of type CV_8UC3 or CV_8UC1 
    * @return BufferedImage of type TYPE_3BYTE_BGR or TYPE_BYTE_GRAY 
    */ 
    public BufferedImage matToBufferedImage(Mat matrix) { 
     int cols = matrix.cols(); 
     int rows = matrix.rows(); 
     int elemSize = (int)matrix.elemSize(); 
     byte[] data = new byte[cols * rows * elemSize]; 
     int type; 

     matrix.get(0, 0, data); 

     switch (matrix.channels()) { 
      case 1: 
       type = BufferedImage.TYPE_BYTE_GRAY; 
       break; 

      case 3: 
       type = BufferedImage.TYPE_3BYTE_BGR; 

       // bgr to rgb 
       byte b; 
       for(int i=0; i<data.length; i=i+3) { 
        b = data[i]; 
        data[i] = data[i+2]; 
        data[i+2] = b; 
       } 
       break; 

      default: 
       return null; 
     } 

     BufferedImage image2 = new BufferedImage(cols, rows, type); 
     image2.getRaster().setDataElements(0, 0, cols, rows, data); 

     return image2; 
    } 

    public void paintComponent(Graphics g){ 
     BufferedImage temp=getimage(); 
     g.drawImage(temp,10,10,temp.getWidth(),temp.getHeight(), this); 
    } 

    public Mat detect(Mat inputframe){ 
     Mat mRgba=new Mat(); 
     Mat mGrey=new Mat(); 
     MatOfRect faces = new MatOfRect(); 
     //MatOfRect eyes = new MatOfRect(); 

     inputframe.copyTo(mRgba); 
     inputframe.copyTo(mGrey); 
     Imgproc.cvtColor(mRgba, mGrey, Imgproc.COLOR_BGR2GRAY); 
     Imgproc.equalizeHist(mGrey, mGrey); 

     face_cascade.detectMultiScale(mGrey, faces); 
     //face_cascade.detectMultiScale(mGrey, faces, 1.1, 2, 0|Objdetect.CASCADE_SCALE_IMAGE, new Size(30, 30), new Size(200,200)); 
     //face_cascade.detectMultiScale(mGrey, faces, 1.1, 2, 2//CV_HAAR_SCALE_IMAGE, 
     //  ,new Size(30, 30), new Size(200,200)); 

     System.out.println(String.format("Detected %s faces", faces.toArray().length)); 

     return mGrey; 
     } 
} 

public class window { 
    public static void main(String arg[]){ 
    // Load the native library. 
    System.loadLibrary("opencv_java245"); 

    String window_name = "Capture - Face detection"; 

    JFrame frame = new JFrame(window_name); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setSize(400,400); 

    My_Panel my_panel = new My_Panel(); 
    frame.setContentPane(my_panel);   
    frame.setVisible(true);   

    //-- 2. Read the video stream 
    BufferedImage temp; 
    Mat webcam_image=new Mat(); 

    VideoCapture capture =new VideoCapture(0); 
    if(capture.isOpened()) 
     { 
      while(true) 
      { 
       capture.read(webcam_image); 
       if(!webcam_image.empty()) 
       { 
        frame.setSize(webcam_image.width()+40,webcam_image.height()+60); 

        //-- 3. Apply the classifier to the captured image 
        // At this point I was wondering where this should be done. 
        // I put it within the panel class, but maybe one could actually 
        // create a processor object... 
        webcam_image=my_panel.detect(webcam_image); 

       //-- 4. Display the image 
        temp=my_panel.matToBufferedImage(webcam_image); 
        my_panel.setimage(temp); 
        my_panel.repaint(); 
       } 
       else 
       { 
        System.out.println(" --(!) No captured frame -- Break!"); 
        break; 
       } 
       } 
      } 
      return; 
    } 
} 

PS:其他信息,以防萬一:

  1. mGrey是:墊[480 * 640 * CV_8UC1,isCont = TRUE,isSubmat =假,nativeObj = 0x19d9af48,DATAADDR = 0x19dc3430]
  2. 面對的是:墊[0 * 0 * CV_8UC1,isCont =假,isSubmat =假,nativeObj = 0x194bb048,DATAADDR =爲0x0]

回答

6

我曾嘗試你的代碼,它工作正常! haarcascade_frontalface_alt.xml文件位置只有一個問題。嘗試使用文件的完整路徑: face_cascade = new CascadeClassifier(「D:/HelloCV/src/haarcascade_frontalface_alt.xml」);

+0

非常感謝您的測試!你是完全正確的。我有2個錯誤:** 1/**加載CascadeClassifier時我沒有收到錯誤,因爲事實和錯誤的情況是顛倒的,呃! ** 2/** CascadeClassifier未加載,因爲使用的方法返回路徑「C:/USERDATA/MEDICAL/CODE/java%20webcam%20facedetect/bin/haarcascade_frontalface_alt.xml」。 html格式代碼正在破壞一切。簡單的空間完成這項工作:「C:/ USERDATA/MEDICAL/CODE/java webcam facedetect/bin/haarcascade_frontalface_alt.xml」。 Mistery解決了!謝謝! – Eduardo

+0

對不起,我不能給你一個投票...沒有足夠的權利:( – Eduardo