当前位置: 首页 > 知识库问答 >
问题:

java中的CascadeClassifier无法通过网络摄像头找到人脸

夔宏深
2023-03-14

我正在尝试将OpenCV Cascade分类器教程从C翻译成Java。在C中运行良好。这个java教程也运行良好。

但翻译根本就没有检测到人脸。我没有明显的错误。我可以看到网络摄像头对视频输入的处理(灰色/直方图…)和视频显示器。级联加载不会给出错误。但是CascadeClassifier调用不会返回任何面孔。。。因此,您可能可以跳过所有代码,直接转到我的级联分类器调用,直至公共Mat检测(Mat inputframe)。由于我不熟悉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是:Mat[480*640*CV_8UC1, isCont=true, isSubmat=false, nativeObj=0x19d9af48, dataAddr=0x19dc3430]
  2. face is: Mat[0*0*CV_8UC1, isCont=false, isSubmat=false, nativeObj=0x194bb048, dataAddr=0x0]

共有1个答案

费朗
2023-03-14

我已经尝试了你的代码,它工作得很好!haarcascade\u frontalface\u alt.xml文件位置只有一个问题。尝试使用文件的完整路径:face\u cascade=new CascadeClassifier(“D:/HelloCV/src/haarcascade\u frontalface\u alt.xml”);

 类似资料:
  • 问题内容: 如何连续从摄像头捕获图像? 我想尝试对象识别(也许使用Java Media Framework)。 我当时正在考虑创建两个线程 一个线程: 节点1:捕获实时图像 节点2:将图片另存为“ 1.jpg” 节点3:等待5秒 节点4:重复… 其他线程: 节点1:等到捕获图像 节点2:使用“ 1.jpg”获取每个像素的颜色 节点3:将数据保存在数组中 节点4:重复… 问题答案: 此JavaCV实

  • 我正在开发一个web应用程序,它可以浏览和拍摄本地照片,我还想通过相机拍摄图像。我使用下面的代码,我可以捕捉设备摄像头。 现在,我想获得图像和onchangeevent,转换为base64,并希望在该页面中显示。 好心帮我伙计们!

  • 我在Ubuntu16.0.4上安装了一个新的Opencv,我编写了一个程序来获取相机流并存储一些帧。它“没有”问题。但不能通过Systemd工作。systemd单元处于活动状态(不要失败),但目标文件夹中没有帧存储。 我一步一步地寻找问题,我发现代码挂在打开摄像头流上。那就是:帽子。打开(“MyIpCameraAddress”) 我试着通过bash脚本而不是脚本来运行代码。但问题依然存在 说明=a

  • 我正在尝试使用gstreamer 1.0将网络摄像头视频从树莓流到VLC播放器。现在,我对覆盆子有以下命令: 以及以下sdp文件,以使用vlc播放流: 当我运行gst-Launst-1.0命令时,我可以通过wireshark看到它正在发送udp数据包,但当我尝试使用vlc和sdp文件播放流时,我什么也没有得到。vlc日志说: 我不知道怎么了。我可能没有正确地构建管道,这就是为什么vlc不能将该流识

  • 我知道这可能是一个相对通用的问题,但我正试图看看如何才能被指向正确的方向... 我试图用AWS Rekognition建立一个实时人脸识别应用程序。我对API很满意,并使用上传到S3的静态图像来执行面部识别。然而,我正试图找到一种将实时数据流到Rekognition的方法。在阅读了Amazon提供的各种文章和文档后,我发现了这个过程,但似乎无法克服一个障碍。 根据文档,我可以用Kinesis来完成

  • Dlib有一个非常方便、快速和高效的目标检测程序,我想做一个类似于这个例子的酷脸跟踪例子。 OpenCV,这是广泛支持,有视频捕捉模块,这是相当快的(五分之一秒的快照相比,1秒或更多的调用一些程序,唤醒网络摄像头和获取图片)。我将此添加到Dlib中的人脸检测器Python示例中。 如果您直接显示和处理OpenCV VideoCapture输出,它看起来很奇怪,因为OpenCV显然存储BGR而不是R