0、前言
项目需要读取摄像头的数据,并经过AI模型计算发送界面显示,因考虑到需要处理的摄像头过多,需要提高可移植性、通用性
目前采用 从OpenCV读取摄像头图像,发送到Redis服务器
1、jar包
| commons-pool2-2.4.2.jar |
| jedis-2.9.0.jar |
| opencv-440.jar |
| |
2、RedisTes
| import org.opencv.core.Mat; |
| import org.opencv.videoio.VideoCapture; |
| import org.opencv.videoio.Videoio; |
| import redis.clients.jedis.Jedis; |
| |
| import java.awt.image.BufferedImage; |
| import java.util.*; |
| import java.util.Timer; |
| |
| public class RedisTest{ |
| private static Jedis jedis; |
| private static final String ip = "192.168.1.62"; |
| private BufferedImage mImg; |
| |
| static { |
| jedis = new Jedis("localhost"); |
| System.out.println("连接成功"); |
| System.load("D:\\Program\\opencv\\build\\java\\x64\\opencv_java440.dll"); |
| } |
| |
| public static void main(String[] args) throws Exception { |
| sendToRedis(); |
| } |
| |
| private static void sendToRedis() { |
| VideoCapture capture = new VideoCapture(); |
| capture.open("rtsp://admin:password@" + ip + ":554/stream0"); |
| int height = (int) capture.get(Videoio.CAP_PROP_FRAME_HEIGHT); |
| int width = (int) capture.get(Videoio.CAP_PROP_FRAME_WIDTH); |
| if (height == 0 || width == 0) { |
| System.out.println("camera not found!"); |
| return; |
| } |
| Mat capImg = new Mat(); |
| |
| Timer timer = new Timer(); |
| timer.schedule(new TimerTask() { |
| @Override |
| public void run() { |
| Jedis jedis = null; |
| try { |
| capture.read(capImg); |
| if (capImg.empty()) { |
| capture.release(); |
| capture.open("rtsp://admin:bjlthy123@" + ip + ":554/stream0"); |
| return; |
| } |
| BufferedImage bufferedImage = Mat2BufImg.Mat2BufImg(capImg, ".jpg"); |
| String imgHex = Mat2BufImg.imageToHex(bufferedImage, "jpg"); |
| jedis = JedisUtil.getJedis(); |
| jedis.getSet(ip, imgHex); |
| System.out.println(imgHex + "\r\n\n\n\n\n"); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } finally { |
| if (jedis != null) { |
| jedis.close(); |
| } |
| } |
| } |
| }, 0, 100); |
| } |
| } |
2、RedisTestShow
| import redis.clients.jedis.Jedis; |
| |
| import javax.swing.*; |
| import java.awt.*; |
| import java.awt.image.BufferedImage; |
| import java.util.Timer; |
| import java.util.TimerTask; |
| |
| public class RedisTestShow extends JPanel { |
| private static Jedis jedis; |
| private static final String ip = "192.168.1.62"; |
| private BufferedImage mImg; |
| |
| static { |
| jedis = new Jedis("localhost"); |
| System.out.println("连接成功"); |
| System.load("D:\\Program\\opencv\\build\\java\\x64\\opencv_java440.dll"); |
| } |
| |
| public static void main(String[] args) throws Exception { |
| getFromRedis(); |
| } |
| |
| private static void getFromRedis() { |
| |
| JFrame frame = new JFrame("camera"); |
| frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); |
| |
| RedisTestShow panel = new RedisTestShow(); |
| |
| frame.setContentPane(panel); |
| frame.setVisible(true); |
| frame.setSize(1280 + frame.getInsets().left + frame.getInsets().right, 720 + frame.getInsets().top + frame.getInsets().bottom); |
| |
| Timer timer = new Timer(); |
| timer.schedule(new TimerTask() { |
| @Override |
| public void run() { |
| try { |
| String imgHex = jedis.get(ip); |
| BufferedImage bufferedImage = Mat2BufImg.hexToImage(imgHex); |
| panel.mImg = bufferedImage; |
| panel.repaint(); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| }, 0, 100); |
| } |
| |
| @Override |
| public void paintComponent(Graphics g) { |
| if (mImg != null) { |
| g.drawImage(mImg, 0, 0, mImg.getWidth(), mImg.getHeight(), this); |
| } |
| } |
| } |
3、Mat2BufImg
| import org.opencv.core.CvType; |
| import org.opencv.core.Mat; |
| import org.opencv.core.MatOfByte; |
| import org.opencv.imgcodecs.Imgcodecs; |
| |
| import javax.imageio.ImageIO; |
| import java.awt.*; |
| import java.awt.image.BufferedImage; |
| import java.awt.image.DataBufferByte; |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.math.BigInteger; |
| import java.util.List; |
| |
| public class Mat2BufImg { |
| |
| |
| |
| |
| |
| |
| |
| |
| public static BufferedImage Mat2BufImg(Mat matrix, String fileExtension) { |
| |
| |
| MatOfByte mob = new MatOfByte(); |
| Imgcodecs.imencode(fileExtension, matrix, mob); |
| |
| byte[] byteArray = mob.toArray(); |
| BufferedImage bufImage = null; |
| try { |
| InputStream in = new ByteArrayInputStream(byteArray); |
| bufImage = ImageIO.read(in); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| return bufImage; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| public static Mat BufImg2Mat(BufferedImage original, int imgType, int matType) { |
| if (original == null) { |
| throw new IllegalArgumentException("original == null"); |
| } |
| |
| |
| if (original.getType() != imgType) { |
| |
| |
| BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), imgType); |
| |
| |
| Graphics2D g = image.createGraphics(); |
| try { |
| g.setComposite(AlphaComposite.Src); |
| g.drawImage(original, 0, 0, null); |
| } finally { |
| g.dispose(); |
| } |
| } |
| |
| byte[] pixels = ((DataBufferByte) original.getRaster().getDataBuffer()).getData(); |
| Mat mat = Mat.eye(original.getHeight(), original.getWidth(), matType); |
| mat.put(0, 0, pixels); |
| return mat; |
| } |
| |
| |
| |
| |
| |
| |
| |
| public static String imageToHex(BufferedImage bufferedImage, String format) { |
| try { |
| ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
| ImageIO.write(bufferedImage, format, outputStream); |
| byte[] bytes = outputStream.toByteArray(); |
| return HexUtils.bytes2Hex(bytes); |
| |
| } catch (IOException e) { |
| e.printStackTrace(); |
| return null; |
| } |
| } |
| |
| public static BufferedImage hexToImage(String hex) { |
| try { |
| byte[] bytes = HexUtils.hex2Bytes(hex); |
| ByteArrayInputStream in = new ByteArrayInputStream(bytes); |
| BufferedImage image = ImageIO.read(in); |
| return image; |
| } catch (Exception e) { |
| return null; |
| } |
| } |
| |
| |
| public static byte[] matToByte(Mat mat) { |
| |
| |
| byte[] grayData = new byte[mat.cols() * mat.rows()]; |
| mat.get(0, 0, grayData); |
| return grayData; |
| } |
| |
| public static Mat vector_uchar_to_Mat(List<Byte> bs) { |
| Mat res; |
| int count = (bs != null) ? bs.size() : 0; |
| if (count > 0) { |
| res = new Mat(count, 1, CvType.CV_8UC1); |
| byte[] buff = new byte[count]; |
| for (int i = 0; i < count; i++) { |
| byte b = bs.get(i); |
| buff[i] = b; |
| } |
| res.put(0, 0, buff); |
| } else { |
| res = new Mat(); |
| } |
| return res; |
| } |
| |
| |
| public Mat matify(BufferedImage bufferedImage) { |
| |
| |
| |
| byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData(); |
| |
| Mat mat = new Mat(bufferedImage.getHeight(), bufferedImage.getWidth(), CvType.CV_8UC3); |
| |
| mat.put(0, 0, pixels); |
| return mat; |
| } |
| } |
4、JedisUtil
| import redis.clients.jedis.Jedis; |
| import redis.clients.jedis.JedisPool; |
| import redis.clients.jedis.JedisPoolConfig; |
| |
| public final class JedisUtil { |
| private JedisUtil() { |
| } |
| |
| private static JedisPool jedisPool; |
| private static int maxtotal = 1000; |
| private static int maxwaitmillis = 100; |
| private static String host = "127.0.0.1"; |
| private static int port = 6379; |
| |
| |
| static { |
| |
| |
| |
| |
| |
| JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); |
| jedisPoolConfig.setMaxTotal(maxtotal); |
| jedisPoolConfig.setMaxWaitMillis(maxwaitmillis); |
| jedisPool = new JedisPool(jedisPoolConfig, host, port); |
| } |
| |
| |
| public static Jedis getJedis() { |
| return jedisPool.getResource(); |
| } |
| |
| |
| public static void close(Jedis jedis) { |
| if (jedis != null) { |
| jedis.shutdown(); |
| } |
| } |
| } |
5、HexUtils
| |
| |
| |
| public class HexUtils { |
| |
| private static final char[] HEXES = { |
| '0', '1', '2', '3', |
| '4', '5', '6', '7', |
| '8', '9', 'a', 'b', |
| 'c', 'd', 'e', 'f' |
| }; |
| |
| |
| |
| |
| public static String bytes2Hex(byte[] bytes) { |
| if (bytes == null || bytes.length == 0) { |
| return null; |
| } |
| |
| StringBuilder hex = new StringBuilder(); |
| |
| for (byte b : bytes) { |
| hex.append(HEXES[(b >> 4) & 0x0F]); |
| hex.append(HEXES[b & 0x0F]); |
| } |
| |
| return hex.toString(); |
| } |
| |
| |
| |
| |
| public static byte[] hex2Bytes(String hex) { |
| if (hex == null || hex.length() == 0) { |
| return null; |
| } |
| |
| char[] hexChars = hex.toCharArray(); |
| byte[] bytes = new byte[hexChars.length / 2]; |
| |
| for (int i = 0; i < bytes.length; i++) { |
| bytes[i] = (byte) Integer.parseInt("" + hexChars[i * 2] + hexChars[i * 2 + 1], 16); |
| } |
| |
| return bytes; |
| } |
| |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)