cv_bridge/utils/
image_encodings.rs

1//! This module contains the image encodings used by OpenCV
2//! 
3//! ## Supported encodings
4//! * `mono8` - 8-bit single channel image
5//! * `rgb8` - 8-bit 3 channel image
6//! * `rgba8` - 8-bit 4 channel image
7//! * `bgr8` - 8-bit 3 channel image
8//! * `bgra8` - 8-bit 4 channel image
9//! * `mono16` - 16-bit single channel image
10//! * `rgb16` - 16-bit 3 channel image
11//! * `rgba16` - 16-bit 4 channel image
12//! * `bgr16` - 16-bit 3 channel image
13//! * `bgra16` - 16-bit 4 channel image
14//! * `bayer_rggb8` - 8-bit Bayer image
15//! * `bayer_bggr8` - 8-bit Bayer image
16//! * `bayer_gbrg8` - 8-bit Bayer image
17//! * `bayer_grbg8` - 8-bit Bayer image
18//! * `bayer_rggb16` - 16-bit Bayer image
19//! * `bayer_bggr16` - 16-bit Bayer image
20//! * `bayer_gbrg16` - 16-bit Bayer image
21//! * `bayer_grbg16` - 16-bit Bayer image
22//! * `yuv422` - 8-bit 2 channel image
23//! * `yuv422_yuy2` - 8-bit 2 channel image
24
25#[derive(Debug)]
26pub enum Encoding {
27    Gray,
28    Rgb,
29    Bgr,
30    Rgba,
31    Bgra,
32    Yuv422,
33    Yuv422yuy2,
34    BayerRGGB, 
35    BayerBGGR,
36    BayerGBRG,
37    BayerGRBG,
38    Invalid
39}
40
41/// Returns the number of channels for the given encoding
42/// 
43/// ## Arguments
44/// * `encoding` - The encoding to get the number of channels for (e.g. "rgb8")
45/// 
46/// ## Returns
47/// The number of channels for the given encoding
48pub fn get_num_channels(encoding: &str) -> usize {
49    match encoding {
50        "mono8" => 1,
51        "rgb8" => 3,
52        "rgba8" => 4,
53        "bgr8" => 3,
54        "bgra8" => 4,
55        "mono16" => 1,
56        "rgb16" => 3,
57        "rgba16" => 4,
58        "bgr16" => 3,
59        "bgra16" => 4,
60        "bayer_rggb8" => 1,
61        "bayer_bggr8" => 1,
62        "bayer_gbrg8" => 1,
63        "bayer_grbg8" => 1,
64        "bayer_rggb16" => 1,
65        "bayer_bggr16" => 1,
66        "bayer_gbrg16" => 1,
67        "bayer_grbg16" => 1,
68        "yuv422" => 2,
69        "yuv422_yuy2" => 2,
70        _ => 0
71    }
72}
73
74/// Returns the bit depth for the given encoding
75/// 
76/// ## Arguments
77/// * `encoding` - The encoding to get the bit depth for (e.g. "rgb8")
78///                Note: The bit depth is the number of bits per channel
79/// 
80/// ## Returns
81/// The bit depth for the given encoding
82pub fn get_bit_depth(encoding: &str) -> u8 {
83    match encoding {
84        "mono8" => 8,
85        "rgb8" => 8,
86        "rgba8" => 8,
87        "bgr8" => 8,
88        "bgra8" => 8,
89        "mono16" => 16,
90        "rgb16" => 16,
91        "rgba16" => 16,
92        "bgr16" => 16,
93        "bgra16" => 16,
94        "bayer_rggb8" => 8,
95        "bayer_bggr8" => 8,
96        "bayer_gbrg8" => 8,
97        "bayer_grbg8" => 8,
98        "bayer_rggb16" => 16,
99        "bayer_bggr16" => 16,
100        "bayer_gbrg16" => 16,
101        "bayer_grbg16" => 16,
102        "yuv422" => 8,
103        "yuv422_yuy2" => 8,
104        _ => 0
105    }
106}
107
108/// Returns the scaling factor when converting between encodings with
109/// different bit depths
110/// 
111/// ## Arguments
112/// * `src_encoding` - The source encoding
113/// * `dst_encoding` - The destination encoding
114/// 
115/// ## Returns
116/// The scaling factor when converting between encodings with different bit depths
117pub fn get_scaling_factor(src_encoding: &str, dst_encoding: &str) -> f64 {
118    let src_depth = get_bit_depth(src_encoding) as i32;
119    let dst_depth = get_bit_depth(dst_encoding) as i32;
120
121    if src_depth == 0 || dst_depth == 0 {
122        return 0.0;
123    }
124
125    f64::powi(2.0, dst_depth - src_depth) as f64
126}
127
128/// Returns the OpenCV type for the given encoding
129/// 
130/// ## Arguments
131/// * `encoding` - The encoding to get the OpenCV type for (e.g. "rgb8")
132/// 
133/// ## Returns
134/// The OpenCV type for the given encoding or an error if the encoding is invalid
135/// (eg. opencv::core::CV_8UC3)
136pub fn from_encstr_to_cvtype(encoding: &str) -> Result<i32, String> {
137    match encoding {
138        "mono8" => Ok(opencv::core::CV_8UC1),
139        "rgb8" => Ok(opencv::core::CV_8UC3),
140        "rgba8" => Ok(opencv::core::CV_8UC4),
141        "bgr8" => Ok(opencv::core::CV_8UC3),
142        "bgra8" => Ok(opencv::core::CV_8UC4),
143        "mono16" => Ok(opencv::core::CV_16UC1),
144        "rgb16" => Ok(opencv::core::CV_16UC3),
145        "rgba16" => Ok(opencv::core::CV_16UC4),
146        "bgr16" => Ok(opencv::core::CV_16UC3),
147        "bgra16" => Ok(opencv::core::CV_16UC4),
148        "bayer_rggb8" => Ok(opencv::core::CV_8UC1),
149        "bayer_bggr8" => Ok(opencv::core::CV_8UC1),
150        "bayer_gbrg8" => Ok(opencv::core::CV_8UC1),
151        "bayer_grbg8" => Ok(opencv::core::CV_8UC1),
152        "bayer_rggb16" => Ok(opencv::core::CV_16UC1),
153        "bayer_bggr16" => Ok(opencv::core::CV_16UC1),
154        "bayer_gbrg16" => Ok(opencv::core::CV_16UC1),
155        "bayer_grbg16" => Ok(opencv::core::CV_16UC1),
156        "yuv422" => Ok(opencv::core::CV_8UC2),
157        "yuv422_yuy2" => Ok(opencv::core::CV_8UC2),
158        _ => Err(format!("Unsupported encoding type: {}", encoding))
159    }
160}
161
162/// Returns the OpenCV encoding for the given encoding
163/// 
164/// ## Arguments
165/// * `encoding` - The encoding to get the OpenCV encoding for (e.g. "rgb8")
166/// 
167/// ## Returns
168/// The OpenCV encoding for the given encoding or an error if the encoding is invalid
169pub fn from_encstr_to_cvenc(encoding: &str) -> Result<Encoding, String> {
170    match encoding {
171        "mono8" => Ok(Encoding::Gray),
172        "rgb8" => Ok(Encoding::Rgb),
173        "rgba8" => Ok(Encoding::Rgba),
174        "bgr8" => Ok(Encoding::Bgr),
175        "bgra8" => Ok(Encoding::Bgra),
176        "mono16" => Ok(Encoding::Gray),
177        "rgb16" => Ok(Encoding::Rgb),
178        "rgba16" => Ok(Encoding::Rgba),
179        "bgr16" => Ok(Encoding::Bgr),
180        "bgra16" => Ok(Encoding::Bgra),
181        "bayer_rggb8" => Ok(Encoding::BayerRGGB),
182        "bayer_bggr8" => Ok(Encoding::BayerBGGR),
183        "bayer_gbrg8" => Ok(Encoding::BayerGBRG),
184        "bayer_grbg8" => Ok(Encoding::BayerGRBG),
185        "bayer_rggb16" => Ok(Encoding::BayerRGGB),
186        "bayer_bggr16" => Ok(Encoding::BayerBGGR),
187        "bayer_gbrg16" => Ok(Encoding::BayerGBRG),
188        "bayer_grbg16" => Ok(Encoding::BayerGRBG),
189        "yuv422" => Ok(Encoding::Yuv422),
190        "yuv422_yuy2" => Ok(Encoding::Yuv422yuy2),
191        _ => Err(format!("Unsupported encoding type: {}", encoding))
192    }
193}
194
195/// Returns the encoding for the given OpenCV encoding and bit depth
196/// 
197/// ## Arguments
198/// * `cvenc` - The OpenCV encoding to get the encoding for
199/// * `cvdepth` - The OpenCV bit depth to get the encoding for
200///          (0 = unsigned 8-bit, 1 = signed 8-bit, 2 = unsigned 16-bit, 3 = signed 16-bit)
201pub fn from_cvenc_to_encstr(cvenc: Encoding, cvdepth: i32) -> Result<String, String> {
202    match (cvenc, cvdepth) {
203        (Encoding::Gray, 0) => Ok("mono8".to_string()),
204        (Encoding::Gray, 1) => Ok("mono8".to_string()),
205        (Encoding::Gray, 2) => Ok("mono16".to_string()),
206        (Encoding::Gray, 3) => Ok("mono16".to_string()),
207        (Encoding::Rgb, 0) => Ok("rgb8".to_string()),
208        (Encoding::Rgb, 1) => Ok("rgb8".to_string()),
209        (Encoding::Rgb, 2) => Ok("rgb16".to_string()),
210        (Encoding::Rgb, 3) => Ok("rgb16".to_string()),
211        (Encoding::Rgba, 0) => Ok("rgba8".to_string()),
212        (Encoding::Rgba, 1) => Ok("rgba8".to_string()),
213        (Encoding::Rgba, 2) => Ok("rgba16".to_string()),
214        (Encoding::Rgba, 3) => Ok("rgba16".to_string()),
215        (Encoding::Bgr, 0) => Ok("bgr8".to_string()),
216        (Encoding::Bgr, 1) => Ok("bgr8".to_string()),
217        (Encoding::Bgr, 2) => Ok("bgr16".to_string()),
218        (Encoding::Bgr, 3) => Ok("bgr16".to_string()),
219        (Encoding::Bgra, 0) => Ok("bgra8".to_string()),
220        (Encoding::Bgra, 1) => Ok("bgra8".to_string()),
221        (Encoding::Bgra, 2) => Ok("bgra16".to_string()),
222        (Encoding::Bgra, 3) => Ok("bgra16".to_string()),
223        (Encoding::BayerRGGB, 0) => Ok("bayer_rggb8".to_string()),
224        (Encoding::BayerRGGB, 1) => Ok("bayer_rggb8".to_string()),
225        (Encoding::BayerRGGB, 2) => Ok("bayer_rggb16".to_string()),
226        (Encoding::BayerRGGB, 3) => Ok("bayer_rggb16".to_string()),
227        (Encoding::BayerBGGR, 0) => Ok("bayer_bggr8".to_string()),
228        (Encoding::BayerBGGR, 1) => Ok("bayer_bggr8".to_string()),
229        (Encoding::BayerBGGR, 2) => Ok("bayer_bggr16".to_string()),
230        (Encoding::BayerBGGR, 3) => Ok("bayer_bggr16".to_string()),
231        (Encoding::BayerGBRG, 0) => Ok("bayer_gbrg8".to_string()),
232        (Encoding::BayerGBRG, 1) => Ok("bayer_gbrg8".to_string()),
233        (Encoding::BayerGBRG, 2) => Ok("bayer_gbrg16".to_string()),
234        (Encoding::BayerGBRG, 3) => Ok("bayer_gbrg16".to_string()),
235        (Encoding::BayerGRBG, 0) => Ok("bayer_grbg8".to_string()),
236        (Encoding::BayerGRBG, 1) => Ok("bayer_grbg8".to_string()),
237        (Encoding::BayerGRBG, 2) => Ok("bayer_grbg16".to_string()),
238        (Encoding::BayerGRBG, 3) => Ok("bayer_grbg16".to_string()),
239        (Encoding::Yuv422, 0) => Ok("yuv422".to_string()),
240        (Encoding::Yuv422yuy2, 0) => Ok("yuv422_yuy2".to_string()),
241        _ => Err(format!("Unsupported encoding type"))
242
243    }
244}
245
246/// Returns the conversion code for going from one color space to another
247/// 
248/// ## Arguments
249/// * `src_encoding` - The source encoding
250/// * `dst_encoding` - The destination encoding
251/// 
252/// ## Returns
253/// * `Ok(i32)` - The conversion code (eg. opencv::imgproc::COLOR_RGB2GRAY)
254pub fn get_conversion_code(src_encoding: Encoding, dst_encoding: Encoding) -> Result<i32, String>{
255    match (&src_encoding, &dst_encoding) {
256        (Encoding::Gray, Encoding::Rgb) => Ok(opencv::imgproc::COLOR_GRAY2RGB),
257        (Encoding::Gray, Encoding::Bgr) => Ok(opencv::imgproc::COLOR_GRAY2BGR),
258        (Encoding::Gray, Encoding::Rgba) => Ok(opencv::imgproc::COLOR_GRAY2RGBA),
259        (Encoding::Gray, Encoding::Bgra) => Ok(opencv::imgproc::COLOR_GRAY2BGRA),
260        (Encoding::Rgb, Encoding::Gray) => Ok(opencv::imgproc::COLOR_RGB2GRAY),
261        (Encoding::Rgb, Encoding::Bgr) => Ok(opencv::imgproc::COLOR_RGB2BGR),
262        (Encoding::Rgb, Encoding::Rgba) => Ok(opencv::imgproc::COLOR_RGB2RGBA),
263        (Encoding::Rgb, Encoding::Bgra) => Ok(opencv::imgproc::COLOR_RGB2BGRA),
264        (Encoding::Bgr, Encoding::Gray) => Ok(opencv::imgproc::COLOR_BGR2GRAY),
265        (Encoding::Bgr, Encoding::Rgb) => Ok(opencv::imgproc::COLOR_BGR2RGB),
266        (Encoding::Bgr, Encoding::Rgba) => Ok(opencv::imgproc::COLOR_BGR2RGBA),
267        (Encoding::Bgr, Encoding::Bgra) => Ok(opencv::imgproc::COLOR_BGR2BGRA),
268        (Encoding::Rgba, Encoding::Gray) => Ok(opencv::imgproc::COLOR_RGBA2GRAY),
269        (Encoding::Rgba, Encoding::Rgb) => Ok(opencv::imgproc::COLOR_RGBA2RGB),
270        (Encoding::Rgba, Encoding::Bgr) => Ok(opencv::imgproc::COLOR_RGBA2BGR),
271        (Encoding::Rgba, Encoding::Bgra) => Ok(opencv::imgproc::COLOR_RGBA2BGRA),
272        (Encoding::Bgra, Encoding::Gray) => Ok(opencv::imgproc::COLOR_BGRA2GRAY),
273        (Encoding::Bgra, Encoding::Rgb) => Ok(opencv::imgproc::COLOR_BGRA2RGB),
274        (Encoding::Bgra, Encoding::Bgr) => Ok(opencv::imgproc::COLOR_BGRA2BGR),
275        (Encoding::Bgra, Encoding::Rgba) => Ok(opencv::imgproc::COLOR_BGRA2RGBA),
276        (Encoding::BayerRGGB, Encoding::Gray) => Ok(opencv::imgproc::COLOR_BayerBG2GRAY),
277        (Encoding::BayerRGGB, Encoding::Rgb) => Ok(opencv::imgproc::COLOR_BayerBG2RGB),
278        (Encoding::BayerRGGB, Encoding::Bgr) => Ok(opencv::imgproc::COLOR_BayerBG2BGR),
279        (Encoding::BayerBGGR, Encoding::Gray) => Ok(opencv::imgproc::COLOR_BayerRG2GRAY),
280        (Encoding::BayerBGGR, Encoding::Rgb) => Ok(opencv::imgproc::COLOR_BayerRG2RGB),
281        (Encoding::BayerBGGR, Encoding::Bgr) => Ok(opencv::imgproc::COLOR_BayerRG2BGR),
282        (Encoding::BayerGBRG, Encoding::Gray) => Ok(opencv::imgproc::COLOR_BayerGR2GRAY),
283        (Encoding::BayerGBRG, Encoding::Rgb) => Ok(opencv::imgproc::COLOR_BayerGR2RGB),
284        (Encoding::BayerGBRG, Encoding::Bgr) => Ok(opencv::imgproc::COLOR_BayerGR2BGR),
285        (Encoding::BayerGRBG, Encoding::Gray) => Ok(opencv::imgproc::COLOR_BayerGB2GRAY),
286        (Encoding::BayerGRBG, Encoding::Rgb) => Ok(opencv::imgproc::COLOR_BayerGB2RGB),
287        (Encoding::BayerGRBG, Encoding::Bgr) => Ok(opencv::imgproc::COLOR_BayerGB2BGR),
288        (Encoding::Yuv422, Encoding::Gray) => Ok(opencv::imgproc::COLOR_YUV2GRAY_UYVY),
289        (Encoding::Yuv422, Encoding::Rgb) => Ok(opencv::imgproc::COLOR_YUV2RGB_UYVY),
290        (Encoding::Yuv422, Encoding::Bgr) => Ok(opencv::imgproc::COLOR_YUV2BGRA_UYVY),
291        (Encoding::Yuv422, Encoding::Rgba) => Ok(opencv::imgproc::COLOR_YUV2RGBA_UYVY),
292        (Encoding::Yuv422, Encoding::Bgra) => Ok(opencv::imgproc::COLOR_YUV2BGR_UYVY),
293        (Encoding::Yuv422yuy2, Encoding::Gray) => Ok(opencv::imgproc::COLOR_YUV2GRAY_YUY2),
294        (Encoding::Yuv422yuy2, Encoding::Rgb) => Ok(opencv::imgproc::COLOR_YUV2RGB_YUY2),
295        (Encoding::Yuv422yuy2, Encoding::Bgr) => Ok(opencv::imgproc::COLOR_YUV2BGR_YUY2),
296        (Encoding::Yuv422yuy2, Encoding::Rgba) => Ok(opencv::imgproc::COLOR_YUV2RGBA_YUY2),
297        (Encoding::Yuv422yuy2, Encoding::Bgra) => Ok(opencv::imgproc::COLOR_YUV2BGRA_YUY2),
298        _ => Err(format!("Unsupported conversion from {:?} to {:?}", src_encoding, dst_encoding)),
299    }
300}