편집 기록

편집 기록
  • 프로필 알 수 없는 사용자님의 편집
    날짜2018.06.21

    OpenCV를 이용하고있습니다. 전송 데이터 크기를 줄여야 할 것 같은데 도움이 필요합니다.


    라즈베리파이에서 OpenCV를 통해 Mat 객체를 Java Server로 전송하고있습니다.

    클라이언트 일부 코드입니다.

    Mat 객체를 이미지로 변환하고, 이를 다시 버퍼 이미지로 변환하여 서버로 전송시킵니다. 이 과정에서 Mat의 데이터 크기가 보통 이미지

    정도의 크기로 나옵니다.

    public static Image toImage(Mat m) {
    
            // Check if image is grayscale or color
            int type = BufferedImage.TYPE_BYTE_GRAY;
            if (m.channels() > 1) {
                type = BufferedImage.TYPE_3BYTE_BGR;
            }
    
            // Transfer bytes from Mat to BufferedImage
            int bufferSize = m.channels() * m.cols() * m.rows();
            byte[] b = new byte[bufferSize];
            m.get(0, 0, b); // get all the pixels
            BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
            final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
            System.arraycopy(b, 0, targetPixels, 0, b.length);
            return image;
        }
    
        public static BufferedImage toBufferedImage(Image img) {
            if (img instanceof BufferedImage) {
                return (BufferedImage) img;
            }
    
            // Create a buffered image with transparency
            BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
    
            // Draw the image on to the buffered image
            Graphics2D bGr = bimage.createGraphics();
            bGr.drawImage(img, 0, 0, null);
            bGr.dispose();
    
            // Return the buffered image
            return bimage;
        }
    
        public static void main(String[] args) {
            String serverIp = "192.168.0.9";
            Socket socket = null;
    
            try 
            {
                // 서버 연결
                socket = new Socket(serverIp, 1492);
                System.out.println("서버에 연결되었습니다.");
    
                // OutputStream 등록
                OutputStream os = socket.getOutputStream();
                //등록한 OutputStream을 ObjectOutputStream 방식으로 사용합니다.
                DataOutputStream oos;
    
                oos = new DataOutputStream(os);
    
                // Register the default camera
                VideoCapture cap = new VideoCapture(0);
    
                // Check if video capturing is enabled
                if (!cap.isOpened())
                    System.exit(-1);
    
                // Matrix for storing image
                Mat image = new Mat();
                int count = 0;
    
                try {
                    while (true) 
                    {
                        System.out.println("while문 카운트 : " + count );
                        cap.read(image);
                        if (!image.empty()) {
    
                            BufferedImage bimg = toBufferedImage(toImage(image));
    
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            ImageIO.write(bimg, "jpg", baos);
                            byte[] imageInByte = baos.toByteArray();
                            oos.writeInt(imageInByte.length); // write length of the
                                                                // imageInByte
                            oos.write(imageInByte); // write the imageInByte
    
                            //FileSender fs = new FileSender(socket, oos, cap, image, os);
                            //fs.start();
                            baos.close();
                        }
    
                        else {
                            System.out.println("No captured frame -- camera disconnected");
                        }
                        count ++;
                    }
    
                } catch (Exception e) {
                    e.getStackTrace();
                } finally {
                    System.out.println("★클라이언트에서 끈남!!");
                    oos.close();
                    os.close();
                    socket.close();
                }
    
            } 
            catch (Exception e) { e.printStackTrace(); }
        }
    }
    

    그리고, 서버는 이 버퍼 이미지를 다시 이미지로 변환하여 이미지 아이콘으로 변경시켜 화면을 계속 뿌려 줌으로써 부드러운 영상정보를 볼 수 있도록 합니다. 이미지

    while (true) 
                {
                    System.out.println("client accept!");
    
                    is = socket.getInputStream();
    
                    // 등록한 InputStream을 ObjectInputStream방식으로 사용합니다.
                    ois = new DataInputStream(is);
    
                    int length = ois.readInt(); // read length of incoming message
                    byte[] data = null;
    
                    if (length > 0) {
                        data = new byte[length];
                        ois.readFully(data, 0, data.length); // read the message
                    }
    
                    String dirName = "C:\\Users\\안형욱\\workspace\\시스템개발프로젝트1";
                    String fileName = "test.jpg";
    
                    System.out.println("data length : " + data.length);
                    ByteArrayInputStream bais = new ByteArrayInputStream(data);
                    BufferedImage imag = ImageIO.read(bais);
                    //ImageIO.write(imag, "jpg", new File(dirName, fileName));
    
                    cm.setCameraView(imag); // 받은 이미지를 변환후 적용
    
                    // 파일 수신 작업 시작
                    // FileReceiver fr = new FileReceiver(socket, cm);
                    // fr.start();
                    bais.close();
                }
    

    근데제가 올린 코드는 일반 PC 노트북의 카메라를 이용할 경우에는 문제없이 부드러운 화면이 잘나오지만, 라즈베리파이를 사용할 경우에는 뚝뚝 끊기듯 나오는 경우가 발생합니다. 이유는 성능 문제라고 생각합니다. 아무래도 라즈베리 파이가 성능이 PC만큼 좋지가 않기때문이라고 생각합니다.

    그래서, 본론을 말씀드리자면 OpenCV에서 Mat의 픽셀이나 데이터에 접근을해서 전체적으로 보내는 데이터 크기를 줄여서 보낼 수 있는 방법이 있을까 싶어서 질문드립니다.

    만약 이 방법 말고 다른 방법으로 라즈베리파이에서 끊기는 문제는 해결할 수 있는지도 알 수 있으면 좋을것 같습니다. 답변부탁드려요~~~ 꼭!!! ㅠㅠㅠㅠ...!!

    코드는 자바로 된 코드로 알려주시면 좋을것 같습니다...! 부탁드립니다..!

  • 프로필 허대영(소프트웨어융합대학)님의 편집
    날짜2016.08.21

    OpenCV를 이용하고있습니다. 전송 데이터 크기를 줄여야 할 것 같은데 도움이 필요합니다.


    라즈베리파이에서 OpenCV를 통해 Mat 객체를 Java Server로 전송하고있습니다.

    클라이언트 일부 코드입니다.

    Mat 객체를 이미지로 변환하고, 이를 다시 버퍼 이미지로 변환하여 서버로 전송시킵니다. 이 과정에서 Mat의 데이터 크기가 보통 이미지

    정도의 크기로 나옵니다.

    public static Image toImage(Mat m) {
    
            // Check if image is grayscale or color
            int type = BufferedImage.TYPE_BYTE_GRAY;
            if (m.channels() > 1) {
                type = BufferedImage.TYPE_3BYTE_BGR;
            }
    
            // Transfer bytes from Mat to BufferedImage
            int bufferSize = m.channels() * m.cols() * m.rows();
            byte[] b = new byte[bufferSize];
            m.get(0, 0, b); // get all the pixels
            BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
            final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
            System.arraycopy(b, 0, targetPixels, 0, b.length);
            return image;
        }
    
        public static BufferedImage toBufferedImage(Image img) {
            if (img instanceof BufferedImage) {
                return (BufferedImage) img;
            }
    
            // Create a buffered image with transparency
            BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
    
            // Draw the image on to the buffered image
            Graphics2D bGr = bimage.createGraphics();
            bGr.drawImage(img, 0, 0, null);
            bGr.dispose();
    
            // Return the buffered image
            return bimage;
        }
    
        public static void main(String[] args) {
            String serverIp = "192.168.0.9";
            Socket socket = null;
    
            try 
            {
                // 서버 연결
                socket = new Socket(serverIp, 1492);
                System.out.println("서버에 연결되었습니다.");
    
                // OutputStream 등록
                OutputStream os = socket.getOutputStream();
                //등록한 OutputStream을 ObjectOutputStream 방식으로 사용합니다.
                DataOutputStream oos;
    
                oos = new DataOutputStream(os);
    
                // Register the default camera
                VideoCapture cap = new VideoCapture(0);
    
                // Check if video capturing is enabled
                if (!cap.isOpened())
                    System.exit(-1);
    
                // Matrix for storing image
                Mat image = new Mat();
                int count = 0;
    
                try {
                    while (true) 
                    {
                        System.out.println("while문 카운트 : " + count );
                        cap.read(image);
                        if (!image.empty()) {
    
                            BufferedImage bimg = toBufferedImage(toImage(image));
    
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            ImageIO.write(bimg, "jpg", baos);
                            byte[] imageInByte = baos.toByteArray();
                            oos.writeInt(imageInByte.length); // write length of the
                                                                // imageInByte
                            oos.write(imageInByte); // write the imageInByte
    
                            //FileSender fs = new FileSender(socket, oos, cap, image, os);
                            //fs.start();
                            baos.close();
                        }
    
                        else {
                            System.out.println("No captured frame -- camera disconnected");
                        }
                        count ++;
                    }
    
                } catch (Exception e) {
                    e.getStackTrace();
                } finally {
                    System.out.println("★클라이언트에서 끈남!!");
                    oos.close();
                    os.close();
                    socket.close();
                }
    
            } 
            catch (Exception e) { e.printStackTrace(); }
        }
    }
    

    그리고, 서버는 이 버퍼 이미지를 다시 이미지로 변환하여 이미지 아이콘으로 변경시켜 화면을 계속 뿌려 줌으로써 부드러운 영상정보를 볼 수 있도록 합니다. 이미지

    while (true) 
                {
                    System.out.println("client accept!");
    
                    is = socket.getInputStream();
    
                    // 등록한 InputStream을 ObjectInputStream방식으로 사용합니다.
                    ois = new DataInputStream(is);
    
                    int length = ois.readInt(); // read length of incoming message
                    byte[] data = null;
    
                    if (length > 0) {
                        data = new byte[length];
                        ois.readFully(data, 0, data.length); // read the message
                    }
    
                    String dirName = "C:\\Users\\안형욱\\workspace\\시스템개발프로젝트1";
                    String fileName = "test.jpg";
    
                    System.out.println("data length : " + data.length);
                    ByteArrayInputStream bais = new ByteArrayInputStream(data);
                    BufferedImage imag = ImageIO.read(bais);
                    //ImageIO.write(imag, "jpg", new File(dirName, fileName));
    
                    cm.setCameraView(imag); // 받은 이미지를 변환후 적용
    
                    // 파일 수신 작업 시작
                    // FileReceiver fr = new FileReceiver(socket, cm);
                    // fr.start();
                    bais.close();
                }
    

    근데제가 올린 코드는 일반 PC 노트북의 카메라를 이용할 경우에는 문제없이 부드러운 화면이 잘나오지만, 라즈베리파이를 사용할 경우에는 뚝뚝 끊기듯 나오는 경우가 발생합니다. 이유는 성능 문제라고 생각합니다. 아무래도 라즈베리 파이가 성능이 PC만큼 좋지가 않기때문이라고 생각합니다.

    그래서, 본론을 말씀드리자면 OpenCV에서 Mat의 픽셀이나 데이터에 접근을해서 전체적으로 보내는 데이터 크기를 줄여서 보낼 수 있는 방법이 있을까 싶어서 질문드립니다.

    만약 이 방법 말고 다른 방법으로 라즈베리파이에서 끊기는 문제는 해결할 수 있는지도 알 수 있으면 좋을것 같습니다. 답변부탁드려요~~~ 꼭!!! ㅠㅠㅠㅠ...!!

    코드는 자바로 된 코드로 알려주시면 좋을것 같습니다...! 부탁드립니다..!

  • 프로필 알 수 없는 사용자님의 편집
    날짜2016.08.20

    OpenCV를 이용하고있습니다. 전송 데이터 크기를 줄여야 할 것 같은데 도움이 필요합니다.


    라즈베리파이에서 OpenCV를 통해 Mat 객체를 Java Server로 전송하고있습니다.

    클라이언트 일부 코드입니다.

    Mat 객체를 이미지로 변환하고, 이를 다시 버퍼 이미지로 변환하여 서버로 전송시킵니다. 이 과정에서 Mat의 데이터 크기가 보통 이미지

    정도의 크기로 나옵니다.

    public static Image toImage(Mat m) {

        // Check if image is grayscale or color
        int type = BufferedImage.TYPE_BYTE_GRAY;
        if (m.channels() > 1) {
            type = BufferedImage.TYPE_3BYTE_BGR;
        }
    
        // Transfer bytes from Mat to BufferedImage
        int bufferSize = m.channels() * m.cols() * m.rows();
        byte[] b = new byte[bufferSize];
        m.get(0, 0, b); // get all the pixels
        BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
        final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
        System.arraycopy(b, 0, targetPixels, 0, b.length);
        return image;
    }
    
    public static BufferedImage toBufferedImage(Image img) {
        if (img instanceof BufferedImage) {
            return (BufferedImage) img;
        }
    
        // Create a buffered image with transparency
        BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
    
        // Draw the image on to the buffered image
        Graphics2D bGr = bimage.createGraphics();
        bGr.drawImage(img, 0, 0, null);
        bGr.dispose();
    
        // Return the buffered image
        return bimage;
    }
    
    public static void main(String[] args) {
        String serverIp = "192.168.0.9";
        Socket socket = null;
    
        try 
        {
            // 서버 연결
            socket = new Socket(serverIp, 1492);
            System.out.println("서버에 연결되었습니다.");
    
            // OutputStream 등록
            OutputStream os = socket.getOutputStream();
            //등록한 OutputStream을 ObjectOutputStream 방식으로 사용합니다.
            DataOutputStream oos;
    
            oos = new DataOutputStream(os);
    
            // Register the default camera
            VideoCapture cap = new VideoCapture(0);
    
            // Check if video capturing is enabled
            if (!cap.isOpened())
                System.exit(-1);
    
            // Matrix for storing image
            Mat image = new Mat();
            int count = 0;
    
            try {
                while (true) 
                {
                    System.out.println("while문 카운트 : " + count );
                    cap.read(image);
                    if (!image.empty()) {
    
                        BufferedImage bimg = toBufferedImage(toImage(image));
    
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        ImageIO.write(bimg, "jpg", baos);
                        byte[] imageInByte = baos.toByteArray();
                        oos.writeInt(imageInByte.length); // write length of the
                                                            // imageInByte
                        oos.write(imageInByte); // write the imageInByte
    
                        //FileSender fs = new FileSender(socket, oos, cap, image, os);
                        //fs.start();
                        baos.close();
                    }
    
                    else {
                        System.out.println("No captured frame -- camera disconnected");
                    }
                    count ++;
                }
    
            } catch (Exception e) {
                e.getStackTrace();
            } finally {
                System.out.println("★클라이언트에서 끈남!!");
                oos.close();
                os.close();
                socket.close();
            }
    
        } 
        catch (Exception e) { e.printStackTrace(); }
    }
    

    }

    그리고, 서버는 이 버퍼 이미지를 다시 이미지로 변환하여 이미지 아이콘으로 변경시켜 화면을 계속 뿌려 줌으로써 부드러운 영상정보를 볼 수 있도록 합니다. 이미지 while (true) { System.out.println("client accept!");

                is = socket.getInputStream();
    
                // 등록한 InputStream을 ObjectInputStream방식으로 사용합니다.
                ois = new DataInputStream(is);
    
                int length = ois.readInt(); // read length of incoming message
                byte[] data = null;
    
                if (length > 0) {
                    data = new byte[length];
                    ois.readFully(data, 0, data.length); // read the message
                }
    
                String dirName = "C:\\Users\\안형욱\\workspace\\시스템개발프로젝트1";
                String fileName = "test.jpg";
    
                System.out.println("data length : " + data.length);
                ByteArrayInputStream bais = new ByteArrayInputStream(data);
                BufferedImage imag = ImageIO.read(bais);
                //ImageIO.write(imag, "jpg", new File(dirName, fileName));
    
                cm.setCameraView(imag); // 받은 이미지를 변환후 적용
    
                // 파일 수신 작업 시작
                // FileReceiver fr = new FileReceiver(socket, cm);
                // fr.start();
                bais.close();
            }
    

    근데제가 올린 코드는 일반 PC 노트북의 카메라를 이용할 경우에는 문제없이 부드러운 화면이 잘나오지만, 라즈베리파이를 사용할 경우에는 뚝뚝 끊기듯 나오는 경우가 발생합니다. 이유는 성능 문제라고 생각합니다. 아무래도 라즈베리 파이가 성능이 PC만큼 좋지가 않기때문이라고 생각합니다.

    그래서, 본론을 말씀드리자면 OpenCV에서 Mat의 픽셀이나 데이터에 접근을해서 전체적으로 보내는 데이터 크기를 줄여서 보낼 수 있는 방법이 있을까 싶어서 질문드립니다.

    만약 이 방법 말고 다른 방법으로 라즈베리파이에서 끊기는 문제는 해결할 수 있는지도 알 수 있으면 좋을것 같습니다. 답변부탁드려요~~~ 꼭!!! ㅠㅠㅠㅠ...!!

    코드는 자바로 된 코드로 알려주시면 좋을것 같습니다...! 부탁드립니다..!