javacpp-opencv图像处理系列3:使用opencv原生方法遍历摄像头设备及调用(增加实时帧率计算方法)

    xiaoxiao2021-03-26  30

    javaCV-opencv图像处理系列:

    opencv图像处理系列之1:实时视频添加文字水印并截取视频图像保存成图片,实现文字水印的字体、位置、大小、粗度、翻转、平滑等操作

    opencv图像处理系列之2:实时视频添加图片水印,实现不同大小图片叠加,图像透明度控制

    opencv图像处理系列之3:使用opencv原生方法遍历摄像头设备及调用(方便多摄像头遍历及调用,相比javacv更快的摄像头读取速度和效率,方便读取后的图像处理)

    opencv图像处理系列之补充篇:国内车辆牌照检测识别系统(万份测试准确率99.7%以上)

    javacv进阶opencv图像检测/识别

    JavaCV进阶opencv图像检测识别:摄像头画面人脸检测

    JavaCV进阶opencv图像检测识别:ffmpeg视频图像画面人脸检测

    javacv-tesserac文字识别系列:

    tesserac文字识别之1:基于google的tesserac ocr识别图片中的文字,跨平台支持英文中文简体繁体等各种字符识别

    tesserac文字识别之2:视频文字识别和视频提取字幕文字字符

    前言

    鉴于很多同学反馈目前javacv采集摄像头存在几点问题

    1、javacv采集摄像头帧率很低

    2、javacv中的摄像头采集依赖opencv的capture采集器,获取的Mat没有及时释放,容易内存溢出

    3、javacv封装的太死,调用摄像头不灵活,无法遍历摄像头设备列表

    4、javacv打开摄像头太慢,一般要3秒才能打开摄像头设备

    所以直接使用opencv采集摄像头设备是一个比较好的方案,并且采集效率上得到了很大的提高,不会像javacv里面一样摄像头掉帧比较严重。

    补充:

    除了可以通过opencv方式获取摄像头外,还可以通过ffmpeg方式获取摄像头:

    windows下还可以通过dshow和gdigrab方式获取摄像头:基于dshow调用windows摄像头、基于gdigrab的windows屏幕画面抓取和摄像头画面采集;

    mac下可以通过avfoundation获取摄像头:基于avfoundation的苹果Mac和ios获取屏幕画面及录屏/截屏以及摄像头画面和音频采样获取实现;

    ffmpeg原生支持安卓摄像头调用,一般情况下后置摄像头是0,前置摄像头是1,不另外补充。

    一、实现的功能

     

    (1)opencv原生摄像头图像采集

    (2)opencv原生摄像头设备遍历

    (3)Mat转换为Frame

    (4)计算实时帧率

    (5)文字水印(显示实时帧率)

     

    二、实现代码

    1、无水印,无帧率计算实现:

    做好自己!--eguid VideoCapture vc=null; //遍历查找摄像头 int index=-1; for(;index<2;index++){ vc=new opencv_videoio.VideoCapture(index); if(vc.grab()){ //找到摄像头设备,退出遍历 System.err.println("当前摄像头:"+index); break; } vc.close();//没找到设备,释放资源 } //vc为null,并且设备没正常开启,说明没找到设备 if(vc!=null&&!vc.isOpened()){ System.err.println("无法找到摄像头,请检查是否存在摄像头设备"); return; } //使用java的JFrame显示图像 CanvasFrame cFrame = new CanvasFrame("做好自己!--eguid!http://www.eguid.cc/",CanvasFrame.getDefaultGamma()/2.2); //javacv提供的转换器,方便mat转换为Frame OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage(); Mat mat=new Mat(); for(;;){ vc.retrieve(mat);//重新获取mat if(vc.grab()){//是否采集到摄像头数据 if(vc.read(mat)){//读取一帧mat图像 // opencv_highgui.imshow("eguid", mat);该opencv方法windows下会无响应 cFrame.showImage(converter.convert(mat)); } mat.release();//释放mat } try { Thread.sleep(45); } catch (InterruptedException e) { e.printStackTrace(); } }

     

    2、实时计算帧率并加实时帧率文字水印到图像

    //做好自己!--eguid!http://www.eguid.cc String msg="fps:";//水印文字 // 水印文字位置 Point point = new Point(10, 50); // 颜色,使用黄色 Scalar scalar = new Scalar(0, 255, 255, 0); DecimalFormat df=new DecimalFormat(".##");//数字格式化 VideoCapture vc=null; //遍历查找摄像头 int index=-1; for(;index<2;index++){ vc=new opencv_videoio.VideoCapture(index); if(vc.grab()){ //找到摄像头设备,退出遍历 System.err.println("做好自己!--eguid温馨提示,获取本机当前摄像头序号:"+index); break; } vc.close();//没找到设备,释放资源 } //vc为null,并且设备没正常开启,说明没找到设备 if(vc!=null&&!vc.isOpened()){ System.err.println("无法找到摄像头,请检查是否存在摄像头设备"); return; } //使用java的JFrame显示图像 CanvasFrame cFrame = new CanvasFrame("做好自己!--eguid!http://www.eguid.cc",CanvasFrame.getDefaultGamma()/2.2); //javacv提供的转换器,方便mat转换为Frame OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage(); Mat mat=new Mat(); double start=System.currentTimeMillis(); double end; for(int i=0;;i++){ vc.retrieve(mat);//重新获取mat if(vc.grab()){//是否采集到摄像头数据 if(vc.read(mat)){//读取一帧mat图像 end=System.currentTimeMillis(); if(mat!=null){ opencv_imgproc.putText(mat,msg+df.format((1000.0/(end-start))), point, opencv_imgproc.CV_FONT_VECTOR0, 1.2, scalar, 1, 20, false); } // opencv_highgui.imshow("eguid", mat);该opencv方法windows下会无响应 cFrame.showImage(converter.convert(mat)); System.err.println(i); start=end; } mat.release();//释放mat } }

    支持eguid原创,欢迎点击下面的“点赞,收藏”。

     

     

    转载请注明原文地址: https://ju.6miu.com/read-450303.html

    最新回复(0)