java Bufferdimage與opencv Mat在內存中的轉化

之前寫Java人臉識別爬蟲的時候遇到的問題,最先的時候是用tempfile的形式去解決識別的問題,每個爬蟲線程爬取圖片到本地,保存爲tempfile,而後opencv再讀取出來作處理和識別,可是這樣涉及磁盤io,爬蟲性能異常緩慢,因此後面思考了一段時間琢磨出來再內存裏面對圖像進行轉化,本質上,圖像數據對Java來講都是bytes[]串,因此個人轉化過程的思路,就是把byte串取出來,從新組裝。
opencv Mat轉BufferImagejava

public static BufferedImage toBufferedImage(Mat matrix) {
        int type = BufferedImage.TYPE_BYTE_GRAY;
        if (matrix.channels() > 1) {
            type = BufferedImage.TYPE_3BYTE_BGR;
        }
        int bufferSize = matrix.channels() * matrix.cols() * matrix.rows();
        byte[] buffer = new byte[bufferSize];
        matrix.get(0, 0, buffer); // get all pixel from martix
        BufferedImage image = new BufferedImage(matrix.cols(), matrix.rows(), type);
        final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
        System.arraycopy(buffer, 0, targetPixels, 0, buffer.length);
        return image;
    }

BufferImage轉爲opencv Mat數組

public static Mat bufferToMartix(BufferedImage image) {
        Mat mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC3);
        byte[] data = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
        if (mat != null) {
            try {
                mat.put(0, 0, data);
            } catch (Exception e) {
                return null;
            }
        }
        return mat;
    }

byte數組轉opencv Mat函數

public static Mat bufferToMartix(byte[] image) throws IOException {
        BufferedImage bImage = ImageIO.read(new ByteArrayInputStream(image));
        byte[] bytes = ((DataBufferByte) bImage.getRaster().getDataBuffer()).getData();
        Mat data = new Mat(bImage.getHeight(), bImage.getWidth(), CvType.CV_8UC3);
        data.put(0, 0, bytes);
        return data;
    }

有意思的是,當我讓一個BufferedImage嵌套爲性能

//這裏假設b_image裏面包含有圖像數據
BufferedImage b_image=b_image=new BufferedImage();
Mat matrix=toBufferedImage(bufferToMartix(b_image))

的時候,JVM機率死掉報出Core Error,因而我分離了這兩個函數避免嵌套使用,沒有去深究這個問題,猜想這可能與JVM的GC(垃圾回收)有關係,並且就算不出現JVM致命錯誤,這樣出來的圖像也是有問題的,會缺失不少數據,而後變成一堆噪聲和一片白,直觀感受就是toBufferedImage調用結束後圖像數據內存就被釋放掉了,當bufferToMartix從後面執行的時候取了一樣大小的內存區塊當作圖像,隨機產生了JVM致命內存衝突,或者不衝突可是數據混亂的問題,由於不是專業Java這個地方還待研究。線程

相關文章
相關標籤/搜索