java - 使用 OpenCV 和 Java 从 gif 帧中获取 Mats

标签 java opencv image-processing

我正在尝试使用 OpenCV 从 gif 中获取帧。我发现Convert each animated GIF frame to a separate BufferedImage并使用了第二个建议。我稍微修改了它以返回 Mats 数组而不是 BufferedImages。

我尝试了两种方法从 gif 中获取 bufferedImages。每个都提出了不同的问题。

  1. 根据上一个线程的建议

    BufferedImage fImage=ir.read(i);
    

    程序调用“ArrayIndexOutOfBoundsException:4096”

  2. 使用上一个线程的原始代码。

    BufferedImage fImage=ir.getRawImageType(i).createBufferedImage(ir.getWidth(i),ir.getHeight(i));
    

    每一帧都是单调颜色(但不是全黑),并且从 BufferedImage 派生的垫子是空的。

    System.loadLibrary( Core.NATIVE_LIBRARY_NAME );
    ArrayList<Mat> frames = new ArrayList<Mat>();
    ImageReader ir = new GIFImageReader(new GIFImageReaderSpi());
    ir.setInput(ImageIO.createImageInputStream(new File("ronPaulTestImage.gif")));
    
    for(int i = 0; i < ir.getNumImages(true); i++){
        BufferedImage fImage=ir.read(i);
        //BufferedImage fImage=ir.getRawImageType(i).createBufferedImage(ir.getWidth(i), ir.getHeight(i));
    
        fImage = toBufferedImageOfType(fImage, BufferedImage.TYPE_3BYTE_BGR);
        //byte[] pixels = ((DataBufferByte) r.getRaster().getDataBuffer()).getData();
        Mat m=new Mat();
        //m.put(0,0,pixels);
        m.put(0, 0,((DataBufferByte) fImage.getRaster().getDataBuffer()).getData());
    
        if(i==40){
        //a test, writes the mat and the image at the specified frame to files, exits
            ImageIO.write(fImage,"jpg",new File("TestError.jpg"));
            Imgcodecs.imwrite("TestErrorMat.jpg",m);
            System.exit(0);
    }
    

这是gif I used

  • test gif

最佳答案

根据 Spektre 的建议,我找到了一个更好的 gif,它修复了单色 bufferedImages。缺少可见的 Mats 是由于我在声明 Mat 时使用了默认构造函数造成的。

工作代码

    public static ArrayList<Mat> getFrames(File gif) throws IOException{
    ArrayList<Mat> frames = new ArrayList<Mat>();
    ImageReader ir = new GIFImageReader(new GIFImageReaderSpi());
    ir.setInput(ImageIO.createImageInputStream(gif));
    for(int i = 0; i < ir.getNumImages(true); i++){
        BufferedImage fImage=ir.read(i);
        fImage = toBufferedImageOfType(fImage, BufferedImage.TYPE_3BYTE_BGR);
        byte[] pixels = ((DataBufferByte) fImage.getRaster().getDataBuffer()).getData();
        Mat m=new Mat(fImage.getHeight(), fImage.getWidth(), CvType.CV_8UC3);
        m.put(0,0,pixels);
        if(i==15){//a test, writes the mat and the image at the specified frame to files, exits
            ImageIO.write(fImage,"jpg",new File("TestError.jpg"));
            Imgcodecs.imwrite("TestErrorMat.jpg",m);
            System.exit(0);
        }
        frames.add(m);
        }
    return frames;
}

关于java - 使用 OpenCV 和 Java 从 gif 帧中获取 Mats,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30429780/

相关文章:

通过 Jersey 发送请求时出现 javax.ws.rs.ProcessingException

python - python OpenCV(cv2)putText方法中的中文编码

python - 在Raspberry Pi 3上设置virtualenv和virtualenvwrapper时出现问题

ios - 如何像 Apple Music 处理专辑封面那样从图像中获取背景和文本颜色?

java - 使用 jobjectarray 中的参数调用 NewObject 方法 jni

java - 将 7M 行的 CSV 文件解析为 Java 对象时出现 OutOfMemory

字符串中的Java正则表达式replaceAll : negative look ahead does not work as expected

image-processing - OpenCV:高效高斯差分

java - Android 5 中的图像内存不足

图像配准(非刚性\非线性)