All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bytedeco.javacv.FlyCaptureFrameGrabber Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2009-2012 Samuel Audet
 *
 * Licensed either under the Apache License, Version 2.0, or (at your option)
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation (subject to the "Classpath" exception),
 * either version 2, or any later version (collectively, the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *     http://www.gnu.org/licenses/
 *     http://www.gnu.org/software/classpath/license.html
 *
 * or as provided in the LICENSE.txt file that accompanied this code.
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.bytedeco.javacv;

import java.io.File;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ShortBuffer;
import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.Loader;

import org.bytedeco.flycapture.PGRFlyCapture.*;
import org.bytedeco.opencv.opencv_core.*;
import org.bytedeco.opencv.opencv_imgproc.*;
import static org.bytedeco.flycapture.global.PGRFlyCapture.*;
import static org.bytedeco.opencv.global.opencv_core.*;
import static org.bytedeco.opencv.global.opencv_imgproc.*;

/**
 *
 * @author Samuel Audet
 */
public class FlyCaptureFrameGrabber extends FrameGrabber {
    public static String[] getDeviceDescriptions() throws Exception {
        tryLoad();

        int[] count = new int[1];
        int error = flycaptureBusCameraCount(count);
        if (error != FLYCAPTURE_OK) {
            throw new Exception("flycaptureBusCameraCount() Error " + error);
        }
        int c = count[0];
        String[] descriptions = new String[c];

        if (c > 0) {
            FlyCaptureInfoEx info = new FlyCaptureInfoEx(c);
            error = flycaptureBusEnumerateCamerasEx(info, count);
            if (error != FLYCAPTURE_OK) {
                throw new Exception("flycaptureBusEnumerateCamerasEx() Error " + error);
            }

            for (int i = 0; i < descriptions.length; i++) {
                info.position(i);
                descriptions[i] = info.pszVendorName() + " " +
                        info.pszModelName() + " " + info.SerialNumber();
            }
        }

        return descriptions;
    }

    public static FlyCaptureFrameGrabber createDefault(File deviceFile)   throws Exception { throw new Exception(FlyCaptureFrameGrabber.class + " does not support device files."); }
    public static FlyCaptureFrameGrabber createDefault(String devicePath) throws Exception { throw new Exception(FlyCaptureFrameGrabber.class + " does not support device paths."); }
    public static FlyCaptureFrameGrabber createDefault(int deviceNumber)  throws Exception { return new FlyCaptureFrameGrabber(deviceNumber); }

    private static Exception loadingException = null;
    public static void tryLoad() throws Exception {
        if (loadingException != null) {
            throw loadingException;
        } else {
            try {
                Loader.load(org.bytedeco.javacpp.PGRFlyCapture.class);
            } catch (Throwable t) {
                throw loadingException = new Exception("Failed to load " + FlyCaptureFrameGrabber.class, t);
            }
        }
    }

    public FlyCaptureFrameGrabber(int deviceNumber) throws Exception {
        int error = flycaptureCreateContext(context);
        if (error != FLYCAPTURE_OK) {
            throw new Exception("flycaptureCreateContext() Error " + error);
        }
        error = flycaptureInitializePlus(context, deviceNumber, numBuffers, (BytePointer)null);
        if (error != FLYCAPTURE_OK) {
            throw new Exception("flycaptureInitialize() Error " + error);
        }
    }
    public void release() throws Exception {
        if (context != null) {
            stop();
            int error = flycaptureDestroyContext(context);
            context = null;
            if (error != FLYCAPTURE_OK) {
                throw new Exception("flycaptureDestroyContext() Error " + error);
            }
        }
    }
    @Override protected void finalize() throws Throwable {
        super.finalize();
        release();
    }

    public static final int
            INITIALIZE         = 0x000,
            TRIGGER_INQ        = 0x530,
            IS_CAMERA_POWER    = 0x400,
            CAMERA_POWER       = 0x610,
            SOFTWARE_TRIGGER   = 0x62C,
            SOFT_ASYNC_TRIGGER = 0x102C,
            IMAGE_DATA_FORMAT  = 0x1048;

    private FlyCaptureContext context = new FlyCaptureContext(null);
    private FlyCaptureImage raw_image = new FlyCaptureImage();
    private FlyCaptureImage conv_image = new FlyCaptureImage();
    private IplImage temp_image, return_image = null;
    private FrameConverter converter = new OpenCVFrameConverter.ToIplImage();
    private final int[] regOut = new int[1];
    private final float[] outFloat = new float[1];
    private final float[] gammaOut = new float[1];

    @Override public double getGamma() {
        return Float.isNaN(gammaOut[0]) || Float.isInfinite(gammaOut[0]) || gammaOut[0] == 0.0f ? 2.2 : gammaOut[0];
    }

    @Override public int getImageWidth() {
        return return_image == null ? super.getImageWidth() : return_image.width();
    }

    @Override public int getImageHeight() {
        return return_image == null ? super.getImageHeight() : return_image.height();
    }

    @Override public double getFrameRate() {
        if (context == null || context.isNull()) {
            return super.getFrameRate();
        } else {
            flycaptureGetCameraAbsProperty(context, FLYCAPTURE_FRAME_RATE, outFloat);
            return outFloat[0];
        }
    }

    @Override public void setImageMode(ImageMode imageMode) {
        if (imageMode != this.imageMode) {
            temp_image = null;
            return_image = null;
        }
        super.setImageMode(imageMode);
    }

    public void start() throws Exception {
        int f = FLYCAPTURE_FRAMERATE_ANY;
        if (frameRate <= 0) {
            f = FLYCAPTURE_FRAMERATE_ANY;
        } else if (frameRate <= 1.876) {
            f = FLYCAPTURE_FRAMERATE_1_875;
        } else if (frameRate <= 3.76) {
            f = FLYCAPTURE_FRAMERATE_3_75;
        } else if (frameRate <= 7.51) {
            f = FLYCAPTURE_FRAMERATE_7_5;
        } else if (frameRate <= 15.01) {
            f = FLYCAPTURE_FRAMERATE_15;
        } else if (frameRate <= 30.01) {
            f = FLYCAPTURE_FRAMERATE_30;
        } else if (frameRate <= 60.01) {
            f = FLYCAPTURE_FRAMERATE_60;
        } else if (frameRate <= 120.01) {
            f = FLYCAPTURE_FRAMERATE_120;
        } else if (frameRate <= 240.01) {
            f = FLYCAPTURE_FRAMERATE_240;
        }

        int c = FLYCAPTURE_VIDEOMODE_ANY;
        if (imageMode == ImageMode.COLOR || imageMode == ImageMode.RAW) {
            if (imageWidth <= 0 || imageHeight <= 0) {
                c = FLYCAPTURE_VIDEOMODE_ANY;
            } else if (imageWidth <= 640 && imageHeight <= 480) {
                c = FLYCAPTURE_VIDEOMODE_640x480RGB;
            } else if (imageWidth <= 800 && imageHeight <= 600) {
                c = FLYCAPTURE_VIDEOMODE_800x600RGB;
            } else if (imageWidth <= 1024 && imageHeight <= 768) {
                c = FLYCAPTURE_VIDEOMODE_1024x768RGB;
            } else if (imageWidth <= 1280 && imageHeight <= 960) {
                c = FLYCAPTURE_VIDEOMODE_1280x960RGB;
            } else if (imageWidth <= 1600 && imageHeight <= 1200) {
                c = FLYCAPTURE_VIDEOMODE_1600x1200RGB;
            }
        } else if (imageMode == ImageMode.GRAY) {
            if (imageWidth <= 0 || imageHeight <= 0) {
                c = FLYCAPTURE_VIDEOMODE_ANY;
            } else if (imageWidth <= 640 && imageHeight <= 480) {
                c = bpp > 8 ? FLYCAPTURE_VIDEOMODE_640x480Y16 : FLYCAPTURE_VIDEOMODE_640x480Y8;
            } else if (imageWidth <= 800 && imageHeight <= 600) {
                c = bpp > 8 ? FLYCAPTURE_VIDEOMODE_800x600Y16 : FLYCAPTURE_VIDEOMODE_800x600Y8;
            } else if (imageWidth <= 1024 && imageHeight <= 768) {
                c = bpp > 8 ? FLYCAPTURE_VIDEOMODE_1024x768Y16 : FLYCAPTURE_VIDEOMODE_1024x768Y8;
            } else if (imageWidth <= 1280 && imageHeight <= 960) {
                c = bpp > 8 ? FLYCAPTURE_VIDEOMODE_1280x960Y16 : FLYCAPTURE_VIDEOMODE_1280x960Y8;
            } else if (imageWidth <= 1600 && imageHeight <= 1200) {
                c = bpp > 8 ? FLYCAPTURE_VIDEOMODE_1600x1200Y16 : FLYCAPTURE_VIDEOMODE_1600x1200Y8;
            }
        }

        // set or reset trigger mode
        int[] iPolarity = new int[1];
        int[] iSource   = new int[1];
        int[] iRawValue = new int[1];
        int[] iMode     = new int[1];
        int error = flycaptureGetTrigger(context, (boolean[])null, iPolarity, iSource, iRawValue, iMode, null);
        if (error != FLYCAPTURE_OK) {
            throw new Exception("flycaptureGetTrigger() Error " + error);
        }
        error = flycaptureSetTrigger(context, triggerMode, iPolarity[0], 7, 14, 0);
        if (error != FLYCAPTURE_OK) {
            // try with trigger mode 0 instead
            error = flycaptureSetTrigger(context, true, iPolarity[0], 7, 0, 0);
        }
        if (error != FLYCAPTURE_OK) {
            throw new Exception("flycaptureSetTrigger() Error " + error);
        }
        if (triggerMode) {
            waitForTriggerReady();
        }

        // try to match the endianness to our platform
        error = flycaptureGetCameraRegister(context, IMAGE_DATA_FORMAT, regOut);
        if (error != FLYCAPTURE_OK) {
            throw new Exception("flycaptureGetCameraRegister() Error " + error);
        }
        int reg;
        if (ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN)) {
            reg = regOut[0] | 0x1;
        } else {
            reg = regOut[0] & ~0x1;
        }
        error = flycaptureSetCameraRegister(context, IMAGE_DATA_FORMAT, reg);
        if (error != FLYCAPTURE_OK) {
            throw new Exception("flycaptureSetCameraRegister() Error " + error);
        }

        error = flycaptureSetBusSpeed(context, FLYCAPTURE_S_FASTEST, FLYCAPTURE_S_FASTEST);
        if (error != FLYCAPTURE_OK) {
            error = flycaptureSetBusSpeed(context,
                    FLYCAPTURE_ANY, FLYCAPTURE_ANY);
            if (error != FLYCAPTURE_OK) {
                throw new Exception("flycaptureSetBusSpeed() Error " + error);
            }
        }

        if (gamma != 0.0) {
            error = flycaptureSetCameraAbsProperty(context, FLYCAPTURE_GAMMA, (float)gamma);
            if (error != FLYCAPTURE_OK) {
                throw new Exception("flycaptureSetCameraAbsProperty() Error " + error + ": Could not set gamma.");
            }
        }
        error = flycaptureGetCameraAbsProperty(context, FLYCAPTURE_GAMMA, gammaOut);
        if (error != FLYCAPTURE_OK) {
            gammaOut[0] = 2.2f;
        }

        error = flycaptureStart(context, c, f);
        if (error != FLYCAPTURE_OK) {
            throw new Exception("flycaptureStart() Error " + error);
        }
        error = flycaptureSetGrabTimeoutEx(context, timeout);
        if (error != FLYCAPTURE_OK) {
            throw new Exception("flycaptureSetGrabTimeoutEx() Error " + error);
        }
    }

    private void waitForTriggerReady() throws Exception {
        // wait for trigger to be ready...
        long time = System.currentTimeMillis();
        do {
            int error = flycaptureGetCameraRegister(context, SOFTWARE_TRIGGER, regOut);
            if (error != FLYCAPTURE_OK) {
                throw new Exception("flycaptureGetCameraRegister() Error " + error);
            }
            if (System.currentTimeMillis() - time > timeout) {
                break;
                //throw new Exception("waitForTriggerReady() Error: Timeout occured.");
            }
        } while((regOut[0] >>> 31) != 0);
    }

    public void stop() throws Exception {
        int error = flycaptureStop(context);
        if (error != FLYCAPTURE_OK && error != FLYCAPTURE_FAILED) {
            throw new Exception("flycaptureStop() Error " + error);
        }
        temp_image    = null;
        return_image  = null;
        timestamp   = 0;
        frameNumber = 0;
    }

    public void trigger() throws Exception {
        waitForTriggerReady();
        int error = flycaptureSetCameraRegister(context, SOFT_ASYNC_TRIGGER, 0x80000000);
        if (error != FLYCAPTURE_OK) {
            throw new Exception("flycaptureSetCameraRegister() Error " + error);
        }
    }

    private int getNumChannels(int pixelFormat) {
        switch (pixelFormat) {
            case FLYCAPTURE_BGR:
            case FLYCAPTURE_RGB8:
            case FLYCAPTURE_RGB16:
            case FLYCAPTURE_S_RGB16:
                return 3;

            case FLYCAPTURE_MONO8:
            case FLYCAPTURE_MONO16:
            case FLYCAPTURE_RAW8:
            case FLYCAPTURE_RAW16:
            case FLYCAPTURE_S_MONO16:
                return 1;

            case FLYCAPTURE_BGRU:
                return 4;

            case FLYCAPTURE_411YUV8:
            case FLYCAPTURE_422YUV8:
            case FLYCAPTURE_444YUV8:
            default:
                return -1;
        }
    }
    private int getDepth(int pixelFormat) {
        switch (pixelFormat) {
            case FLYCAPTURE_BGR:
            case FLYCAPTURE_RGB8:
            case FLYCAPTURE_MONO8:
            case FLYCAPTURE_RAW8:
            case FLYCAPTURE_BGRU:
                return IPL_DEPTH_8U;

            case FLYCAPTURE_MONO16:
            case FLYCAPTURE_RAW16:
            case FLYCAPTURE_RGB16:
                return IPL_DEPTH_16U;

            case FLYCAPTURE_S_MONO16:
            case FLYCAPTURE_S_RGB16:
                return IPL_DEPTH_16S;

            case FLYCAPTURE_411YUV8:
            case FLYCAPTURE_422YUV8:
            case FLYCAPTURE_444YUV8:
            default:
                return IPL_DEPTH_8U;
        }
    }

    public Frame grab() throws Exception {
        int error = flycaptureGrabImage2(context, raw_image);
        if (error != FLYCAPTURE_OK) {
            throw new Exception("flycaptureGrabImage2() Error " + error + " (Has start() been called?)");
        }

        int w = raw_image.iCols();
        int h = raw_image.iRows();
        int format = raw_image.pixelFormat();
        int depth = getDepth(format);
        int stride = raw_image.iRowInc();
        int size = h*stride;
        int numChannels = getNumChannels(format);
        error = flycaptureGetCameraRegister(context, IMAGE_DATA_FORMAT, regOut);
        if (error != FLYCAPTURE_OK) {
            throw new Exception("flycaptureGetCameraRegister() Error " + error);
        }
        ByteOrder frameEndian = (regOut[0] & 0x1) != 0 ?
                ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
        boolean alreadySwapped = false;
        boolean colorbayer = raw_image.bStippled();
        boolean colorrgb = format == FLYCAPTURE_RGB8 || format == FLYCAPTURE_RGB16 ||
                           format == FLYCAPTURE_BGR  || format == FLYCAPTURE_BGRU;
        boolean coloryuv = format == FLYCAPTURE_411YUV8 || format == FLYCAPTURE_422YUV8 ||
                           format == FLYCAPTURE_444YUV8;
        BytePointer imageData = raw_image.pData();

        if ((depth == IPL_DEPTH_8U || frameEndian.equals(ByteOrder.nativeOrder())) &&
                (imageMode == ImageMode.RAW || (imageMode == ImageMode.COLOR && numChannels == 3) ||
                (imageMode == ImageMode.GRAY && numChannels == 1 && !colorbayer))) {
            if (return_image == null) {
                return_image = IplImage.createHeader(w, h, depth, numChannels);
            }
            return_image.widthStep(stride);
            return_image.imageSize(size);
            return_image.imageData(imageData);
        } else {
            if (return_image == null) {
                return_image = IplImage.create(w, h, depth, imageMode == ImageMode.COLOR ? 3 : 1);
            }
            if (temp_image == null) {
                if (imageMode == ImageMode.COLOR &&
                        (numChannels > 1 || depth > 8) && !coloryuv && !colorbayer) {
                    temp_image = IplImage.create(w, h, depth, numChannels);
                } else if (imageMode == ImageMode.GRAY && colorbayer) {
                    temp_image = IplImage.create(w, h, depth, 3);
                } else if (imageMode == ImageMode.GRAY && colorrgb) {
                    temp_image = IplImage.createHeader(w, h, depth, 3);
                } else if (imageMode == ImageMode.COLOR && numChannels == 1 && !coloryuv && !colorbayer) {
                    temp_image = IplImage.createHeader(w, h, depth, 1);
                } else {
                    temp_image = return_image;
                }
            }
            conv_image.iRowInc(temp_image.widthStep());
            conv_image.pData(temp_image.imageData());
            if (depth == IPL_DEPTH_8U) {
                conv_image.pixelFormat(imageMode == ImageMode.RAW ? FLYCAPTURE_RAW8 :
                                       temp_image.nChannels() == 1  ? FLYCAPTURE_MONO8 : FLYCAPTURE_BGR);
            } else {
                conv_image.pixelFormat(imageMode == ImageMode.RAW ? FLYCAPTURE_RAW16 :
                                       temp_image.nChannels() == 1  ? FLYCAPTURE_MONO16 : FLYCAPTURE_RGB16);
            }

            if (depth != IPL_DEPTH_8U && conv_image.pixelFormat() == format && conv_image.iRowInc() == stride) {
                // we just need a copy to swap bytes..
                ShortBuffer in  = raw_image.getByteBuffer().order(frameEndian).asShortBuffer();
                ShortBuffer out = temp_image.getByteBuffer().order(ByteOrder.nativeOrder()).asShortBuffer();
                out.put(in);
                alreadySwapped = true;
            } else if ((imageMode == ImageMode.GRAY && colorrgb) ||
                    (imageMode == ImageMode.COLOR && numChannels == 1 && !coloryuv && !colorbayer)) {
                temp_image.widthStep(stride);
                temp_image.imageSize(size);
                temp_image.imageData(imageData);
            } else if (!colorrgb && (colorbayer || coloryuv || numChannels > 1)) {
                error = flycaptureConvertImage(context, raw_image, conv_image);
                if (error != FLYCAPTURE_OK) {
                    throw new Exception("flycaptureConvertImage() Error " + error);
                }
            }

            if (!alreadySwapped && depth != IPL_DEPTH_8U &&
                    !frameEndian.equals(ByteOrder.nativeOrder())) {
                // ack, the camera's endianness doesn't correspond to our machine ...
                // swap bytes of 16-bit images
                ByteBuffer  bb  = temp_image.getByteBuffer();
                ShortBuffer in  = bb.order(frameEndian).asShortBuffer();
                ShortBuffer out = bb.order(ByteOrder.nativeOrder()).asShortBuffer();
                out.put(in);
            }

            if (imageMode == ImageMode.COLOR && numChannels == 1 && !coloryuv && !colorbayer) {
                cvCvtColor(temp_image, return_image, CV_GRAY2BGR);
            } else if (imageMode == ImageMode.GRAY && (colorbayer || colorrgb)) {
                cvCvtColor(temp_image, return_image, CV_BGR2GRAY);
            }
        }

        error = flycaptureGetColorTileFormat(context, regOut);
        if (error != FLYCAPTURE_OK) {
            sensorPattern = -1L;
        } else switch (regOut[0]) {
            case FLYCAPTURE_STIPPLEDFORMAT_BGGR: sensorPattern = SENSOR_PATTERN_BGGR; break;
            case FLYCAPTURE_STIPPLEDFORMAT_GBRG: sensorPattern = SENSOR_PATTERN_GBRG; break;
            case FLYCAPTURE_STIPPLEDFORMAT_GRBG: sensorPattern = SENSOR_PATTERN_GRBG; break;
            case FLYCAPTURE_STIPPLEDFORMAT_RGGB: sensorPattern = SENSOR_PATTERN_RGGB; break;
            default: sensorPattern = -1L;
        }

        FlyCaptureTimestamp timeStamp = raw_image.timeStamp();
        timestamp = timeStamp.ulSeconds() * 1000000L + timeStamp.ulMicroSeconds();
        return converter.convert(return_image);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy