camera_usb
helpers.h
Go to the documentation of this file.
1 /*
2  * \file helpers.h
3  *
4  * \brief Some general helper functions.
5  *
6  * German Research Center for Artificial Intelligence\n
7  * Project: Rimres
8  *
9  * \date 17.02.17
10  *
11  * \author Stefan.Haase@ground-truth-robotics.de
12  */
13 
14 #ifndef _CAM_V4L2_HELPERS_H_
15 #define _CAM_V4L2_HELPERS_H_
16 
17 #include <assert.h>
18 
19 #include <base/samples/Frame.hpp>
20 
21 namespace camera
22 {
23 
24 class Helpers {
25  public:
29  Helpers() {
30  for(int v=0; v<256; ++v) {
31  lookup_v2r[v] = ( (v-128) * 37221 ) >> 15;
32  }
33 
34  for(int u=0; u<256; ++u) {
35  for(int v=0; v<256; ++v) {
36  lookup_uv2g[u][v] = ( ((u-128) * 12975) + ((v-128) * 18949) ) >> 15;
37  }
38  }
39 
40  for(int u=0; u<256; ++u) {
41  lookup_u2b[u] = ((u-128) * 66883) >> 15;
42  }
43 
44  }
45 
51  static void removeJpegCommentBlock( base::samples::frame::Frame& frame) {
52 
53  if(frame.getFrameMode() == base::samples::frame::MODE_JPEG) {
54  std::vector<uint8_t>::iterator it = frame.image.begin();
55  std::vector<uint8_t>::iterator it_n = frame.image.begin() + 1;
56  for(; it_n != frame.image.end(); it++, it_n++) {
57  if(*it == 0xFF && *it_n == 0xFE) {
58  size_t old_length = *(it+2)<<8 | *(it_n+2);
59  // e.g. empty comment block: FF FE 00 02 XX
60  // it it+4
61  frame.image.erase(it, it + (2 + old_length));
62  break;
63  }
64 
65  // Start of scan, no comment block found.
66  if(*it == 0xFF && *it_n == 0XDA) {
67  break;
68  }
69  }
70  }
71  }
72 
73  static bool storeImageToFile(std::vector<uint8_t> const& buffer, std::string const& file_name) {
74  LOG_DEBUG("storeImageToFile, buffer contains %d bytes, stores to %s",
75  buffer.size(), file_name.c_str());
76 
77  if(buffer.empty()) {
78  LOG_WARN("Empty buffer passed, nothing will be stored");
79  return false;
80  }
81 
82  FILE* file = NULL;
83  file = fopen(file_name.c_str(),"w");
84  if(file == NULL) {
85  LOG_ERROR("File %s could not be opened, no image will be stored", file_name.c_str());
86  return false;
87  }
88  unsigned int written = fwrite (&buffer[0], 1 , buffer.size(), file);
89  if(written != buffer.size()) {
90  LOG_ERROR("Only %d of %d bytes could be written", written, buffer.size());
91  fclose(file);
92  return false;
93  }
94  fclose(file);
95  return true;
96  }
97 
98  uint8_t clip(int value) {
99  if(value < 0)
100  return 0;
101  if(value > 255)
102  return 255;
103  return value;
104  }
105 
106  void convertYUYVPixel(uint8_t y, uint8_t u, uint8_t v,
107  uint8_t& r, uint8_t& g, uint8_t& b) {
108 
109  int y2 = (int)y;
110 
111  int r2 = y2 + lookup_v2r[(int)v]; // ((v2 * 37221) >> 15);
112  int g2 = y2 - lookup_uv2g[(int)u][(int)v]; // (((u2 * 12975) + (v2 * 18949)) >> 15);
113  int b2 = y2 + lookup_u2b[(int)u]; // ((u-128) * 66883) >> 15
114 
115  // Cap the values.
116  r = clip(r2);
117  g = clip(g2);
118  b = clip(b2);
119  }
120 
129  void convertYUYV2RGB(uint8_t* yuyv_data,
130  size_t yuyv_data_length,
131  std::vector<uint8_t>& rgb_buffer) {
132 
133  assert(yuyv_data_length%4 == 0);
134  // YUYV are two bytes per pixel, RGB uses three.
135  int rgb_size = (yuyv_data_length / 2) * 3;
136  rgb_buffer.resize(rgb_size);
137  std::vector<uint8_t>::iterator it = rgb_buffer.begin();
138  // Piyel 1: yuv
139  // Pixel 2: y2uv
140  uint8_t* y = yuyv_data;
141  uint8_t* u = y + 1;
142  uint8_t* y2 = y + 2;
143  uint8_t* v = y + 3;
144  uint8_t r,g,b;
145  // y [16,235] uv [16,240]
146  for(unsigned int i=0; i < yuyv_data_length/4 && it != rgb_buffer.end(); ++i, y+=4, u+=4, y2+=4, v+=4) {
147  /*
148  *it = *y + 1.403 * *v; it++; // R 38.448 to
149  *it = *y - 0.344 * *u - 0.714 * *v; it++; // G
150  *it = *y + 1.77 * *u; it++; // B
151  *it = *y2 + 1.403 * *v; it++; // R2
152  *it = *y2 - 0.344 * *u - 0.714 * *v; it++; // G2
153  *it = *y2 + 1.77 * *u; it++; // B2
154  */
155  convertYUYVPixel(*y, *u, *v, r, g, b);
156  *it = r; it++;
157  *it = g; it++;
158  *it = b; it++;
159 
160  convertYUYVPixel(*y2, *u, *v, r, g, b);
161  *it = r; it++;
162  *it = g; it++;
163  *it = b; it++;
164  }
165  }
166 
167  private:
168  int lookup_v2r[256];
169  int lookup_uv2g[256][256];
170  int lookup_u2b[256];
171 };
172 
173 } // end namespace camera
174 
175 #endif
void convertYUYV2RGB(uint8_t *yuyv_data, size_t yuyv_data_length, std::vector< uint8_t > &rgb_buffer)
Definition: helpers.h:129
void convertYUYVPixel(uint8_t y, uint8_t u, uint8_t v, uint8_t &r, uint8_t &g, uint8_t &b)
Definition: helpers.h:106
static void removeJpegCommentBlock(base::samples::frame::Frame &frame)
Definition: helpers.h:51
static bool storeImageToFile(std::vector< uint8_t > const &buffer, std::string const &file_name)
Definition: helpers.h:73
Definition: helpers.h:24
Helpers()
Definition: helpers.h:29
uint8_t clip(int value)
Definition: helpers.h:98