CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-bytedeco--libdc1394

JavaCPP Presets for libdc1394 - Java bindings for controlling IEEE 1394 (FireWire) digital cameras following IIDC/DCAM specifications

Pending
Overview
Eval results
Files

image-conversion.mddocs/

Image Conversion

Built-in image format conversion including Bayer pattern demosaicing, color space conversion, and stereo processing for libdc1394.

Capabilities

Bayer Pattern Demosaicing

Converts raw Bayer pattern images to RGB color images using various interpolation algorithms.

/**
 * Demosaics 8-bit Bayer pattern data to RGB
 * @param bayer Input Bayer pattern data
 * @param rgb Output RGB data buffer (3x size of input)
 * @param sx Image width in pixels
 * @param sy Image height in pixels
 * @param tile Bayer tile pattern (DC1394_COLOR_FILTER_*)
 * @param method Demosaicing method (DC1394_BAYER_METHOD_*)
 * @return DC1394_SUCCESS on success, error code on failure
 */
int dc1394_bayer_decoding_8bit(BytePointer bayer, BytePointer rgb, int sx, int sy, 
                              int tile, int method);

/**
 * Demosaics 16-bit Bayer pattern data to RGB
 * @param bayer Input 16-bit Bayer pattern data
 * @param rgb Output 16-bit RGB data buffer (3x size of input)
 * @param sx Image width in pixels
 * @param sy Image height in pixels
 * @param tile Bayer tile pattern (DC1394_COLOR_FILTER_*)
 * @param method Demosaicing method (DC1394_BAYER_METHOD_*)
 * @param bits Actual bit depth of input data (8-16)
 * @return DC1394_SUCCESS on success, error code on failure
 */
int dc1394_bayer_decoding_16bit(ShortPointer bayer, ShortPointer rgb, int sx, int sy, 
                               int tile, int method, int bits);

Usage Example:

import org.bytedeco.libdc1394.*;
import static org.bytedeco.libdc1394.global.dc1394.*;
import org.bytedeco.javacpp.*;

// Capture RAW frame and convert to RGB
dc1394video_frame_t frame = new dc1394video_frame_t(null);
dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_WAIT, frame);

if (frame.color_coding() == DC1394_COLOR_CODING_RAW8) {
    int width = frame.size(0);
    int height = frame.size(1);
    
    // Allocate RGB output buffer (3x larger than input)
    BytePointer rgbData = new BytePointer(width * height * 3);
    
    // Perform Bayer demosaicing
    int err = dc1394_bayer_decoding_8bit(
        frame.image(),                    // Input Bayer data
        rgbData,                         // Output RGB buffer
        width, height,                   // Image dimensions
        frame.color_filter(),            // Bayer tile pattern
        DC1394_BAYER_METHOD_BILINEAR     // Demosaicing algorithm
    );
    
    if (err == DC1394_SUCCESS) {
        System.out.println("Bayer demosaicing successful");
        System.out.println("RGB data size: " + (width * height * 3) + " bytes");
        
        // Use RGB data...
        processRGBImage(rgbData, width, height);
    }
    
    rgbData.deallocate();
}

dc1394_capture_enqueue(camera, frame);

Frame-Based Conversion

High-level conversion functions that operate on complete frame structures.

/**
 * Demosaics a complete video frame from Bayer to RGB
 * @param in Input frame with Bayer data
 * @param out Output frame for RGB data (must be pre-allocated)
 * @param method Demosaicing method (DC1394_BAYER_METHOD_*)
 * @return DC1394_SUCCESS on success, error code on failure
 */
int dc1394_debayer_frames(dc1394video_frame_t in, dc1394video_frame_t out, int method);

/**
 * Converts between different color formats
 * @param in Input frame
 * @param out Output frame (must be pre-allocated with correct format)
 * @return DC1394_SUCCESS on success, error code on failure
 */
int dc1394_convert_frames(dc1394video_frame_t in, dc1394video_frame_t out);

Usage Example:

// High-level frame conversion
dc1394video_frame_t inputFrame = new dc1394video_frame_t(null);
dc1394video_frame_t outputFrame = new dc1394video_frame_t(null);

dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_WAIT, inputFrame);

if (inputFrame.color_coding() == DC1394_COLOR_CODING_RAW8) {
    // Allocate output frame for RGB data
    int width = inputFrame.size(0);
    int height = inputFrame.size(1);
    long rgbBytes = width * height * 3;
    
    BytePointer rgbBuffer = new BytePointer(rgbBytes);
    
    // Setup output frame structure
    outputFrame.image(rgbBuffer);
    outputFrame.total_bytes(rgbBytes);
    outputFrame.image_bytes(rgbBytes);
    outputFrame.size(0, width);
    outputFrame.size(1, height);
    outputFrame.color_coding(DC1394_COLOR_CODING_RGB8);
    
    // Perform frame-based debayering
    int err = dc1394_debayer_frames(inputFrame, outputFrame, DC1394_BAYER_METHOD_VNG);
    if (err == DC1394_SUCCESS) {
        System.out.println("Frame debayering completed");
    }
    
    rgbBuffer.deallocate();
}

dc1394_capture_enqueue(camera, inputFrame);

Color Format Conversion

Converts between different color formats (YUV, RGB, Monochrome).

/**
 * Converts image data to YUV422 format
 * @param src Source image data
 * @param dest Destination buffer
 * @param width Image width
 * @param height Image height
 * @param byte_order Byte order (DC1394_BYTE_ORDER_*)
 * @param source_coding Source color coding
 * @param bits Bit depth
 * @return DC1394_SUCCESS on success, error code on failure
 */
int dc1394_convert_to_YUV422(BytePointer src, BytePointer dest, int width, int height, 
                             int byte_order, int source_coding, int bits);

/**
 * Converts image data to RGB8 format
 * @param src Source image data
 * @param dest Destination buffer
 * @param width Image width
 * @param height Image height
 * @param byte_order Byte order
 * @param source_coding Source color coding
 * @param bits Bit depth
 * @return DC1394_SUCCESS on success, error code on failure
 */
int dc1394_convert_to_RGB8(BytePointer src, BytePointer dest, int width, int height, 
                           int byte_order, int source_coding, int bits);

/**
 * Converts image data to MONO8 format
 * @param src Source image data
 * @param dest Destination buffer
 * @param width Image width
 * @param height Image height
 * @param byte_order Byte order
 * @param source_coding Source color coding
 * @param bits Bit depth
 * @return DC1394_SUCCESS on success, error code on failure
 */
int dc1394_convert_to_MONO8(BytePointer src, BytePointer dest, int width, int height, 
                            int byte_order, int source_coding, int bits);

Usage Example:

// Convert YUV422 to RGB8
dc1394video_frame_t frame = new dc1394video_frame_t(null);
dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_WAIT, frame);

if (frame.color_coding() == DC1394_COLOR_CODING_YUV422) {
    int width = frame.size(0);
    int height = frame.size(1);
    
    // YUV422 uses 2 bytes per pixel, RGB8 uses 3
    BytePointer rgbBuffer = new BytePointer(width * height * 3);
    
    int err = dc1394_convert_to_RGB8(
        frame.image(),                    // Source YUV422 data
        rgbBuffer,                       // Destination RGB buffer
        width, height,                   // Dimensions
        DC1394_BYTE_ORDER_UYVY,         // YUV byte order
        DC1394_COLOR_CODING_YUV422,     // Source format
        8                               // Bit depth
    );
    
    if (err == DC1394_SUCCESS) {
        System.out.println("YUV422 to RGB8 conversion successful");
        // Use RGB data...
    }
    
    rgbBuffer.deallocate();
}

dc1394_capture_enqueue(camera, frame);

Stereo Image Processing

Processes stereo image pairs and deinterlaced stereo data.

/**
 * Deinterlaces stereo image data (line-interleaved)
 * @param src Source interleaved stereo data
 * @param dest Destination buffers for left and right images
 * @param width Image width
 * @param height Total height (both images)
 * @param bpp Bytes per pixel
 * @return DC1394_SUCCESS on success, error code on failure
 */
int dc1394_deinterlace_stereo(BytePointer src, BytePointer dest, int width, int height, int bpp);

/**
 * Deinterlaces stereo frame data
 * @param in Input stereo frame
 * @param out1 Output frame for first camera
 * @param out2 Output frame for second camera
 * @return DC1394_SUCCESS on success, error code on failure
 */
int dc1394_deinterlace_stereo_frames(dc1394video_frame_t in, dc1394video_frame_t out1, 
                                    dc1394video_frame_t out2);

Low-Level Color Space Conversion

Direct color space conversion functions for custom processing.

/**
 * Converts YUV to RGB (inline function)
 * @param y Y component
 * @param u U component  
 * @param v V component
 * @param r Output R component
 * @param g Output G component
 * @param b Output B component
 */
void YUV2RGB(int y, int u, int v, IntPointer r, IntPointer g, IntPointer b);

/**
 * Converts RGB to YUV (inline function)
 * @param r R component
 * @param g G component
 * @param b B component
 * @param y Output Y component
 * @param u Output U component
 * @param v Output V component
 */
void RGB2YUV(int r, int g, int b, IntPointer y, IntPointer u, IntPointer v);

Constants

Bayer Demosaicing Methods

// Quality vs speed tradeoff methods
static final int DC1394_BAYER_METHOD_NEAREST = 0;      // Fastest, lowest quality
static final int DC1394_BAYER_METHOD_SIMPLE = 1;       // Simple interpolation
static final int DC1394_BAYER_METHOD_BILINEAR = 2;     // Good quality/speed balance
static final int DC1394_BAYER_METHOD_HQLINEAR = 3;     // High-quality linear
static final int DC1394_BAYER_METHOD_DOWNSAMPLE = 4;   // Downsample for speed
static final int DC1394_BAYER_METHOD_EDGESENSE = 5;    // Edge-aware interpolation
static final int DC1394_BAYER_METHOD_VNG = 6;          // Variable Number of Gradients (high quality)
static final int DC1394_BAYER_METHOD_AHD = 7;          // Adaptive Homogeneity-Directed (best quality)

// Method range
static final int DC1394_BAYER_METHOD_MIN = DC1394_BAYER_METHOD_NEAREST;
static final int DC1394_BAYER_METHOD_MAX = DC1394_BAYER_METHOD_AHD;
static final int DC1394_BAYER_METHOD_NUM = (DC1394_BAYER_METHOD_MAX - DC1394_BAYER_METHOD_MIN + 1);

Color Filter Patterns

// Bayer color filter arrangements
static final int DC1394_COLOR_FILTER_RGGB = 512;       // Red-Green-Green-Blue
static final int DC1394_COLOR_FILTER_GBRG = 513;       // Green-Blue-Red-Green
static final int DC1394_COLOR_FILTER_GRBG = 514;       // Green-Red-Blue-Green
static final int DC1394_COLOR_FILTER_BGGR = 515;       // Blue-Green-Green-Red

// Color filter range
static final int DC1394_COLOR_FILTER_MIN = DC1394_COLOR_FILTER_RGGB;
static final int DC1394_COLOR_FILTER_MAX = DC1394_COLOR_FILTER_BGGR;
static final int DC1394_COLOR_FILTER_NUM = (DC1394_COLOR_FILTER_MAX - DC1394_COLOR_FILTER_MIN + 1);

Byte Order Constants

// YUV byte ordering
static final int DC1394_BYTE_ORDER_UYVY = 800;         // U-Y-V-Y ordering
static final int DC1394_BYTE_ORDER_YUYV = 801;         // Y-U-Y-V ordering

// General byte order
static final int DC1394_LITTLE_ENDIAN = 802;           // Little endian byte order
static final int DC1394_BIG_ENDIAN = 803;              // Big endian byte order

Bayer Method Comparison

Quality vs Performance

  • NEAREST: Fastest, produces blocky artifacts
  • SIMPLE: Basic averaging, some color fringing
  • BILINEAR: Good general-purpose option
  • HQLINEAR: Better edge preservation
  • VNG: Excellent quality, moderate speed
  • AHD: Best quality, slowest processing

Algorithm Selection Guidelines

// Algorithm selection based on application needs
int selectBayerMethod(String application) {
    switch (application) {
        case "realtime":
            return DC1394_BAYER_METHOD_BILINEAR;  // Good speed/quality balance
        case "preview":
            return DC1394_BAYER_METHOD_SIMPLE;    // Fast preview
        case "scientific":
            return DC1394_BAYER_METHOD_AHD;       // Best quality
        case "mobile":
            return DC1394_BAYER_METHOD_NEAREST;   // Fastest for mobile
        case "photography":
            return DC1394_BAYER_METHOD_VNG;       // High quality
        default:
            return DC1394_BAYER_METHOD_BILINEAR;  // Default choice
    }
}

Advanced Conversion Workflows

Complete RAW Processing Pipeline

// Complete RAW image processing workflow
void processRAWImage(dc1394video_frame_t rawFrame) {
    if (rawFrame.color_coding() != DC1394_COLOR_CODING_RAW8) {
        System.err.println("Frame is not RAW format");
        return;
    }
    
    int width = rawFrame.size(0);
    int height = rawFrame.size(1);
    
    // Step 1: Demosaic Bayer pattern to RGB
    BytePointer rgbData = new BytePointer(width * height * 3);
    
    int err = dc1394_bayer_decoding_8bit(
        rawFrame.image(),
        rgbData,
        width, height,
        rawFrame.color_filter(),
        DC1394_BAYER_METHOD_VNG  // High quality
    );
    
    if (err != DC1394_SUCCESS) {
        System.err.println("Bayer demosaicing failed: " + err);
        rgbData.deallocate();
        return;
    }
    
    System.out.println("RAW processing completed:");
    System.out.println("  Input: " + width + "x" + height + " RAW8");
    System.out.println("  Output: " + width + "x" + height + " RGB8");
    System.out.println("  Algorithm: VNG");
    System.out.println("  Bayer pattern: " + getBayerPatternName(rawFrame.color_filter()));
    
    // Step 2: Additional processing (optional)
    // - White balance correction
    // - Gamma correction  
    // - Color space conversion
    // - Noise reduction
    
    // Step 3: Save or display result
    saveRGBImage(rgbData, width, height, "output.ppm");
    
    rgbData.deallocate();
}

String getBayerPatternName(int pattern) {
    switch (pattern) {
        case DC1394_COLOR_FILTER_RGGB: return "RGGB";
        case DC1394_COLOR_FILTER_GBRG: return "GBRG";  
        case DC1394_COLOR_FILTER_GRBG: return "GRBG";
        case DC1394_COLOR_FILTER_BGGR: return "BGGR";
        default: return "Unknown";
    }
}

Multi-Format Conversion

// Convert any supported format to RGB8
BytePointer convertToRGB8(dc1394video_frame_t frame) {
    int width = frame.size(0);
    int height = frame.size(1);
    int colorCoding = frame.color_coding();
    
    BytePointer rgbBuffer = new BytePointer(width * height * 3);
    
    switch (colorCoding) {
        case DC1394_COLOR_CODING_RGB8:
            // Already RGB8, direct copy
            frame.image().get(rgbBuffer.asBuffer());
            break;
            
        case DC1394_COLOR_CODING_RAW8:
            // Demosaic Bayer pattern
            dc1394_bayer_decoding_8bit(frame.image(), rgbBuffer, 
                                      width, height, 
                                      frame.color_filter(),
                                      DC1394_BAYER_METHOD_BILINEAR);
            break;
            
        case DC1394_COLOR_CODING_YUV422:
            // Convert YUV to RGB
            dc1394_convert_to_RGB8(frame.image(), rgbBuffer,
                                  width, height,
                                  DC1394_BYTE_ORDER_UYVY,
                                  colorCoding, 8);
            break;
            
        case DC1394_COLOR_CODING_MONO8:
            // Convert monochrome to RGB (replicate channels)
            convertMono8ToRGB8(frame.image(), rgbBuffer, width, height);
            break;
            
        default:
            System.err.println("Unsupported color format: " + colorCoding);
            rgbBuffer.deallocate();
            return null;
    }
    
    return rgbBuffer;
}

void convertMono8ToRGB8(BytePointer mono, BytePointer rgb, int width, int height) {
    int pixels = width * height;
    for (int i = 0; i < pixels; i++) {
        byte value = mono.get(i);
        rgb.put(i * 3, value);     // R
        rgb.put(i * 3 + 1, value); // G  
        rgb.put(i * 3 + 2, value); // B
    }
}

Performance Optimization

// Optimized conversion with memory reuse
class ImageConverter {
    private BytePointer rgbBuffer;
    private BytePointer tempBuffer;
    private int bufferWidth = 0;
    private int bufferHeight = 0;
    
    public BytePointer convertFrame(dc1394video_frame_t frame) {
        int width = frame.size(0);
        int height = frame.size(1);
        
        // Reallocate buffers only if size changed
        if (width != bufferWidth || height != bufferHeight) {
            deallocateBuffers();
            allocateBuffers(width, height);
        }
        
        // Perform conversion using pre-allocated buffers
        switch (frame.color_coding()) {
            case DC1394_COLOR_CODING_RAW8:
                dc1394_bayer_decoding_8bit(frame.image(), rgbBuffer,
                                          width, height,
                                          frame.color_filter(),
                                          DC1394_BAYER_METHOD_BILINEAR);
                break;
                
            case DC1394_COLOR_CODING_YUV422:
                dc1394_convert_to_RGB8(frame.image(), rgbBuffer,
                                      width, height,
                                      DC1394_BYTE_ORDER_UYVY,
                                      frame.color_coding(), 8);
                break;
                
            // ... other formats
        }
        
        return rgbBuffer;
    }
    
    private void allocateBuffers(int width, int height) {
        rgbBuffer = new BytePointer(width * height * 3);
        tempBuffer = new BytePointer(width * height * 4); // For intermediate conversions
        bufferWidth = width;
        bufferHeight = height;
    }
    
    private void deallocateBuffers() {
        if (rgbBuffer != null) {
            rgbBuffer.deallocate();
            rgbBuffer = null;
        }
        if (tempBuffer != null) {
            tempBuffer.deallocate();
            tempBuffer = null;
        }
    }
    
    public void cleanup() {
        deallocateBuffers();
    }
}

Image Quality Considerations

Bayer Pattern Handling

  • Check color filter: Always use correct Bayer pattern from frame metadata
  • Edge handling: Demosaicing may produce artifacts at image edges
  • Color accuracy: Higher quality methods produce more accurate colors

Color Space Conversion

  • Gamma correction: May need gamma adjustment after RGB conversion
  • White balance: RAW images require white balance correction
  • Color matrix: Professional applications may need custom color matrices

Performance vs Quality

  • Real-time: Use BILINEAR or SIMPLE methods
  • Archival: Use VNG or AHD methods for best quality
  • Batch processing: Consider threading for multiple images

Error Handling and Validation

// Validate conversion parameters
boolean validateConversionParams(dc1394video_frame_t frame, int method) {
    // Check frame validity
    if (frame.image() == null || frame.total_bytes() == 0) {
        System.err.println("Invalid frame data");
        return false;
    }
    
    // Check color coding support
    int coding = frame.color_coding();
    if (coding != DC1394_COLOR_CODING_RAW8 && 
        coding != DC1394_COLOR_CODING_RAW16 &&
        coding != DC1394_COLOR_CODING_YUV422 &&
        coding != DC1394_COLOR_CODING_RGB8) {
        System.err.println("Unsupported color coding: " + coding);
        return false;
    }
    
    // Check method validity
    if (method < DC1394_BAYER_METHOD_MIN || method > DC1394_BAYER_METHOD_MAX) {
        System.err.println("Invalid Bayer method: " + method);
        return false;
    }
    
    // Check dimensions
    if (frame.size(0) <= 0 || frame.size(1) <= 0) {
        System.err.println("Invalid frame dimensions");
        return false;
    }
    
    return true;
}

Install with Tessl CLI

npx tessl i tessl/maven-org-bytedeco--libdc1394

docs

camera-features.md

format7.md

image-conversion.md

index.md

iso-resource-management.md

logging.md

system-management.md

trigger-control.md

utility-functions.md

video-capture.md

video-modes.md

tile.json