zoukankan      html  css  js  c++  java
  • Java 调用OpenCV获取图像数据,发送Redis并从Redis获取数据显示

    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 + "
    
    
    
    
    ");
                    } 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() {
            //Java窗口容器
            JFrame frame = new JFrame("camera");
            frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            //Java画板容器
            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 {
    
        /**
         * Mat转换成BufferedImage
         *
         * @param matrix        要转换的Mat
         * @param fileExtension 格式为 ".jpg", ".png", etc
         * @return
         */
        public static BufferedImage Mat2BufImg(Mat matrix, String fileExtension) {
            // convert the matrix into a matrix of bytes appropriate for
            // this file extension
            MatOfByte mob = new MatOfByte();
            Imgcodecs.imencode(fileExtension, matrix, mob);
            // convert the "matrix of bytes" into a byte array
            byte[] byteArray = mob.toArray();
            BufferedImage bufImage = null;
            try {
                InputStream in = new ByteArrayInputStream(byteArray);
                bufImage = ImageIO.read(in);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return bufImage;
        }
    
        /**
         * BufferedImage转换成Mat
         *
         * @param original 要转换的BufferedImage
         * @param imgType  bufferedImage的类型 如 BufferedImage.TYPE_3BYTE_BGR
         * @param matType  转换成mat的type 如 CvType.CV_8UC3
         */
        public static Mat BufImg2Mat(BufferedImage original, int imgType, int matType) {
            if (original == null) {
                throw new IllegalArgumentException("original == null");
            }
    
            // Don't convert if it already has correct type
            if (original.getType() != imgType) {
    
                // Create a buffered image
                BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), imgType);
    
                // Draw the image onto the new buffer
                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;
        }
    
        /**
         * 将图片转换成十六进制字符串
         *
         * @param bufferedImage BufferedImage图片流
         * @param format        参数format表示图片的格式,比如jpg等
         */
        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);
                // return new BigInteger(1, bytes).toString(16);
            } 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) {
            // Mat grayMatData = new Mat();
            // cvtColor(rgbData,grayMatData,COLOR_RGB2GRAY);
            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;
        }
    
        // Convert image to Mat
        public Mat matify(BufferedImage bufferedImage) {
            // Convert INT to BYTE
            //im = new BufferedImage(im.getWidth(), im.getHeight(),BufferedImage.TYPE_3BYTE_BGR);
            // Convert bufferedimage to byte array
            byte[] pixels = ((DataBufferByte) bufferedImage.getRaster().getDataBuffer()).getData();
            // Create a Matrix the same size of image
            Mat mat = new Mat(bufferedImage.getHeight(), bufferedImage.getWidth(), CvType.CV_8UC3);
            // Fill Matrix with image values
            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;
    
        /*读取jedis.properties配置文件*/
        static {
            // ResourceBundle rb = ResourceBundle.getBundle("jedis");
            // maxtotal = Integer.parseInt(rb.getString("maxtotal"));
            // maxwaitmillis = Integer.parseInt(rb.getString("maxwaitmillis"));
            // host = rb.getString("host");
            // port = Integer.parseInt(rb.getString("port"));
            JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
            jedisPoolConfig.setMaxTotal(maxtotal);
            jedisPoolConfig.setMaxWaitMillis(maxwaitmillis);
            jedisPool = new JedisPool(jedisPoolConfig, host, port);
        }
    
        /*获取jedis*/
        public static Jedis getJedis() {
            return jedisPool.getResource();
        }
    
        /*关闭Jedis*/
        public static void close(Jedis jedis) {
            if (jedis != null) {
                jedis.shutdown();
            }
        }
    }
    

    5、HexUtils

    /**
     * 16进制字符串 与 byte数组 相互转换工具类
     */
    public class HexUtils {
    
        private static final char[] HEXES = {
                '0', '1', '2', '3',
                '4', '5', '6', '7',
                '8', '9', 'a', 'b',
                'c', 'd', 'e', 'f'
        };
    
        /**
         * byte数组 转换成 16进制小写字符串
         */
        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();
        }
    
        /**
         * 16进制字符串 转换为对应的 byte数组
         */
        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];   // 如果 hex 中的字符不是偶数个, 则忽略最后一个
    
            for (int i = 0; i < bytes.length; i++) {
                bytes[i] = (byte) Integer.parseInt("" + hexChars[i * 2] + hexChars[i * 2 + 1], 16);
            }
    
            return bytes;
        }
    
    }
    
  • 相关阅读:
    [Sql Server][原创]
    SQL Server T-SQL高级查询
    SQL 网文链接
    Epicor系统二次开发
    lambda表达式的变量作用域
    写一个正则表达式匹配手机号
    函数装饰器在类方法中的使用方法
    关于Django的session的使用 (装饰器版)
    Django ORM相关操作(2)
    Django ORM相关操作(1)
  • 原文地址:https://www.cnblogs.com/kikyoqiang/p/14548232.html
Copyright © 2011-2022 走看看