0
# Image Conversion
1
2
Built-in image format conversion including Bayer pattern demosaicing, color space conversion, and stereo processing for libdc1394.
3
4
## Capabilities
5
6
### Bayer Pattern Demosaicing
7
8
Converts raw Bayer pattern images to RGB color images using various interpolation algorithms.
9
10
```java { .api }
11
/**
12
* Demosaics 8-bit Bayer pattern data to RGB
13
* @param bayer Input Bayer pattern data
14
* @param rgb Output RGB data buffer (3x size of input)
15
* @param sx Image width in pixels
16
* @param sy Image height in pixels
17
* @param tile Bayer tile pattern (DC1394_COLOR_FILTER_*)
18
* @param method Demosaicing method (DC1394_BAYER_METHOD_*)
19
* @return DC1394_SUCCESS on success, error code on failure
20
*/
21
int dc1394_bayer_decoding_8bit(BytePointer bayer, BytePointer rgb, int sx, int sy,
22
int tile, int method);
23
24
/**
25
* Demosaics 16-bit Bayer pattern data to RGB
26
* @param bayer Input 16-bit Bayer pattern data
27
* @param rgb Output 16-bit RGB data buffer (3x size of input)
28
* @param sx Image width in pixels
29
* @param sy Image height in pixels
30
* @param tile Bayer tile pattern (DC1394_COLOR_FILTER_*)
31
* @param method Demosaicing method (DC1394_BAYER_METHOD_*)
32
* @param bits Actual bit depth of input data (8-16)
33
* @return DC1394_SUCCESS on success, error code on failure
34
*/
35
int dc1394_bayer_decoding_16bit(ShortPointer bayer, ShortPointer rgb, int sx, int sy,
36
int tile, int method, int bits);
37
```
38
39
**Usage Example:**
40
41
```java
42
import org.bytedeco.libdc1394.*;
43
import static org.bytedeco.libdc1394.global.dc1394.*;
44
import org.bytedeco.javacpp.*;
45
46
// Capture RAW frame and convert to RGB
47
dc1394video_frame_t frame = new dc1394video_frame_t(null);
48
dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_WAIT, frame);
49
50
if (frame.color_coding() == DC1394_COLOR_CODING_RAW8) {
51
int width = frame.size(0);
52
int height = frame.size(1);
53
54
// Allocate RGB output buffer (3x larger than input)
55
BytePointer rgbData = new BytePointer(width * height * 3);
56
57
// Perform Bayer demosaicing
58
int err = dc1394_bayer_decoding_8bit(
59
frame.image(), // Input Bayer data
60
rgbData, // Output RGB buffer
61
width, height, // Image dimensions
62
frame.color_filter(), // Bayer tile pattern
63
DC1394_BAYER_METHOD_BILINEAR // Demosaicing algorithm
64
);
65
66
if (err == DC1394_SUCCESS) {
67
System.out.println("Bayer demosaicing successful");
68
System.out.println("RGB data size: " + (width * height * 3) + " bytes");
69
70
// Use RGB data...
71
processRGBImage(rgbData, width, height);
72
}
73
74
rgbData.deallocate();
75
}
76
77
dc1394_capture_enqueue(camera, frame);
78
```
79
80
### Frame-Based Conversion
81
82
High-level conversion functions that operate on complete frame structures.
83
84
```java { .api }
85
/**
86
* Demosaics a complete video frame from Bayer to RGB
87
* @param in Input frame with Bayer data
88
* @param out Output frame for RGB data (must be pre-allocated)
89
* @param method Demosaicing method (DC1394_BAYER_METHOD_*)
90
* @return DC1394_SUCCESS on success, error code on failure
91
*/
92
int dc1394_debayer_frames(dc1394video_frame_t in, dc1394video_frame_t out, int method);
93
94
/**
95
* Converts between different color formats
96
* @param in Input frame
97
* @param out Output frame (must be pre-allocated with correct format)
98
* @return DC1394_SUCCESS on success, error code on failure
99
*/
100
int dc1394_convert_frames(dc1394video_frame_t in, dc1394video_frame_t out);
101
```
102
103
**Usage Example:**
104
105
```java
106
// High-level frame conversion
107
dc1394video_frame_t inputFrame = new dc1394video_frame_t(null);
108
dc1394video_frame_t outputFrame = new dc1394video_frame_t(null);
109
110
dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_WAIT, inputFrame);
111
112
if (inputFrame.color_coding() == DC1394_COLOR_CODING_RAW8) {
113
// Allocate output frame for RGB data
114
int width = inputFrame.size(0);
115
int height = inputFrame.size(1);
116
long rgbBytes = width * height * 3;
117
118
BytePointer rgbBuffer = new BytePointer(rgbBytes);
119
120
// Setup output frame structure
121
outputFrame.image(rgbBuffer);
122
outputFrame.total_bytes(rgbBytes);
123
outputFrame.image_bytes(rgbBytes);
124
outputFrame.size(0, width);
125
outputFrame.size(1, height);
126
outputFrame.color_coding(DC1394_COLOR_CODING_RGB8);
127
128
// Perform frame-based debayering
129
int err = dc1394_debayer_frames(inputFrame, outputFrame, DC1394_BAYER_METHOD_VNG);
130
if (err == DC1394_SUCCESS) {
131
System.out.println("Frame debayering completed");
132
}
133
134
rgbBuffer.deallocate();
135
}
136
137
dc1394_capture_enqueue(camera, inputFrame);
138
```
139
140
### Color Format Conversion
141
142
Converts between different color formats (YUV, RGB, Monochrome).
143
144
```java { .api }
145
/**
146
* Converts image data to YUV422 format
147
* @param src Source image data
148
* @param dest Destination buffer
149
* @param width Image width
150
* @param height Image height
151
* @param byte_order Byte order (DC1394_BYTE_ORDER_*)
152
* @param source_coding Source color coding
153
* @param bits Bit depth
154
* @return DC1394_SUCCESS on success, error code on failure
155
*/
156
int dc1394_convert_to_YUV422(BytePointer src, BytePointer dest, int width, int height,
157
int byte_order, int source_coding, int bits);
158
159
/**
160
* Converts image data to RGB8 format
161
* @param src Source image data
162
* @param dest Destination buffer
163
* @param width Image width
164
* @param height Image height
165
* @param byte_order Byte order
166
* @param source_coding Source color coding
167
* @param bits Bit depth
168
* @return DC1394_SUCCESS on success, error code on failure
169
*/
170
int dc1394_convert_to_RGB8(BytePointer src, BytePointer dest, int width, int height,
171
int byte_order, int source_coding, int bits);
172
173
/**
174
* Converts image data to MONO8 format
175
* @param src Source image data
176
* @param dest Destination buffer
177
* @param width Image width
178
* @param height Image height
179
* @param byte_order Byte order
180
* @param source_coding Source color coding
181
* @param bits Bit depth
182
* @return DC1394_SUCCESS on success, error code on failure
183
*/
184
int dc1394_convert_to_MONO8(BytePointer src, BytePointer dest, int width, int height,
185
int byte_order, int source_coding, int bits);
186
```
187
188
**Usage Example:**
189
190
```java
191
// Convert YUV422 to RGB8
192
dc1394video_frame_t frame = new dc1394video_frame_t(null);
193
dc1394_capture_dequeue(camera, DC1394_CAPTURE_POLICY_WAIT, frame);
194
195
if (frame.color_coding() == DC1394_COLOR_CODING_YUV422) {
196
int width = frame.size(0);
197
int height = frame.size(1);
198
199
// YUV422 uses 2 bytes per pixel, RGB8 uses 3
200
BytePointer rgbBuffer = new BytePointer(width * height * 3);
201
202
int err = dc1394_convert_to_RGB8(
203
frame.image(), // Source YUV422 data
204
rgbBuffer, // Destination RGB buffer
205
width, height, // Dimensions
206
DC1394_BYTE_ORDER_UYVY, // YUV byte order
207
DC1394_COLOR_CODING_YUV422, // Source format
208
8 // Bit depth
209
);
210
211
if (err == DC1394_SUCCESS) {
212
System.out.println("YUV422 to RGB8 conversion successful");
213
// Use RGB data...
214
}
215
216
rgbBuffer.deallocate();
217
}
218
219
dc1394_capture_enqueue(camera, frame);
220
```
221
222
### Stereo Image Processing
223
224
Processes stereo image pairs and deinterlaced stereo data.
225
226
```java { .api }
227
/**
228
* Deinterlaces stereo image data (line-interleaved)
229
* @param src Source interleaved stereo data
230
* @param dest Destination buffers for left and right images
231
* @param width Image width
232
* @param height Total height (both images)
233
* @param bpp Bytes per pixel
234
* @return DC1394_SUCCESS on success, error code on failure
235
*/
236
int dc1394_deinterlace_stereo(BytePointer src, BytePointer dest, int width, int height, int bpp);
237
238
/**
239
* Deinterlaces stereo frame data
240
* @param in Input stereo frame
241
* @param out1 Output frame for first camera
242
* @param out2 Output frame for second camera
243
* @return DC1394_SUCCESS on success, error code on failure
244
*/
245
int dc1394_deinterlace_stereo_frames(dc1394video_frame_t in, dc1394video_frame_t out1,
246
dc1394video_frame_t out2);
247
```
248
249
### Low-Level Color Space Conversion
250
251
Direct color space conversion functions for custom processing.
252
253
```java { .api }
254
/**
255
* Converts YUV to RGB (inline function)
256
* @param y Y component
257
* @param u U component
258
* @param v V component
259
* @param r Output R component
260
* @param g Output G component
261
* @param b Output B component
262
*/
263
void YUV2RGB(int y, int u, int v, IntPointer r, IntPointer g, IntPointer b);
264
265
/**
266
* Converts RGB to YUV (inline function)
267
* @param r R component
268
* @param g G component
269
* @param b B component
270
* @param y Output Y component
271
* @param u Output U component
272
* @param v Output V component
273
*/
274
void RGB2YUV(int r, int g, int b, IntPointer y, IntPointer u, IntPointer v);
275
```
276
277
## Constants
278
279
### Bayer Demosaicing Methods
280
281
```java { .api }
282
// Quality vs speed tradeoff methods
283
static final int DC1394_BAYER_METHOD_NEAREST = 0; // Fastest, lowest quality
284
static final int DC1394_BAYER_METHOD_SIMPLE = 1; // Simple interpolation
285
static final int DC1394_BAYER_METHOD_BILINEAR = 2; // Good quality/speed balance
286
static final int DC1394_BAYER_METHOD_HQLINEAR = 3; // High-quality linear
287
static final int DC1394_BAYER_METHOD_DOWNSAMPLE = 4; // Downsample for speed
288
static final int DC1394_BAYER_METHOD_EDGESENSE = 5; // Edge-aware interpolation
289
static final int DC1394_BAYER_METHOD_VNG = 6; // Variable Number of Gradients (high quality)
290
static final int DC1394_BAYER_METHOD_AHD = 7; // Adaptive Homogeneity-Directed (best quality)
291
292
// Method range
293
static final int DC1394_BAYER_METHOD_MIN = DC1394_BAYER_METHOD_NEAREST;
294
static final int DC1394_BAYER_METHOD_MAX = DC1394_BAYER_METHOD_AHD;
295
static final int DC1394_BAYER_METHOD_NUM = (DC1394_BAYER_METHOD_MAX - DC1394_BAYER_METHOD_MIN + 1);
296
```
297
298
### Color Filter Patterns
299
300
```java { .api }
301
// Bayer color filter arrangements
302
static final int DC1394_COLOR_FILTER_RGGB = 512; // Red-Green-Green-Blue
303
static final int DC1394_COLOR_FILTER_GBRG = 513; // Green-Blue-Red-Green
304
static final int DC1394_COLOR_FILTER_GRBG = 514; // Green-Red-Blue-Green
305
static final int DC1394_COLOR_FILTER_BGGR = 515; // Blue-Green-Green-Red
306
307
// Color filter range
308
static final int DC1394_COLOR_FILTER_MIN = DC1394_COLOR_FILTER_RGGB;
309
static final int DC1394_COLOR_FILTER_MAX = DC1394_COLOR_FILTER_BGGR;
310
static final int DC1394_COLOR_FILTER_NUM = (DC1394_COLOR_FILTER_MAX - DC1394_COLOR_FILTER_MIN + 1);
311
```
312
313
### Byte Order Constants
314
315
```java { .api }
316
// YUV byte ordering
317
static final int DC1394_BYTE_ORDER_UYVY = 800; // U-Y-V-Y ordering
318
static final int DC1394_BYTE_ORDER_YUYV = 801; // Y-U-Y-V ordering
319
320
// General byte order
321
static final int DC1394_LITTLE_ENDIAN = 802; // Little endian byte order
322
static final int DC1394_BIG_ENDIAN = 803; // Big endian byte order
323
```
324
325
## Bayer Method Comparison
326
327
### Quality vs Performance
328
329
- **NEAREST**: Fastest, produces blocky artifacts
330
- **SIMPLE**: Basic averaging, some color fringing
331
- **BILINEAR**: Good general-purpose option
332
- **HQLINEAR**: Better edge preservation
333
- **VNG**: Excellent quality, moderate speed
334
- **AHD**: Best quality, slowest processing
335
336
### Algorithm Selection Guidelines
337
338
```java
339
// Algorithm selection based on application needs
340
int selectBayerMethod(String application) {
341
switch (application) {
342
case "realtime":
343
return DC1394_BAYER_METHOD_BILINEAR; // Good speed/quality balance
344
case "preview":
345
return DC1394_BAYER_METHOD_SIMPLE; // Fast preview
346
case "scientific":
347
return DC1394_BAYER_METHOD_AHD; // Best quality
348
case "mobile":
349
return DC1394_BAYER_METHOD_NEAREST; // Fastest for mobile
350
case "photography":
351
return DC1394_BAYER_METHOD_VNG; // High quality
352
default:
353
return DC1394_BAYER_METHOD_BILINEAR; // Default choice
354
}
355
}
356
```
357
358
## Advanced Conversion Workflows
359
360
### Complete RAW Processing Pipeline
361
362
```java
363
// Complete RAW image processing workflow
364
void processRAWImage(dc1394video_frame_t rawFrame) {
365
if (rawFrame.color_coding() != DC1394_COLOR_CODING_RAW8) {
366
System.err.println("Frame is not RAW format");
367
return;
368
}
369
370
int width = rawFrame.size(0);
371
int height = rawFrame.size(1);
372
373
// Step 1: Demosaic Bayer pattern to RGB
374
BytePointer rgbData = new BytePointer(width * height * 3);
375
376
int err = dc1394_bayer_decoding_8bit(
377
rawFrame.image(),
378
rgbData,
379
width, height,
380
rawFrame.color_filter(),
381
DC1394_BAYER_METHOD_VNG // High quality
382
);
383
384
if (err != DC1394_SUCCESS) {
385
System.err.println("Bayer demosaicing failed: " + err);
386
rgbData.deallocate();
387
return;
388
}
389
390
System.out.println("RAW processing completed:");
391
System.out.println(" Input: " + width + "x" + height + " RAW8");
392
System.out.println(" Output: " + width + "x" + height + " RGB8");
393
System.out.println(" Algorithm: VNG");
394
System.out.println(" Bayer pattern: " + getBayerPatternName(rawFrame.color_filter()));
395
396
// Step 2: Additional processing (optional)
397
// - White balance correction
398
// - Gamma correction
399
// - Color space conversion
400
// - Noise reduction
401
402
// Step 3: Save or display result
403
saveRGBImage(rgbData, width, height, "output.ppm");
404
405
rgbData.deallocate();
406
}
407
408
String getBayerPatternName(int pattern) {
409
switch (pattern) {
410
case DC1394_COLOR_FILTER_RGGB: return "RGGB";
411
case DC1394_COLOR_FILTER_GBRG: return "GBRG";
412
case DC1394_COLOR_FILTER_GRBG: return "GRBG";
413
case DC1394_COLOR_FILTER_BGGR: return "BGGR";
414
default: return "Unknown";
415
}
416
}
417
```
418
419
### Multi-Format Conversion
420
421
```java
422
// Convert any supported format to RGB8
423
BytePointer convertToRGB8(dc1394video_frame_t frame) {
424
int width = frame.size(0);
425
int height = frame.size(1);
426
int colorCoding = frame.color_coding();
427
428
BytePointer rgbBuffer = new BytePointer(width * height * 3);
429
430
switch (colorCoding) {
431
case DC1394_COLOR_CODING_RGB8:
432
// Already RGB8, direct copy
433
frame.image().get(rgbBuffer.asBuffer());
434
break;
435
436
case DC1394_COLOR_CODING_RAW8:
437
// Demosaic Bayer pattern
438
dc1394_bayer_decoding_8bit(frame.image(), rgbBuffer,
439
width, height,
440
frame.color_filter(),
441
DC1394_BAYER_METHOD_BILINEAR);
442
break;
443
444
case DC1394_COLOR_CODING_YUV422:
445
// Convert YUV to RGB
446
dc1394_convert_to_RGB8(frame.image(), rgbBuffer,
447
width, height,
448
DC1394_BYTE_ORDER_UYVY,
449
colorCoding, 8);
450
break;
451
452
case DC1394_COLOR_CODING_MONO8:
453
// Convert monochrome to RGB (replicate channels)
454
convertMono8ToRGB8(frame.image(), rgbBuffer, width, height);
455
break;
456
457
default:
458
System.err.println("Unsupported color format: " + colorCoding);
459
rgbBuffer.deallocate();
460
return null;
461
}
462
463
return rgbBuffer;
464
}
465
466
void convertMono8ToRGB8(BytePointer mono, BytePointer rgb, int width, int height) {
467
int pixels = width * height;
468
for (int i = 0; i < pixels; i++) {
469
byte value = mono.get(i);
470
rgb.put(i * 3, value); // R
471
rgb.put(i * 3 + 1, value); // G
472
rgb.put(i * 3 + 2, value); // B
473
}
474
}
475
```
476
477
### Performance Optimization
478
479
```java
480
// Optimized conversion with memory reuse
481
class ImageConverter {
482
private BytePointer rgbBuffer;
483
private BytePointer tempBuffer;
484
private int bufferWidth = 0;
485
private int bufferHeight = 0;
486
487
public BytePointer convertFrame(dc1394video_frame_t frame) {
488
int width = frame.size(0);
489
int height = frame.size(1);
490
491
// Reallocate buffers only if size changed
492
if (width != bufferWidth || height != bufferHeight) {
493
deallocateBuffers();
494
allocateBuffers(width, height);
495
}
496
497
// Perform conversion using pre-allocated buffers
498
switch (frame.color_coding()) {
499
case DC1394_COLOR_CODING_RAW8:
500
dc1394_bayer_decoding_8bit(frame.image(), rgbBuffer,
501
width, height,
502
frame.color_filter(),
503
DC1394_BAYER_METHOD_BILINEAR);
504
break;
505
506
case DC1394_COLOR_CODING_YUV422:
507
dc1394_convert_to_RGB8(frame.image(), rgbBuffer,
508
width, height,
509
DC1394_BYTE_ORDER_UYVY,
510
frame.color_coding(), 8);
511
break;
512
513
// ... other formats
514
}
515
516
return rgbBuffer;
517
}
518
519
private void allocateBuffers(int width, int height) {
520
rgbBuffer = new BytePointer(width * height * 3);
521
tempBuffer = new BytePointer(width * height * 4); // For intermediate conversions
522
bufferWidth = width;
523
bufferHeight = height;
524
}
525
526
private void deallocateBuffers() {
527
if (rgbBuffer != null) {
528
rgbBuffer.deallocate();
529
rgbBuffer = null;
530
}
531
if (tempBuffer != null) {
532
tempBuffer.deallocate();
533
tempBuffer = null;
534
}
535
}
536
537
public void cleanup() {
538
deallocateBuffers();
539
}
540
}
541
```
542
543
## Image Quality Considerations
544
545
### Bayer Pattern Handling
546
547
- **Check color filter**: Always use correct Bayer pattern from frame metadata
548
- **Edge handling**: Demosaicing may produce artifacts at image edges
549
- **Color accuracy**: Higher quality methods produce more accurate colors
550
551
### Color Space Conversion
552
553
- **Gamma correction**: May need gamma adjustment after RGB conversion
554
- **White balance**: RAW images require white balance correction
555
- **Color matrix**: Professional applications may need custom color matrices
556
557
### Performance vs Quality
558
559
- **Real-time**: Use BILINEAR or SIMPLE methods
560
- **Archival**: Use VNG or AHD methods for best quality
561
- **Batch processing**: Consider threading for multiple images
562
563
## Error Handling and Validation
564
565
```java
566
// Validate conversion parameters
567
boolean validateConversionParams(dc1394video_frame_t frame, int method) {
568
// Check frame validity
569
if (frame.image() == null || frame.total_bytes() == 0) {
570
System.err.println("Invalid frame data");
571
return false;
572
}
573
574
// Check color coding support
575
int coding = frame.color_coding();
576
if (coding != DC1394_COLOR_CODING_RAW8 &&
577
coding != DC1394_COLOR_CODING_RAW16 &&
578
coding != DC1394_COLOR_CODING_YUV422 &&
579
coding != DC1394_COLOR_CODING_RGB8) {
580
System.err.println("Unsupported color coding: " + coding);
581
return false;
582
}
583
584
// Check method validity
585
if (method < DC1394_BAYER_METHOD_MIN || method > DC1394_BAYER_METHOD_MAX) {
586
System.err.println("Invalid Bayer method: " + method);
587
return false;
588
}
589
590
// Check dimensions
591
if (frame.size(0) <= 0 || frame.size(1) <= 0) {
592
System.err.println("Invalid frame dimensions");
593
return false;
594
}
595
596
return true;
597
}
598
```