javabufferedimagejavacviplimage

JavaCV - Why IplImage.createFrom(image) doesn't exist anymore?


I'm working with JavaCV at the moment, to try some simple blob detection. I'm using maven and got JavaCV 0.11 (more specific org.bytedeco.javacv) from their repositories. Everything compiles without errors and works fine, but the method to create an IplImage from an BufferedImage seems like it doesn't exist. Eclipse says

The method createFrom(BufferedImage) is undefined for the type opencv_core.IplImage

I have no idea what the problem is because everything works fine except this one method so far.


Solution

  • The reason...

    JavaCV 0.11 has introduced the concept of FrameConverter.

    The goal is to don't create unecessary coupling between an application using JavaCV and another API (FFmpeg, Java 2D...).

    Instead, JavaCV uses Frame class instances for storing audio samples or video image data. Those frames can be later shared between various APIs thanks to FrameConverters.

    See more: JavaCV Frame Converters

    The workaround...

    It's always possible copy and paste the code of the createFrom method into your own code or refactor it using FrameConverters.

    Below is the (not compiled) code of the method taken from the source repository:

    public static IplImage createFrom(BufferedImage image) {
        return createFrom(image, 1.0);
    }
    
    public static IplImage createFrom(BufferedImage image, double gamma) {
        return createFrom(image, gamma, false);
    }
    
    public static IplImage createFrom(BufferedImage image, double gamma, boolean flipChannels) {
        if (image == null) {
            return null;
        }
        SampleModel sm = image.getSampleModel();
        int depth = 0, numChannels = sm.getNumBands();
        switch (image.getType()) {
            case BufferedImage.TYPE_INT_RGB:
            case BufferedImage.TYPE_INT_ARGB:
            case BufferedImage.TYPE_INT_ARGB_PRE:
            case BufferedImage.TYPE_INT_BGR:
                depth = IPL_DEPTH_8U;
                numChannels = 4;
                break;
        }
        if (depth == 0 || numChannels == 0) {
            switch (sm.getDataType()) {
                case DataBuffer.TYPE_BYTE:   depth = IPL_DEPTH_8U;  break;
                case DataBuffer.TYPE_USHORT: depth = IPL_DEPTH_16U; break;
                case DataBuffer.TYPE_SHORT:  depth = IPL_DEPTH_16S; break;
                case DataBuffer.TYPE_INT:    depth = IPL_DEPTH_32S; break;
                case DataBuffer.TYPE_FLOAT:  depth = IPL_DEPTH_32F; break;
                case DataBuffer.TYPE_DOUBLE: depth = IPL_DEPTH_64F; break;
                default: assert false;
            }
        }
        IplImage i = create(image.getWidth(), image.getHeight(), depth, numChannels);
        i.copyFrom(image, gamma, flipChannels);
        return i;
    }
    

    Reference: opencv_core.java