研究如何视频中识别物体-调用分类器(1)

先说一下javacv

JavaCV [1]  是一款基于JavaCPP [2]  调用方式(JNI的一层封装),由多种开源计算机视觉库组成的包装库,封装了包含FFmpegOpenCVtensorflow、caffe、tesseract、libdc1394、OpenKinect、videoInput和ARToolKitPlus等在内的计算机视觉领域的常用库和实用程序类。 

一、先学习如何使用javaCV获取视频,并且获取其中的一帧 

package cc.eguid.javacv;
 
import javax.swing.JFrame;
 
import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.javacv.OpenCVFrameConverter;
import org.bytedeco.javacv.FrameGrabber.Exception;
import org.bytedeco.javacv.OpenCVFrameGrabber;
 
/**
 * JavaCV调用本地摄像头实时图像视频
 * @author eguid  
 * @date 2016年6月13日
 * @since  javacv1.2
 */
public class JavavcCameraTest{
  public static void main(String[] args) throws Exception, InterruptedException{
 
    OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);//新建opencv抓取器,一般的电脑和移动端设备中摄像头默认序号是0,不排除其他情况
    grabber.start();//开始获取摄像头数据
 
    CanvasFrame canvas = new CanvasFrame("摄像头预览");//新建一个预览窗口
    canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
    //窗口是否关闭
    while(canvas.isDisplayable()){
      /*获取摄像头图像并在窗口中显示,这里Frame frame=grabber.grab()得到是解码后的视频图像*/
      canvas.showImage(grabber.grab());
    }
    grabber.close();//停止抓取
  }
}

 关键是,(1)获取摄像头。(2)建立一个Canvas,(3)用grabber.grab()输出解码后的图像,用Canvas.showImage显示。

二、学习使用分类器

 这是一段经典代码,调用摄像头,然后通过分类器找到每帧图像中的人脸。在上面画框。就是这么简单。代码的关键是

CascadeClassifier cascade = new CascadeClassifier(cascadeClassifierXml);

记住,这里是我们下一节要去研究的,“分类器的训练”

import static org.bytedeco.opencv.global.opencv_core.*;
import static org.bytedeco.opencv.global.opencv_face.*;
import static org.bytedeco.opencv.global.opencv_imgproc.*;
import static org.bytedeco.opencv.global.opencv_objdetect.*;
/**
* JavaCV人脸检测
* @author eguid  
*/
public class JavaCVFaceDetectTest{
    /**
     * JavaCV人脸检测
     * @author eguid  
     * @param cascadeClassifierXml 基于Haar特征的cascade正面人脸分类器
     * @param width 图像宽度
     * @param height 图像高度
     */
    public static void faceDetection(String cascadeClassifierXml,Integer width,Integer height) throws Exception, InterruptedException {
        // 开启摄像头,获取图像(得到的图像为frame类型,需要转换为mat类型进行检测和识别)
        OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
        if(width!=null&&width>1&&height!=null&&height>1) {
            grabber.setImageWidth(width);
            grabber.setImageHeight(height);
        }
        grabber.start();
         
        if(width==null||height==null) {
            height=grabber.getImageHeight();
            width=grabber.getImageWidth();
        }
         
        CanvasFrame canvas = new CanvasFrame("人脸检测");// 新建一个预览窗口
        canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        canvas.setVisible(true);
        canvas.setFocusable(true);
        //窗口置顶
        if(canvas.isAlwaysOnTopSupported()) {
            canvas.setAlwaysOnTop(true);
        }
        Frame frame =null;
         
        // 读取opencv人脸检测器
        CascadeClassifier cascade = new CascadeClassifier(cascadeClassifierXml);
                     
        for(;canvas.isVisible()&&(frame=grabber.grab())!=null;) {
             
            Mat img = (Mat) frame.opaque;// 从frame中直接获取Mat
             
            Mat grayImg = new Mat();//存放灰度图
            //摄像头色彩模式设置成ImageMode.Gray下不需要再做灰度
            cvtColor(img, grayImg, COLOR_BGRA2GRAY);// 摄像头获取的是彩色图像,所以先灰度化下
            //如果要获取摄像头灰度图,可以直接对FrameGrabber进行设置grabber.setImageMode(ImageMode.GRAY);,grabber.grab()获取的都是灰度图
             
            equalizeHist(grayImg, grayImg);// 均衡化直方图
  
            // 检测到的人脸
            RectVector faces = new RectVector();
            cascade.detectMultiScale(grayImg, faces);
             
            // 遍历人脸
            for (int i = 0; i < faces.size(); i++) {
                Rect face_i = faces.get(i);
                //绘制人脸矩形区域,scalar色彩顺序:BGR(蓝绿红)
                rectangle(img, face_i, new Scalar(0, 255, 0, 1));
                 
                int pos_x = Math.max(face_i.tl().x() - 10, 0);
                int pos_y = Math.max(face_i.tl().y() - 10, 0);
                // 在人脸矩形上方绘制提示文字
                putText(img, "people face", new Point(pos_x, pos_y), FONT_HERSHEY_COMPLEX, 1.0,new Scalar(0, 0, 255, 2.0));
            }
             
            canvas.showImage(frame);// 获取摄像头图像并放到窗口上显示,frame是一帧视频图像
            Thread.sleep(40);// 40毫秒刷新一次图像
        }
        cascade.close();
        canvas.dispose();
        grabber.close();// 停止抓取
    }
 }

三、如何训练分类器(Cascade)

从上面看,关键的问题是:如何提供不同的分类器。

这部分且听下回分解。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值