原 荐 Java基于百度AI+JavaCV+OpenCV 实现摄像头人数动态统计

栏目: 编程工具 · 发布时间: 7年前

原 荐  <a href='https://www.codercto.com/topics/22013.html'>Java</a> 基于百度AI+JavaCV+OpenCV 实现摄像头人数动态统计

【Java】人流量统计-动态版之视频转图识别请访问 http://ai.baidu.com/forum/topic/show/940413

本文是基于上一篇进行迭代的。本文主要是以摄像头画面进行人流量统计。并对返回图像进行展示。需要额外了解 JavaCV OpenCV swing awt等 

也许JavaCV OpenCV  不需要也可以实现效果。但是小帅丶就先用这样的方式实现了。别的方式大家就自己尝试吧

项目代码地址 https://gitee.com/xshuai/bodyTrack

  • 注意的问题
1.动态识别的area参数为矩阵的4个顶点的xy坐标(即像素) 顺序是 上左下右 也就是顺时针一圈4个点的坐标点
2.case_init 为int 请不要给大于int范围的值。或非int类型的值 即正整数就行 
3.area的值不要大于图片本身的宽高
  • 需要用到的jar 通过maven引入(下载的jar较多。需要等待较长时间)
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <ffmpeg.version>3.2.1-1.3</ffmpeg.version>
    <javacv.version>1.4.1</javacv.version>
  </properties>

  <dependencies>
  
 <dependency>
      <groupId>org.bytedeco.javacpp-presets</groupId>
      <artifactId>ffmpeg-platform</artifactId>
      <version>${ffmpeg.version}</version>
    </dependency>
	<!-- fastjson -->
	<dependency>
		<groupId>com.alibaba</groupId>
		<artifactId>fastjson</artifactId>
		<version>1.2.35</version>
	</dependency>
    <dependency>
      <groupId>org.bytedeco</groupId>
      <artifactId>javacv</artifactId>
      <version>${javacv.version}</version>
    </dependency>

	<dependency>
		<groupId>org.bytedeco.javacpp-presets</groupId>
		<artifactId>opencv-platform</artifactId>
		<version>3.4.1-1.4.1</version>
	</dependency>
  </dependencies>
  •  需要用到的Java工具类
HttpUtil https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
  • 调用接口示例代码(需要自己的电脑有摄像头哦)
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacv.CanvasFrame;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.bytedeco.javacv.OpenCVFrameConverter;
import org.bytedeco.javacv.OpenCVFrameConverter.ToIplImage;
import org.bytedeco.javacv.OpenCVFrameGrabber;

import com.alibaba.fastjson.JSONObject;

import cn.xsshome.body.util.HttpUtil;
/**
 * 获取摄像头画面进行处理并回显图片在画面中
 * 人流量统计(动态版)JavaAPI示例代码
 * @author 小帅丶
 *
 */
public class JavavcCameraTest {
	
	static OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
	//人流量统计(动态版)接口地址
	private static String BODY_TRACKING_URL="https://aip.baidubce.com/rest/2.0/image-classify/v1/body_tracking";
	
	private static String ACCESS_TOKEN ="";//接口的token

	public static void main(String[] args) throws Exception,
			InterruptedException {
		OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
		grabber.start(); // 开始获取摄像头数据
		CanvasFrame canvas = new CanvasFrame("人流量实时统计");// 新建一个窗口
		canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		canvas.setAlwaysOnTop(true);
		int ex = 0;
		while (true) {
			if (!canvas.isDisplayable()) {// 窗口是否关闭
				grabber.stop();// 停止抓取
				System.exit(2);// 退出
				grabber.close();
			}
			// canvas.showImage(grabber.grab());//显示摄像头抓取的画面
			Java2DFrameConverter java2dFrameConverter = new Java2DFrameConverter();
			// 摄像头抓取的画面转BufferedImage
			BufferedImage bufferedImage = java2dFrameConverter.getBufferedImage(grabber.grabFrame());
			// bufferedImage 请求API接口 检测人流量
			String result = getBodyTrack(bufferedImage);
			BufferedImage bufferedImageAPI = getAPIResult(result);
			// 如果识别为空 则显示摄像头抓取的画面
			if (null == bufferedImageAPI) {
				canvas.showImage(grabber.grab());
			} else {
				// BufferedImage转IplImage
				IplImage iplImageAPI = BufImgToIplData(bufferedImageAPI);
				// 将IplImage转为Frame 并显示在窗口中
				Frame convertFrame = converter.convert(iplImageAPI);
				canvas.showImage(convertFrame);
			}
			ex++;
//			Thread.sleep(100);// 100毫秒刷新一次图像.因为接口返回需要时间。所以看到的画面还是会有一定的延迟
		}
	}
	/**
     * BufferedImage转IplImage
     * @param bufferedImageAPI
     * @return
     */
    private static IplImage BufImgToIplData(BufferedImage bufferedImageAPI) {
    	IplImage iplImage = null;
    	ToIplImage iplConverter = new OpenCVFrameConverter.ToIplImage();
    	Java2DFrameConverter java2dConverter = new Java2DFrameConverter();
    	iplImage = iplConverter.convert(java2dConverter.convert(bufferedImageAPI));
		return iplImage;
	}
	/**
     * IplImage 转 BufferedImage
     * @param mat
     * @return BufferedImage
     */
	public static BufferedImage iplToBufImgData(IplImage mat) {
		if (mat.height() > 0 && mat.width() > 0) {
			//TYPE_3BYTE_BGR 表示一个具有 8 位 RGB 颜色分量的图像,对应于 Windows 风格的 BGR 颜色模型,具有用 3 字节存储的 Blue、Green 和 Red 三种颜色。 
			BufferedImage image = new BufferedImage(mat.width(), mat.height(),BufferedImage.TYPE_3BYTE_BGR);
			WritableRaster raster = image.getRaster();
			DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
			byte[] data = dataBuffer.getData();
			BytePointer bytePointer = new BytePointer(data);
			mat.imageData(bytePointer);
			return image;
		}
		return null;
	}
	/**
     * 接口结果转bufferimage
     * @param result
     * @return BufferedImage
     * @throws Exception 
     */
    private static BufferedImage getAPIResult(String result) throws Exception {
    	JSONObject object = JSONObject.parseObject(result);
    	BufferedImage bufferedImage = null;
    	if(object.getInteger("person_num")>=1){
    		Decoder decoder = Base64.getDecoder();
    		byte [] b = decoder.decode(object.getString("image"));
    		ByteArrayInputStream in = new ByteArrayInputStream(b);  
    		bufferedImage = ImageIO.read(in); 
    		
    		ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    		ImageIO.write(bufferedImage,"jpg", baos); 
    		 byte[] imageInByte = baos.toByteArray(); 
            // Base64解码
    		for (int i = 0; i < imageInByte.length; ++i) {
    			if (imageInByte[i] < 0) {// 调整异常数据
    				imageInByte[i] += 256;
    			}
    		 }
    		 OutputStream out = new FileOutputStream("G:/testimg/xiaoshuairesult.jpg");//接口返回的渲染图
    		 out.write(imageInByte);
    		 out.flush();
    		 out.close();
    		return bufferedImage;
    	}else{
    		return null;
    	}
	}
	/**
	 * 获取接口处理结果图
	 * @param bufferedImage
	 * @return String
	 * @throws Exception
	 */
	public static String getBodyTrack(BufferedImage bufferedImage) throws Exception{
		 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
         ImageIO.write(bufferedImage,"jpg",baos); 
         byte[] imageInByte = baos.toByteArray(); 
         Encoder base64 = Base64.getEncoder();
         String imageBase64 = base64.encodeToString(imageInByte);
        // Base64解码
		for (int i = 0; i < imageInByte.length; ++i) {
			if (imageInByte[i] < 0) {// 调整异常数据
				imageInByte[i] += 256;
			}
		 }
		 // 生成jpeg图片
		 OutputStream out = new FileOutputStream("G:/testimg/xiaoshuai.jpg");// 新生成的图片
		 out.write(imageInByte);
		 out.flush();
		 out.close();
		 System.out.println("保存成功");  
		 baos.flush();       
		 baos.close();
         String access_token = ACCESS_TOKEN;
         String case_id = "2018";
         String case_init = "true";
         String area = "10,10,630,10,630,470,10,469";
		 String params = "image=" + URLEncoder.encode(imageBase64, "utf-8")
				+ "&dynamic=true&show=true&case_id=" + case_id
				+ "&case_init="+case_init +"&area="+area;
         //静态识别
//		 String params = "image=" + URLEncoder.encode(imageBase64, "utf-8")+"&dynamic=false&show=true";
 		 String result = HttpUtil.post(BODY_TRACKING_URL, access_token, params);
 		 System.out.println("接口内容==>"+result);
		 return result;
	}
	/**
     * IplImage 转 BufferedImage
     * @param mat
     * @return BufferedImage
     */
	public static BufferedImage bufferimgToBase64(IplImage mat) {
		if (mat.height() > 0 && mat.width() > 0) {
			BufferedImage image = new BufferedImage(mat.width(), mat.height(),BufferedImage.TYPE_3BYTE_BGR);
			WritableRaster raster = image.getRaster();
			DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
			byte[] data = dataBuffer.getData();
			BytePointer bytePointer = new BytePointer(data);
			mat.imageData(bytePointer);
			return image;
		}
		return null;
	}
}
  • 摄像头中的内容截图示意(本人头像就不直接显示了。万一吓着大家呢) 也不要用去马赛克的技术还原图片哦。

原 荐 Java基于百度AI+JavaCV+OpenCV 实现摄像头人数动态统计

还是很好玩的、不需要自己去整OpenCV一套就能实现统计摄像头中的人数。

原 荐 Java基于百度AI+JavaCV+OpenCV 实现摄像头人数动态统计

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

PHP and MySQL Web Development

PHP and MySQL Web Development

Luke Welling、Laura Thomson / Sams / July 25, 2007 / $49.99

Book Description PHP and MySQL Web Development teaches you to develop dynamic, secure, commerical Web sites. Using the same accessible, popular teaching style of the three previous editions, this b......一起来看看 《PHP and MySQL Web Development》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

随机密码生成器
随机密码生成器

多种字符组合密码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具