1,基于ffmpeg封装类
<!-- https://mvnrepository.com/artifact/org.bytedeco/javacv-platform -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.7</version>
</dependency>
获取帧图像buff
private BufferedImage FrameToBufferedImage(Frame frame) {
Java2DFrameConverter converter = new Java2DFrameConverter();
BufferedImage bufferedImage = converter.getBufferedImage(frame);
converter.close();
return bufferedImage;
}
长时间连接可能中断,单独封个初始化摄像头连接的函数以便中断时再次初始化
private FFmpegFrameGrabber getGrabber() throws org.bytedeco.javacv.FFmpegFrameGrabber.Exception {
FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(m_rtspURL);
grabber.setOption("rtsp_transport", "tcp");
grabber.setImageWidth(960);
grabber.setImageHeight(540);
grabber.start();
return grabber;
}
摄像头数据截图
/** 摄像头截图 */
public static void screenshot(String rtspURL, String fileName, Long samplingRate) throws Exception {
avutil.av_log_set_level(avutil.AV_LOG_ERROR);
FFmpegLogCallback.set();
FFmpegFrameGrabber grabber = this.getGrabber();
File outPut = new File(fileName);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// 间隔多少帧取1帧,普通网络摄像帧率约25Hz。这里不要用sleep控制,会越来越慢
int samplingRate = 5;
int index = 0;
Frame frame = null;
while (true){
frame = grabber.grabImage();
if(frame == null)
{
grabber.stop();
grabber.release();
grabber = this.getGrabber();
System.out.println("没切到图");
continue;
}
if (frame != null && index++ >= samplingRate) {
ImageIO.write(FrameToBufferedImage(frame), "jpg", outPut);
index = 0;
}
}
}
2,基于OpenCV封装类
<!-- https://mvnrepository.com/artifact/org.bytedeco.javacpp-presets/opencv -->
<dependency>
<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>opencv</artifactId>
<version>3.2.0-1.3</version>
</dependency>
截图(里头有人脸识别、截图、HTTP推送等,没用的可以删除忽略)
/** 摄像头截图 */
public void screenshot_ex() throws IOException {
// 内存不能实时释放,尽量不new
VideoCapture capture = new VideoCapture();
capture.open(m_rtspURL);
capture.set(3, 960);
capture.set(4, 540);
if (!capture.isOpened()) {
m_log.error("ERROR:could not open camera {}", m_rtspURL);
return;
}
// type 0: 表示rgb 人脸检测 1:表示nir人脸检测
int type = 0;
Mat frame = new Mat();
int index = 0;
while (true) {
boolean have = capture.read(frame);
// 切一下 resize(原矩阵,新矩阵,宽,高)
Imgproc.resize(frame, frame, new Size(960,540));
// 截一下 submat(起始行,截止行,起始列,截止列)
// frame = frame.submat(20, 540 - 88, 96, 960 - 96);
if (!have) {
m_log.error("切图失败");
capture.release();
capture.open(m_rtspURL);
continue;
}
if(index++ < m_samplingRate)
{
continue;
}
index = 0;
if (!frame.empty()) {
long matAddr = frame.getNativeObjAddr();
// 获取特征
FeatureInfo[] featureInfo = Face.faceFeature(matAddr, type);
if (featureInfo == null || featureInfo.length <= 0) {
m_log.info("无人脸");
continue;
}
List<FaceAttribute> eatureInfoList = new ArrayList<>();
for (int i = 0; i < featureInfo.length; i++) {
FeatureInfo fi = featureInfo[i];
// (注意)父类对象实例化时不知道子类,所以这个地方不能父实例强转子实例,要new个子实例
// FaceAttribute faceAttribute = new FaceAttribute(fi);
FaceAttribute faceAttribute = new FaceAttribute();
// 抠图
Mat mat_sub = new Mat();
long outAddr = mat_sub.getNativeObjAddr();
Face.faceCrop(matAddr, outAddr);
// 属性
faceAttribute.setAttribute(Face.faceAttr(outAddr));
// 搜索
faceAttribute.setIdentify(Face.identifyWithAll(fi.feature, type).replaceAll("\\n|\\t",""));
// 绘制
FaceDraw.drawRects(frame, fi.box);
eatureInfoList.add(faceAttribute);
mat_sub = null;
}
// 保存
String fname = UUID.randomUUID().toString() + ".jpg";
Imgcodecs.imwrite(m_rtspImage + fname, frame);
// 发送
JSONObject jo = new JSONObject();
jo.put("error_code", 0);
jo.put("img_src", m_rtspImage_down + fname);
String str = GsonUtils.toJson(eatureInfoList);
jo.put("face_list", str);
Map<String, Object> map = new HashMap<>();
map.put("JsonData", jo);
map.put("UseState", 0);
map.put("CreateDate", LocalDateTime.now().toString());
String param = GsonUtils.toJson(map);
try {
m_HttpUtil.postAsync(m_sendURL, param);
m_log.info("INFO::向{}推发送数据成功{}",m_sendURL, param);
} catch (java.lang.Exception e) {
m_log.error("ERROR::向{}推送数据失败 ",m_sendURL);
}
eatureInfoList = null;
jo = null;
map = null;
System.gc();
}
}
}
依赖的dll放到运行目录(这狗平台不让传附件)