我想將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:其他信息,以防萬一:
- mGrey是:墊[480 * 640 * CV_8UC1,isCont = TRUE,isSubmat =假,nativeObj = 0x19d9af48,DATAADDR = 0x19dc3430]
- 面對的是:墊[0 * 0 * CV_8UC1,isCont =假,isSubmat =假,nativeObj = 0x194bb048,DATAADDR =爲0x0]
非常感謝您的測試!你是完全正確的。我有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
對不起,我不能給你一個投票...沒有足夠的權利:( – Eduardo