@@ -113,6 +113,7 @@ class PiCameraMaxFramerate(object):
113
113
'resolution' ,
114
114
'framerate' ,
115
115
'isp_blocks' ,
116
+ 'colorspace' ,
116
117
))
117
118
118
119
@@ -341,6 +342,13 @@ class PiCamera(object):
341
342
'sharpening' : 1 << 22 ,
342
343
}
343
344
345
+ COLORSPACES = {
346
+ 'auto' : mmal .MMAL_COLOR_SPACE_UNKNOWN ,
347
+ 'jfif' : mmal .MMAL_COLOR_SPACE_JPEG_JFIF ,
348
+ 'bt601' : mmal .MMAL_COLOR_SPACE_ITUR_BT601 ,
349
+ 'bt709' : mmal .MMAL_COLOR_SPACE_ITUR_BT709 ,
350
+ }
351
+
344
352
_METER_MODES_R = {v : k for (k , v ) in METER_MODES .items ()}
345
353
_EXPOSURE_MODES_R = {v : k for (k , v ) in EXPOSURE_MODES .items ()}
346
354
_FLASH_MODES_R = {v : k for (k , v ) in FLASH_MODES .items ()}
@@ -350,6 +358,7 @@ class PiCamera(object):
350
358
_STEREO_MODES_R = {v : k for (k , v ) in STEREO_MODES .items ()}
351
359
_CLOCK_MODES_R = {v : k for (k , v ) in CLOCK_MODES .items ()}
352
360
_ISP_BLOCKS_R = {v : k for (k , v ) in ISP_BLOCKS .items ()}
361
+ _COLORSPACES_R = {v : k for (k , v ) in COLORSPACES .items ()}
353
362
354
363
__slots__ = (
355
364
'_used_led' ,
@@ -432,6 +441,7 @@ def _parse_options(args, kwargs):
432
441
'clock_mode' : 'reset' ,
433
442
'framerate_range' : None ,
434
443
'isp_blocks' : None ,
444
+ 'colorspace' : 'auto' ,
435
445
}
436
446
arg_names = (
437
447
'camera_num' ,
@@ -536,6 +546,12 @@ def _init_config(cls, options):
536
546
raise PiCameraValueError (
537
547
'Invalid clock mode: %s' % options ['clock_mode' ])
538
548
549
+ try :
550
+ colorspace = cls .COLORSPACES [options ['colorspace' ]]
551
+ except KeyError :
552
+ raise PiCameraValueError (
553
+ 'Invalid colorspace: %s' % options ['colorspace' ])
554
+
539
555
all_blocks = set (cls .ISP_BLOCKS .keys ())
540
556
if options ['isp_blocks' ] is None :
541
557
isp_blocks = 0
@@ -553,13 +569,15 @@ def _init_config(cls, options):
553
569
clock_mode = clock_mode ,
554
570
resolution = cls .MAX_RESOLUTION ,
555
571
framerate = 30 ,
556
- isp_blocks = 0 )
572
+ isp_blocks = 0 ,
573
+ colorspace = mmal .MMAL_COLOR_SPACE_UNKNOWN )
557
574
new_config = PiCameraConfig (
558
575
sensor_mode = options ['sensor_mode' ],
559
576
clock_mode = clock_mode ,
560
577
resolution = resolution ,
561
578
framerate = framerate ,
562
- isp_blocks = isp_blocks )
579
+ isp_blocks = isp_blocks ,
580
+ colorspace = colorspace )
563
581
return old_config , new_config
564
582
565
583
def _init_led (self , options ):
@@ -2159,8 +2177,8 @@ def _enable_camera(self):
2159
2177
2160
2178
def _configure_splitter (self ):
2161
2179
"""
2162
- Ensures all splitter output ports have a sensible format (I420) and
2163
- buffer sizes .
2180
+ Ensures the splitter has the same format as the attached camera
2181
+ output port (the video port) .
2164
2182
2165
2183
This method is used to ensure the splitter configuration is sane,
2166
2184
typically after :meth:`_configure_camera` is called.
@@ -2210,7 +2228,8 @@ def _get_config(self):
2210
2228
),
2211
2229
framerate = framerate ,
2212
2230
isp_blocks = self ._camera .control .params [
2213
- mmal .MMAL_PARAMETER_CAMERA_ISP_BLOCK_OVERRIDE ]
2231
+ mmal .MMAL_PARAMETER_CAMERA_ISP_BLOCK_OVERRIDE ],
2232
+ colorspace = self ._camera .outputs [0 ].colorspace
2214
2233
)
2215
2234
2216
2235
def _configure_camera (self , old , new ):
@@ -2306,6 +2325,7 @@ def _configure_camera(self, old, new):
2306
2325
else :
2307
2326
port .framesize = new .resolution
2308
2327
port .framerate = new .framerate
2328
+ port .colorspace = new .colorspace
2309
2329
port .commit ()
2310
2330
except :
2311
2331
# If anything goes wrong, restore original resolution and
@@ -2529,9 +2549,53 @@ def _set_isp_blocks(self, value):
2529
2549
2530
2550
camera.isp_blocks |= {{'white-balance'}}
2531
2551
2552
+ The camera must not be closed, and no recording must be active when the
2553
+ property is set.
2554
+
2532
2555
.. versionadded:: 1.14
2533
2556
""" .format (values = docstring_values (ISP_BLOCKS )))
2534
2557
2558
+ def _get_colorspace (self ):
2559
+ return self ._COLORSPACES_R [self ._camera .outputs [0 ].colorspace ]
2560
+ def _set_colorspace (self , value ):
2561
+ self ._check_camera_open ()
2562
+ self ._check_recording_stopped ()
2563
+ try :
2564
+ colorspace = self .COLORSPACES [value ]
2565
+ except KeyError :
2566
+ raise PiCameraValueError ("Invalid colorspace %s" % value )
2567
+ config = self ._get_config ()
2568
+ self ._disable_camera ()
2569
+ self ._configure_camera (config , config ._replace (colorspace = colorspace ))
2570
+ self ._configure_splitter ()
2571
+ self ._enable_camera ()
2572
+ colorspace = property (_get_colorspace , _set_colorspace , doc = """\
2573
+ Retrieves or sets the `color space`_ that the camera uses for
2574
+ conversion between the `YUV`_ and RGB systems.
2575
+
2576
+ The value is a string that represents which of a series of fixed
2577
+ conversion tables are used by the camera firmware (the firmware works
2578
+ largely in the YUV color system internally). The following strings are
2579
+ the valid values:
2580
+
2581
+ {values}
2582
+
2583
+ The "bt601" and "bt709" values correspond to the standard `SDTV and
2584
+ HDTV tables`_. The "auto" value is the default and corresponds to
2585
+ "bt601" in practice. One of these values is likely what you want when
2586
+ recording H.264 video. However, when recording MJPEG video, you may
2587
+ want to use the "jfif" table instead as it produces luma values in the
2588
+ 0-255 range, rather than the 16-235 range produced by the standard
2589
+ tables.
2590
+
2591
+ The camera must not be closed, and no recording must be active when the
2592
+ property is set.
2593
+
2594
+ .. _color space: https://en.wikipedia.org/wiki/Color_space
2595
+ .. _YUV: https://en.wikipedia.org/wiki/YUV
2596
+ .. _SDTV and HDTV tables: https://en.wikipedia.org/wiki/YUV#Conversion_to/from_RGB
2597
+ """ .format (values = docstring_values (COLORSPACES )))
2598
+
2535
2599
def _get_resolution (self ):
2536
2600
self ._check_camera_open ()
2537
2601
return mo .PiResolution (
0 commit comments