26#include <linux/videodev2.h>
28#include <opencv2/imgproc/imgproc.hpp>
37 case 3:
return cv::Mat(src.
height, src.
width, CV_8UC3, src.
buf->data());
38 case 2:
return cv::Mat(src.
height, src.
width, CV_8UC2, src.
buf->data());
39 case 1:
return cv::Mat(src.
height, src.
width, CV_8UC1, src.
buf->data());
40 default:
LFATAL(
"Unsupported RawImage format");
47 inline void rgb565pixrgb(
unsigned short rgb565,
unsigned char & r,
unsigned char & g,
unsigned char & b)
49 r = ((((rgb565 >> 11) & 0x1F) * 527) + 23) >> 6;
50 g = ((((rgb565 >> 5) & 0x3F) * 259) + 33) >> 6;
51 b = (((rgb565 & 0x1F) * 527) + 23) >> 6;
54 class rgb565ToGray :
public cv::ParallelLoopBody
57 rgb565ToGray(cv::Mat
const & inputImage,
unsigned char * outImage,
size_t outw) :
58 inImg(inputImage), outImg(outImage)
60 inlinesize = inputImage.cols * 2;
61 outlinesize = outw * 1;
64 virtual void operator()(
const cv::Range & range)
const
66 for (
int j = range.start; j < range.end; ++j)
68 int const inoff = j * inlinesize;
69 int const outoff = j * outlinesize;
71 for (
int i = 0; i < inImg.cols; ++i)
73 int const in = inoff + i * 2;
74 int const out = outoff + i;
75 unsigned short const rgb565 = ((
unsigned short)(inImg.data[in + 0]) << 8) | inImg.data[in + 1];
76 unsigned char r, g, b;
77 rgb565pixrgb(rgb565, r, g, b);
78 int lum = int(r + g + b) / 3;
85 cv::Mat
const & inImg;
86 unsigned char * outImg;
87 int inlinesize, outlinesize;
90 class rgb565ToBGR :
public cv::ParallelLoopBody
93 rgb565ToBGR(cv::Mat
const & inputImage,
unsigned char * outImage,
size_t outw) :
94 inImg(inputImage), outImg(outImage)
96 inlinesize = inputImage.cols * 2;
97 outlinesize = outw * 3;
100 virtual void operator()(
const cv::Range & range)
const
102 for (
int j = range.start; j < range.end; ++j)
104 int const inoff = j * inlinesize;
105 int const outoff = j * outlinesize;
107 for (
int i = 0; i < inImg.cols; ++i)
109 int const in = inoff + i * 2;
110 int const out = outoff + i * 3;
111 unsigned short const rgb565 = ((
unsigned short)(inImg.data[in + 0]) << 8) | inImg.data[in + 1];
113 unsigned char r, g, b; rgb565pixrgb(rgb565, r, g, b);
122 cv::Mat
const & inImg;
123 unsigned char * outImg;
124 int inlinesize, outlinesize;
127 class rgb565ToRGB :
public cv::ParallelLoopBody
130 rgb565ToRGB(cv::Mat
const & inputImage,
unsigned char * outImage,
size_t outw) :
131 inImg(inputImage), outImg(outImage)
133 inlinesize = inputImage.cols * 2;
134 outlinesize = outw * 3;
137 virtual void operator()(
const cv::Range & range)
const
139 for (
int j = range.start; j < range.end; ++j)
141 int const inoff = j * inlinesize;
142 int const outoff = j * outlinesize;
144 for (
int i = 0; i < inImg.cols; ++i)
146 int const in = inoff + i * 2;
147 int const out = outoff + i * 3;
148 unsigned short const rgb565 = ((
unsigned short)(inImg.data[in + 0]) << 8) | inImg.data[in + 1];
150 unsigned char r, g, b; rgb565pixrgb(rgb565, r, g, b);
159 cv::Mat
const & inImg;
160 unsigned char * outImg;
161 int inlinesize, outlinesize;
164 class rgb565ToRGBA :
public cv::ParallelLoopBody
167 rgb565ToRGBA(cv::Mat
const & inputImage,
unsigned char * outImage,
size_t outw) :
168 inImg(inputImage), outImg(outImage)
170 inlinesize = inputImage.cols * 2;
171 outlinesize = outw * 4;
174 virtual void operator()(
const cv::Range & range)
const
176 for (
int j = range.start; j < range.end; ++j)
178 int const inoff = j * inlinesize;
179 int const outoff = j * outlinesize;
181 for (
int i = 0; i < inImg.cols; ++i)
183 int const in = inoff + i * 2;
184 int const out = outoff + i * 4;
185 unsigned short const rgb565 = ((
unsigned short)(inImg.data[in + 0]) << 8) | inImg.data[in + 1];
187 unsigned char r, g, b; rgb565pixrgb(rgb565, r, g, b);
191 outImg[out + 3] = (
unsigned char)(255);
197 cv::Mat
const & inImg;
198 unsigned char * outImg;
199 int inlinesize, outlinesize;
203#ifdef JEVOIS_PLATFORM
207 class yuyvToGrayNEON :
public cv::ParallelLoopBody
210 yuyvToGrayNEON(cv::Mat
const & inputImage,
unsigned char * outImage,
size_t outw) :
211 inImg(inputImage), outImg(outImage)
213 inlinesize = inputImage.cols * 2;
214 outlinesize = outw * 1;
215 initer = (inputImage.cols >> 4);
218 virtual void operator()(
const cv::Range & range)
const
220 unsigned char const * inptr = inImg.data + range.start * inlinesize;
221 unsigned char * outptr = outImg + range.start * outlinesize;
223 for (
int j = range.start; j < range.end; ++j)
225 unsigned char const * ip = inptr;
unsigned char * op = outptr;
227 for (
int i = 0; i < initer; ++i)
229 uint8x16x2_t
const pixels = vld2q_u8(ip);
230 vst1q_u8(op, pixels.val[0]);
233 inptr += inlinesize; outptr += outlinesize;
238 cv::Mat
const & inImg;
239 unsigned char * outImg;
240 int inlinesize, outlinesize, initer;
253 case V4L2_PIX_FMT_GREY:
return rawimgcv;
255 case V4L2_PIX_FMT_YUYV:
258 result = cv::Mat(cv::Size(src.
width, src.
height), CV_8UC1);
259 cv::parallel_for_(cv::Range(0, src.
height), yuyvToGrayNEON(rawimgcv, result.data, result.cols));
261 cv::cvtColor(rawimgcv, result, cv::COLOR_YUV2GRAY_YUYV);
265 case V4L2_PIX_FMT_SRGGB8: cv::cvtColor(rawimgcv, result, cv::COLOR_BayerBG2GRAY);
return result;
267 case V4L2_PIX_FMT_RGB565:
268 result = cv::Mat(cv::Size(src.
width, src.
height), CV_8UC1);
269 cv::parallel_for_(cv::Range(0, src.
height), rgb565ToGray(rawimgcv, result.data, result.cols));
272 case V4L2_PIX_FMT_MJPEG:
LFATAL(
"MJPEG not supported");
274 case V4L2_PIX_FMT_BGR24: cv::cvtColor(rawimgcv, result, cv::COLOR_BGR2GRAY);
return result;
276 case V4L2_PIX_FMT_RGB24: cv::cvtColor(rawimgcv, result, cv::COLOR_RGB2GRAY);
return result;
278 LFATAL(
"Unknown RawImage pixel format");
289 case V4L2_PIX_FMT_BGR24:
return rawimgcv;
291 case V4L2_PIX_FMT_YUYV: cv::cvtColor(rawimgcv, result, cv::COLOR_YUV2BGR_YUYV);
return result;
292 case V4L2_PIX_FMT_GREY: cv::cvtColor(rawimgcv, result, cv::COLOR_GRAY2BGR);
return result;
293 case V4L2_PIX_FMT_SRGGB8: cv::cvtColor(rawimgcv, result, cv::COLOR_BayerBG2BGR);
return result;
295 case V4L2_PIX_FMT_RGB565:
296 result = cv::Mat(cv::Size(src.
width, src.
height), CV_8UC3);
297 cv::parallel_for_(cv::Range(0, src.
height), rgb565ToBGR(rawimgcv, result.data, result.cols));
300 case V4L2_PIX_FMT_MJPEG:
LFATAL(
"MJPEG not supported");
301 case V4L2_PIX_FMT_RGB24: cv::cvtColor(rawimgcv, result, cv::COLOR_RGB2BGR);
return result;
303 LFATAL(
"Unknown RawImage pixel format");
314 case V4L2_PIX_FMT_RGB24:
return rawimgcv;
316 case V4L2_PIX_FMT_YUYV: cv::cvtColor(rawimgcv, result, cv::COLOR_YUV2RGB_YUYV);
return result;
317 case V4L2_PIX_FMT_GREY: cv::cvtColor(rawimgcv, result, cv::COLOR_GRAY2RGB);
return result;
318 case V4L2_PIX_FMT_SRGGB8: cv::cvtColor(rawimgcv, result, cv::COLOR_BayerBG2RGB);
return result;
320 case V4L2_PIX_FMT_RGB565:
321 result = cv::Mat(cv::Size(src.
width, src.
height), CV_8UC3);
322 cv::parallel_for_(cv::Range(0, src.
height), rgb565ToRGB(rawimgcv, result.data, result.cols));
325 case V4L2_PIX_FMT_MJPEG:
LFATAL(
"MJPEG not supported");
326 case V4L2_PIX_FMT_BGR24: cv::cvtColor(rawimgcv, result, cv::COLOR_BGR2RGB);
return result;
328 LFATAL(
"Unknown RawImage pixel format");
339 case V4L2_PIX_FMT_YUYV: cv::cvtColor(rawimgcv, result, cv::COLOR_YUV2RGBA_YUYV);
return result;
341 case V4L2_PIX_FMT_GREY: cv::cvtColor(rawimgcv, result, cv::COLOR_GRAY2RGBA);
return result;
343 case V4L2_PIX_FMT_SRGGB8:
348 cv::cvtColor(rawimgcv, fixme, cv::COLOR_BayerBG2RGB);
349 cv::cvtColor(fixme, result, cv::COLOR_RGB2RGBA);
353 case V4L2_PIX_FMT_RGB565:
354 result = cv::Mat(cv::Size(src.
width, src.
height), CV_8UC4);
355 cv::parallel_for_(cv::Range(0, src.
height), rgb565ToRGBA(rawimgcv, result.data, result.cols));
358 case V4L2_PIX_FMT_MJPEG:
LFATAL(
"MJPEG not supported");
360 case V4L2_PIX_FMT_BGR24: cv::cvtColor(rawimgcv, result, cv::COLOR_BGR2RGBA);
return result;
362 case V4L2_PIX_FMT_RGB24: cv::cvtColor(rawimgcv, result, cv::COLOR_RGB2RGBA);
return result;
364 LFATAL(
"Unknown RawImage pixel format");
370 if (img.
bytesperpix() != 2)
LFATAL(
"Can only byteswap images with 2 bytes/pixel");
372#ifdef JEVOIS_PLATFORM
374 unsigned int ncores = 4;
375 size_t const nbc = img.
bytesize() / ncores;
376 unsigned char * ptr = img.
pixelsw<
unsigned char>();
381 std::vector<std::future<void> > fut;
382 for (
unsigned int core = 0; core < ncores-1; ++core)
384 unsigned char * cptr = ptr + core * nbc;
385 for (size_t i = 0; i < nbc; i += 16) vst1q_u8(cptr + i, vrev16q_u8(vld1q_u8(cptr + i)));
390 for (
size_t i = (ncores-1) * nbc; i < sz; i += 16) vst1q_u8(ptr + i, vrev16q_u8(vld1q_u8(ptr + i)));
393 for (
auto & f : fut) f.get();
397 unsigned short * ptr = img.
pixelsw<
unsigned short>();
398 for (
size_t i = 0; i < sz; ++i) ptr[i] = __builtin_bswap16(ptr[i]);
405 if (src.
fmt != dest.
fmt)
LFATAL(
"src and dest must have the same pixel format");
406 if (x < 0 || y < 0 || x + src.width > dest.
width || y + src.
height > dest.
height)
407 LFATAL(
"src does not fit within dest");
411 unsigned char const * sptr = src.
pixels<
unsigned char>();
412 unsigned char * dptr = dest.
pixelsw<
unsigned char>() + (x + y * dest.
width) * bpp;
413 size_t const srclinelen = src.
width * bpp;
414 size_t const dstlinelen = dest.
width * bpp;
416 for (
unsigned int j = 0; j < src.
height; ++j)
418 memcpy(dptr, sptr, srclinelen);
428 if (src.
fmt != dest.
fmt)
LFATAL(
"src and dest must have the same pixel format");
429 if (x < 0 || y < 0 || x + w > src.
width || y +
h > src.
height)
LFATAL(
"roi not within source image");
430 if (dx < 0 || dy < 0 || dx + w > dest.
width || dy +
h > dest.
height)
LFATAL(
"roi not within dest image");
434 unsigned char const * sptr = src.
pixels<
unsigned char>() + (x + y * src.
width) * bpp;
435 unsigned char * dptr = dest.
pixelsw<
unsigned char>() + (dx + dy * dest.
width) * bpp;
436 size_t const srclinelen = src.
width * bpp;
437 size_t const dstlinelen = dest.
width * bpp;
439 for (
unsigned int j = 0; j <
h; ++j)
441 memcpy(dptr, sptr, w * bpp);
450 if (x + src.cols >
int(dest.
width) || y + src.rows >
int(dest.
height))
LFATAL(
"src does not fit within dest");
453 unsigned char const * sptr = src.data;
454 unsigned char * dptr = dest.
pixelsw<
unsigned char>() + (x + y * dest.
width) * bpp;
455 size_t const dststride = (dest.
width - src.cols) * bpp;
457 for (
int j = 0; j < src.rows; ++j)
459 for (
int i = 0; i < src.cols; ++i) { *dptr++ = *sptr++; *dptr++ = 0x80; }
468 unsigned short *
const dptr = img.
pixelsw<
unsigned short>();
469 int const w = int(img.
width);
471 if (rad == 0) {
if (img.
coordsOk(cx, cy)) dptr[cx + w * cy] = col;
return; }
473 int const intrad = rad;
474 for (
int y = -intrad; y <= intrad; ++y)
476 int bound = int(std::sqrt(
float(intrad * intrad - y * y)));
477 for (
int x = -bound; x <= bound; ++x)
478 if (img.
coordsOk(x + cx, y + cy)) dptr[x + cx + w * (y + cy)] = col;
484 unsigned int thick,
unsigned int col)
491 int bound1 = rad, bound2;
493 for (
unsigned int dy = 1; dy <= rad; ++dy)
496 bound1 = int(0.4999F + sqrtf(rad*rad - dy*dy));
497 for (
int dx = bound1; dx <= bound2; ++dx)
511 inline bool isZero(
double a)
512 {
return (a < 0.0001 && a > -0.0001 ); }
514 bool clipT(
double num,
double denom,
double & tE,
double & tL)
516 if (isZero(denom))
return (num <= 0.0);
518 double t = num / denom;
521 if (t > tL)
return false;
524 if (t < tE)
return false;
537 if (x1 < wxmin && x2 < wxmin)
return false;
538 if (x1 >= wxmax && x2 >= wxmax)
return false;
539 if (y1 < wymin && y2 < wymin)
return false;
540 if (y1 >= wymax && y2 >= wymax)
return false;
542 int const toofar = 5000;
543 if (x1 < -toofar || x1 > toofar || y1 < -toofar || y1 > toofar)
return false;
544 if (x2 < -toofar || x2 > toofar || y2 < -toofar || y2 > toofar)
return false;
548 double dx = x2 - x1, dy = y2 - y1;
549 if (isZero(dx) && isZero(dy))
return true;
551 double tE = 0.0, tL = 1.0;
553 if (clipT(wxmin - x1, dx, tE, tL) && clipT(x1 - wxmax, -dx, tE, tL) &&
554 clipT(wymin - y1, dy, tE, tL) && clipT(y1 - wymax, -dy, tE, tL))
556 if (tL < 1) { x2 = x1 + tL * dx; y2 = y1 + tL * dy; }
557 if (tE > 0) { x1 += tE * dx; y1 += tE * dy; }
568 if (thick > 500)
LFATAL(
"Thickness " << thick <<
" too large. Did you mistakenly swap thick and col?");
576 int const dx = x2 - x1;
int const ax = std::abs(dx) << 1;
int const sx = dx < 0 ? -1 : 1;
577 int const dy = y2 - y1;
int const ay = std::abs(dy) << 1;
int const sy = dy < 0 ? -1 : 1;
583 int d = ay - (ax >> 1);
589 if (d >= 0) { y += sy; d -= ax; }
595 int d = ax - (ay >> 1);
600 if (d >= 0) { x += sx; d -= ay; }
608 unsigned int thick,
unsigned int col)
634 unsigned int const imgw = img.
width;
635 unsigned short * b = img.
pixelsw<
unsigned short>() + x + y * imgw;
638 unsigned int const offy = (
h-1) * imgw;
639 for (
unsigned int xx = 0; xx < w; ++xx) { b[xx] = col; b[xx + offy] = col; }
642 unsigned int const offx = w-1;
643 for (
unsigned int yy = 0; yy <
h * imgw; yy += imgw) { b[yy] = col; b[yy + offx] = col; }
656 unsigned int const stride = img.
width - w;
657 unsigned short * b = img.
pixelsw<
unsigned short>() + x + y * img.
width;
659 for (
unsigned int yy = 0; yy <
h; ++yy)
661 for (
unsigned int xx = 0; xx < w; ++xx) *b++ = col;
673 extern const unsigned char font10x20[95][200];
674 extern const unsigned char font11x22[95][242];
675 extern const unsigned char font12x22[95][264];
676 extern const unsigned char font14x26[95][364];
677 extern const unsigned char font15x28[95][420];
678 extern const unsigned char font16x29[95][464];
679 extern const unsigned char font20x38[95][760];
680 extern const unsigned char font5x7[95][35];
681 extern const unsigned char font6x10[95][60];
682 extern const unsigned char font7x13[95][91];
700 int len = int(strlen(txt));
701 unsigned int const imgw = img.
width;
703 int fontw, fonth;
unsigned char const * fontptr;
718 default:
LFATAL(
"Invalid font");
722 if (y < 0 || y + fonth >
int(img.
height))
return;
723 while (x + len * fontw >
int(imgw)) { --len;
if (len <= 0)
return; }
730 unsigned short * b = img.
pixelsw<
unsigned short>() + x + y * imgw;
732 for (
int i = 0; i < len; ++i)
734 int idx = txt[i] - 32;
if (idx >= 95) idx = 0;
735 unsigned char const * ptr = fontptr + fontw * fonth * idx;
736 unsigned short * bb = b;
737 for (
int yy = 0; yy < fonth; ++yy)
740 for (
int xx = 0; xx < fontw; ++xx)
if (*ptr++) ++bb;
else *bb++ = col;
750 unsigned char * b = img.
pixelsw<
unsigned char>() + x + y * imgw;
752 for (
int i = 0; i < len; ++i)
754 int idx = txt[i] - 32;
if (idx >= 95) idx = 0;
755 unsigned char const * ptr = fontptr + fontw * fonth * idx;
756 unsigned char * bb = b;
757 for (
int yy = 0; yy < fonth; ++yy)
760 for (
int xx = 0; xx < fontw; ++xx)
if (*ptr++) ++bb;
else *bb++ = col;
769 LFATAL(
"Sorry, only 1 and 2 bytes/pixel images are supported for now");
790 case Font5x7: fonth = 7;
break;
802 default:
LFATAL(
"Invalid font");
805 return y + fonth + 2;
811 class bgrToBayer :
public cv::ParallelLoopBody
814 bgrToBayer(cv::Mat
const & inputImage,
unsigned char * outImage,
size_t outw) :
815 inImg(inputImage), outImg(outImage)
817 inlinesize = inputImage.cols * 3;
818 outlinesize = outw * 1;
821 virtual void operator()(
const cv::Range & range)
const
823 for (
int j = range.start; j < range.end; ++j)
825 int const inoff = j * inlinesize;
826 int const outoff = j * outlinesize;
828 for (
int i = 0; i < inImg.cols; i += 2)
830 int const in = inoff + i * 3;
831 int const out = outoff + i;
833 if ( (j & 1) == 0) { outImg[out + 0] = inImg.data[in + 2]; outImg[out + 1] = inImg.data[in + 4]; }
834 else { outImg[out + 0] = inImg.data[in + 1]; outImg[out + 1] = inImg.data[in + 3]; }
840 cv::Mat
const & inImg;
841 unsigned char * outImg;
842 int inlinesize, outlinesize;
848 if (src.type() != CV_8UC3)
850 if (dst.
fmt != V4L2_PIX_FMT_SRGGB8)
LFATAL(
"dst format must be V4L2_PIX_FMT_SRGGB8");
851 if (
int(dst.
width) != src.cols ||
int(dst.
height) != src.rows)
LFATAL(
"src and dst dims must match");
853 cv::parallel_for_(cv::Range(0, src.rows), bgrToBayer(src, dst.
pixelsw<
unsigned char>(), dst.
width));
860 class rgbToBayer :
public cv::ParallelLoopBody
863 rgbToBayer(cv::Mat
const & inputImage,
unsigned char * outImage,
size_t outw) :
864 inImg(inputImage), outImg(outImage)
866 inlinesize = inputImage.cols * 3;
867 outlinesize = outw * 1;
870 virtual void operator()(
const cv::Range & range)
const
872 for (
int j = range.start; j < range.end; ++j)
874 int const inoff = j * inlinesize;
875 int const outoff = j * outlinesize;
877 for (
int i = 0; i < inImg.cols; i += 2)
879 int const in = inoff + i * 3;
880 int const out = outoff + i;
882 if ( (j & 1) == 0) { outImg[out + 0] = inImg.data[in + 0]; outImg[out + 1] = inImg.data[in + 4]; }
883 else { outImg[out + 0] = inImg.data[in + 1]; outImg[out + 1] = inImg.data[in + 5]; }
889 cv::Mat
const & inImg;
890 unsigned char * outImg;
891 int inlinesize, outlinesize;
897 if (src.type() != CV_8UC3)
899 if (dst.
fmt != V4L2_PIX_FMT_SRGGB8)
LFATAL(
"dst format must be V4L2_PIX_FMT_SRGGB8");
900 if (
int(dst.
width) != src.cols ||
int(dst.
height) != src.rows)
LFATAL(
"src and dst dims must match");
902 cv::parallel_for_(cv::Range(0, src.rows), rgbToBayer(src, dst.
pixelsw<
unsigned char>(), dst.
width));
909 class grayToBayer :
public cv::ParallelLoopBody
912 grayToBayer(cv::Mat
const & inputImage,
unsigned char * outImage,
size_t outw) :
913 inImg(inputImage), outImg(outImage)
915 inlinesize = inputImage.cols * 1;
916 outlinesize = outw * 1;
919 virtual void operator()(
const cv::Range & range)
const
921 for (
int j = range.start; j < range.end; ++j)
923 int const inoff = j * inlinesize;
924 int const outoff = j * outlinesize;
926 memcpy(&outImg[outoff], &inImg.data[inoff], inlinesize);
931 cv::Mat
const & inImg;
932 unsigned char * outImg;
933 int inlinesize, outlinesize;
939 if (src.type() != CV_8UC1)
941 if (dst.
fmt != V4L2_PIX_FMT_SRGGB8)
LFATAL(
"dst format must be V4L2_PIX_FMT_SRGGB8");
942 if (
int(dst.
width) != src.cols ||
int(dst.
height) != src.rows)
LFATAL(
"src and dst dims must match");
944 cv::parallel_for_(cv::Range(0, src.rows), grayToBayer(src, dst.
pixelsw<
unsigned char>(), dst.
width));
951 class rgbaToBayer :
public cv::ParallelLoopBody
954 rgbaToBayer(cv::Mat
const & inputImage,
unsigned char * outImage,
size_t outw) :
955 inImg(inputImage), outImg(outImage)
957 inlinesize = inputImage.cols * 4;
958 outlinesize = outw * 1;
961 virtual void operator()(
const cv::Range & range)
const
963 for (
int j = range.start; j < range.end; ++j)
965 int const inoff = j * inlinesize;
966 int const outoff = j * outlinesize;
968 for (
int i = 0; i < inImg.cols; i += 2)
970 int const in = inoff + i * 4;
971 int const out = outoff + i;
973 if ( (j & 1) == 0) { outImg[out + 0] = inImg.data[in + 0]; outImg[out + 1] = inImg.data[in + 5]; }
974 else { outImg[out + 0] = inImg.data[in + 1]; outImg[out + 1] = inImg.data[in + 6]; }
980 cv::Mat
const & inImg;
981 unsigned char * outImg;
982 int inlinesize, outlinesize;
988 if (src.type() != CV_8UC4)
990 if (dst.
fmt != V4L2_PIX_FMT_SRGGB8)
LFATAL(
"dst format must be V4L2_PIX_FMT_SRGGB8");
991 if (
int(dst.
width) != src.cols ||
int(dst.
height) != src.rows)
LFATAL(
"src and dst dims must match");
993 cv::parallel_for_(cv::Range(0, src.rows), rgbaToBayer(src, dst.
pixelsw<
unsigned char>(), dst.
width));
1000 class bgrToYUYV :
public cv::ParallelLoopBody
1003 bgrToYUYV(cv::Mat
const & inputImage,
unsigned char * outImage,
size_t outw) :
1004 inImg(inputImage), outImg(outImage)
1006 inlinesize = inputImage.cols * 3;
1007 outlinesize = outw * 2;
1010 virtual void operator()(
const cv::Range & range)
const
1012 for (
int j = range.start; j < range.end; ++j)
1014 int const inoff = j * inlinesize;
1015 int const outoff = j * outlinesize;
1017 for (
int i = 0; i < inImg.cols; i += 2)
1019 int mc = inoff + i * 3;
1020 unsigned char const B1 = inImg.data[mc + 0];
1021 unsigned char const G1 = inImg.data[mc + 1];
1022 unsigned char const R1 = inImg.data[mc + 2];
1023 unsigned char const B2 = inImg.data[mc + 3];
1024 unsigned char const G2 = inImg.data[mc + 4];
1025 unsigned char const R2 = inImg.data[mc + 5];
1027 float const Y1 = (0.257F * R1) + (0.504F * G1) + (0.098F * B1) + 16.0F;
1029 float const U1 = -(0.148F * R1) - (0.291F * G1) + (0.439F * B1) + 128.0F;
1030 float const Y2 = (0.257F * R2) + (0.504F * G2) + (0.098F * B2) + 16.0F;
1031 float const V2 = (0.439F * R2) - (0.368F * G2) - (0.071F * B2) + 128.0F;
1034 mc = outoff + i * 2;
1035 outImg[mc + 0] = Y1;
1036 outImg[mc + 1] = U1;
1037 outImg[mc + 2] = Y2;
1038 outImg[mc + 3] = V2;
1044 cv::Mat
const & inImg;
1045 unsigned char * outImg;
1046 int inlinesize, outlinesize;
1052 if (src.type() != CV_8UC3)
1054 if (dst.
fmt != V4L2_PIX_FMT_YUYV)
LFATAL(
"dst format must be V4L2_PIX_FMT_YUYV");
1055 if (
int(dst.
width) != src.cols ||
int(dst.
height) < src.rows)
LFATAL(
"src and dst dims must match");
1057 cv::parallel_for_(cv::Range(0, src.rows), bgrToYUYV(src, dst.
pixelsw<
unsigned char>(), dst.
width));
1064 if (src.type() != CV_8UC3)
1066 dst = cv::Mat(src.rows, src.cols, CV_8UC2);
1068 cv::parallel_for_(cv::Range(0, src.rows), bgrToYUYV(src, dst.data, dst.cols));
1074 if (src.type() != CV_8UC3)
1076 if (dst.
fmt != V4L2_PIX_FMT_YUYV)
LFATAL(
"dst format must be V4L2_PIX_FMT_YUYV");
1077 if (x + src.cols >
int(dst.
width) || y + src.rows >
int(dst.
height))
LFATAL(
"src does not fit within dst");
1079 cv::parallel_for_(cv::Range(0, src.rows), bgrToYUYV(src, dst.
pixelsw<
unsigned char>() +
1086 class rgbToYUYV :
public cv::ParallelLoopBody
1089 rgbToYUYV(cv::Mat
const & inputImage,
unsigned char * outImage,
size_t outw) :
1090 inImg(inputImage), outImg(outImage)
1092 inlinesize = inputImage.cols * 3;
1093 outlinesize = outw * 2;
1096 virtual void operator()(
const cv::Range & range)
const
1098 for (
int j = range.start; j < range.end; ++j)
1100 int const inoff = j * inlinesize;
1101 int const outoff = j * outlinesize;
1103 for (
int i = 0; i < inImg.cols; i += 2)
1105 int mc = inoff + i * 3;
1106 unsigned char const R1 = inImg.data[mc + 0];
1107 unsigned char const G1 = inImg.data[mc + 1];
1108 unsigned char const B1 = inImg.data[mc + 2];
1109 unsigned char const R2 = inImg.data[mc + 3];
1110 unsigned char const G2 = inImg.data[mc + 4];
1111 unsigned char const B2 = inImg.data[mc + 5];
1113 float const Y1 = (0.257F * R1) + (0.504F * G1) + (0.098F * B1) + 16.0F;
1115 float const U1 = -(0.148F * R1) - (0.291F * G1) + (0.439F * B1) + 128.0F;
1116 float const Y2 = (0.257F * R2) + (0.504F * G2) + (0.098F * B2) + 16.0F;
1117 float const V2 = (0.439F * R2) - (0.368F * G2) - (0.071F * B2) + 128.0F;
1120 mc = outoff + i * 2;
1121 outImg[mc + 0] = Y1;
1122 outImg[mc + 1] = U1;
1123 outImg[mc + 2] = Y2;
1124 outImg[mc + 3] = V2;
1130 cv::Mat
const & inImg;
1131 unsigned char * outImg;
1132 int inlinesize, outlinesize;
1138 if (src.type() != CV_8UC3)
1140 if (dst.
fmt != V4L2_PIX_FMT_YUYV)
LFATAL(
"dst format must be V4L2_PIX_FMT_YUYV");
1141 if (
int(dst.
width) != src.cols ||
int(dst.
height) < src.rows)
LFATAL(
"src and dst dims must match");
1143 cv::parallel_for_(cv::Range(0, src.rows), rgbToYUYV(src, dst.
pixelsw<
unsigned char>(), dst.
width));
1150 if (src.type() != CV_8UC3)
1152 dst = cv::Mat(src.rows, src.cols, CV_8UC2);
1154 cv::parallel_for_(cv::Range(0, src.rows), rgbToYUYV(src, dst.data, dst.cols));
1160 if (src.type() != CV_8UC3)
1162 if (dst.
fmt != V4L2_PIX_FMT_YUYV)
LFATAL(
"dst format must be V4L2_PIX_FMT_YUYV");
1163 if (x + src.cols >
int(dst.
width) || y + src.rows >
int(dst.
height))
LFATAL(
"src does not fit within dst");
1165 cv::parallel_for_(cv::Range(0, src.rows), rgbToYUYV(src, dst.
pixelsw<
unsigned char>() +
1172 class grayToYUYV :
public cv::ParallelLoopBody
1175 grayToYUYV(cv::Mat
const & inputImage,
unsigned char * outImage,
size_t outw) :
1176 inImg(inputImage), outImg(outImage)
1178 inlinesize = inputImage.cols * 1;
1179 outlinesize = outw * 2;
1182 virtual void operator()(
const cv::Range & range)
const
1184 for (
int j = range.start; j < range.end; ++j)
1186 int const inoff = j * inlinesize;
1187 int const outoff = j * outlinesize;
1189 for (
int i = 0; i < inImg.cols; ++i)
1192 unsigned char const G = inImg.data[mc + 0];
1194 mc = outoff + i * 2;
1196 outImg[mc + 1] = 0x80;
1202 cv::Mat
const & inImg;
1203 unsigned char * outImg;
1204 int inlinesize, outlinesize;
1210 if (src.type() != CV_8UC1)
1212 if (dst.
fmt != V4L2_PIX_FMT_YUYV)
LFATAL(
"dst format must be V4L2_PIX_FMT_YUYV");
1213 if (
int(dst.
width) != src.cols ||
int(dst.
height) < src.rows)
LFATAL(
"src and dst dims must match");
1215 cv::parallel_for_(cv::Range(0, src.rows), grayToYUYV(src, dst.
pixelsw<
unsigned char>(), dst.
width));
1222 if (src.type() != CV_8UC1)
1224 dst = cv::Mat(src.rows, src.cols, CV_8UC2);
1226 cv::parallel_for_(cv::Range(0, src.rows), grayToYUYV(src, dst.data, dst.cols));
1232 class rgbaToYUYV :
public cv::ParallelLoopBody
1235 rgbaToYUYV(cv::Mat
const & inputImage,
unsigned char * outImage,
size_t outw) :
1236 inImg(inputImage), outImg(outImage)
1238 inlinesize = inputImage.cols * 4;
1239 outlinesize = outw * 2;
1242 virtual void operator()(
const cv::Range & range)
const
1244 for (
int j = range.start; j < range.end; ++j)
1246 int const inoff = j * inlinesize;
1247 int const outoff = j * outlinesize;
1249 for (
int i = 0; i < inImg.cols; i += 2)
1251 int mc = inoff + i * 4;
1252 unsigned char const R1 = inImg.data[mc + 0];
1253 unsigned char const G1 = inImg.data[mc + 1];
1254 unsigned char const B1 = inImg.data[mc + 2];
1255 unsigned char const R2 = inImg.data[mc + 4];
1256 unsigned char const G2 = inImg.data[mc + 5];
1257 unsigned char const B2 = inImg.data[mc + 6];
1259 float const Y1 = (0.257F * R1) + (0.504F * G1) + (0.098F * B1) + 16.0F;
1260 float const U1 = -(0.148F * R1) - (0.291F * G1) + (0.439F * B1) + 128.0F;
1261 float const Y2 = (0.257F * R2) + (0.504F * G2) + (0.098F * B2) + 16.0F;
1262 float const V2 = (0.439F * R2) - (0.368F * G2) - (0.071F * B2) + 128.0F;
1264 mc = outoff + i * 2;
1265 outImg[mc + 0] = Y1;
1266 outImg[mc + 1] = U1;
1267 outImg[mc + 2] = Y2;
1268 outImg[mc + 3] = V2;
1274 cv::Mat
const & inImg;
1275 unsigned char * outImg;
1276 int inlinesize, outlinesize;
1282 if (src.type() != CV_8UC4)
1284 if (dst.
fmt != V4L2_PIX_FMT_YUYV)
LFATAL(
"dst format must be V4L2_PIX_FMT_YUYV");
1285 if (
int(dst.
width) != src.cols ||
int(dst.
height) != src.rows)
LFATAL(
"src and dst dims must match");
1287 cv::parallel_for_(cv::Range(0, src.rows), rgbaToYUYV(src, dst.
pixelsw<
unsigned char>(), dst.
width));
1294 if (src.type() != CV_8UC4)
1296 dst = cv::Mat(src.rows, src.cols, CV_8UC2);
1298 cv::parallel_for_(cv::Range(0, src.rows), rgbaToYUYV(src, dst.data, dst.cols));
1304 if (src.type() != CV_8UC3)
1306 if (
int(dst.
width) != src.cols ||
int(dst.
height) < src.rows)
LFATAL(
"src and dst dims must match");
1313 case V4L2_PIX_FMT_SRGGB8: convertCvBGRtoBayer(src, dst);
break;
1314 case V4L2_PIX_FMT_YUYV: convertCvBGRtoYUYV(src, dst);
break;
1315 case V4L2_PIX_FMT_GREY: cv::cvtColor(src, dstcv, cv::COLOR_BGR2GRAY);
break;
1316 case V4L2_PIX_FMT_RGB565: cv::cvtColor(src, dstcv, cv::COLOR_BGR2BGR565);
break;
1319 case V4L2_PIX_FMT_RGB24: cv::cvtColor(src, dstcv, cv::COLOR_BGR2RGB);
break;
1327 if (src.type() != CV_8UC3)
1329 if (
int(dst.
width) != src.cols ||
int(dst.
height) < src.rows)
LFATAL(
"src and dst dims must match");
1336 case V4L2_PIX_FMT_SRGGB8: convertCvRGBtoBayer(src, dst);
break;
1337 case V4L2_PIX_FMT_YUYV: convertCvRGBtoYUYV(src, dst);
break;
1338 case V4L2_PIX_FMT_GREY: cv::cvtColor(src, dstcv, cv::COLOR_RGB2GRAY);
break;
1339 case V4L2_PIX_FMT_RGB565: cv::cvtColor(src, dstcv, cv::COLOR_RGB2BGR565);
break;
1341 case V4L2_PIX_FMT_BGR24: cv::cvtColor(src, dstcv, cv::COLOR_RGB2BGR);
break;
1350 if (src.type() != CV_8UC4)
1352 if (dst.
fmt != V4L2_PIX_FMT_GREY)
LFATAL(
"dst must have pixel type V4L2_PIX_FMT_GREY");
1353 int const w = src.cols,
h = src.rows;
1354 if (
int(dst.
width) < w ||
int(dst.
height) < 4 *
h)
LFATAL(
"dst must be at least as wide and 4x as tall as src");
1356 unsigned char const * sptr = src.data;
unsigned char * dptr = dst.
pixelsw<
unsigned char>();
1357 int const stride = int(dst.
width) - w;
1360 std::vector<std::future<void> > fut;
1361 for (
int i = 0; i < 3; ++i) fut.push_back(
jevois::async([&](
int offset) {
1362 unsigned char const * s = sptr + offset; unsigned char * d = dptr + offset * w * h;
1363 for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { *d++ = *s; s += 4; } d += stride; } }, i));
1365 unsigned char const * s = sptr + 3;
unsigned char * d = dptr + 3 * w *
h;
1366 for (
int y = 0; y <
h; ++y) {
for (
int x = 0; x < w; ++x) { *d++ = *s; s += 4; } d += stride; }
1369 for (
auto & f : fut) f.get();
1375 if (src.type() != CV_8UC4)
1377 if (
int(dst.
width) != src.cols ||
int(dst.
height) != src.rows)
LFATAL(
"src and dst dims must match");
1383 case V4L2_PIX_FMT_SRGGB8: convertCvRGBAtoBayer(src, dst);
break;
1384 case V4L2_PIX_FMT_YUYV: convertCvRGBAtoYUYV(src, dst);
break;
1385 case V4L2_PIX_FMT_GREY: cv::cvtColor(src, dstcv, cv::COLOR_RGBA2GRAY);
break;
1386 case V4L2_PIX_FMT_RGB565: cv::cvtColor(src, dstcv, cv::COLOR_BGRA2BGR565);
break;
1388 case V4L2_PIX_FMT_BGR24: cv::cvtColor(src, dstcv, cv::COLOR_RGBA2BGR);
break;
1389 case V4L2_PIX_FMT_RGB24: cv::cvtColor(src, dstcv, cv::COLOR_RGBA2RGB);
break;
1397 if (src.type() != CV_8UC1)
1399 if (
int(dst.
width) != src.cols ||
int(dst.
height) != src.rows)
LFATAL(
"src and dst dims must match");
1405 case V4L2_PIX_FMT_SRGGB8: convertCvGRAYtoBayer(src, dst);
break;
1406 case V4L2_PIX_FMT_YUYV: convertCvGRAYtoYUYV(src, dst);
break;
1408 case V4L2_PIX_FMT_RGB565: cv::cvtColor(src, dstcv, cv::COLOR_GRAY2BGR565);
break;
1410 case V4L2_PIX_FMT_BGR24: cv::cvtColor(src, dstcv, cv::COLOR_GRAY2BGR);
break;
1411 case V4L2_PIX_FMT_RGB24: cv::cvtColor(src, dstcv, cv::COLOR_GRAY2RGB);
break;
1419 class hflipYUYV :
public cv::ParallelLoopBody
1422 hflipYUYV(
unsigned char * outImage,
size_t outw) :
1423 outImg(outImage), linesize(outw * 2)
1426 virtual void operator()(
const cv::Range & range)
const
1428 for (
int j = range.start; j < range.end; ++j)
1430 int const off = j * linesize;
1432 for (
int i = 0; i < linesize / 2; i += 4)
1434 unsigned char * ptr1 = outImg + off + i;
1435 unsigned char * ptr2 = outImg + off + linesize - 4 - i;
1436 std::swap(ptr1[0], ptr2[2]);
1437 std::swap(ptr1[1], ptr2[1]);
1438 std::swap(ptr1[2], ptr2[0]);
1439 std::swap(ptr1[3], ptr2[3]);
1445 unsigned char * outImg;
1454 if (img.
fmt != V4L2_PIX_FMT_YUYV)
LFATAL(
"img format must be V4L2_PIX_FMT_YUYV");
1455 cv::parallel_for_(cv::Range(0, img.
height), hflipYUYV(img.
pixelsw<
unsigned char>(), img.
width));
1462 class bayerToYUYV :
public cv::ParallelLoopBody
1465 bayerToYUYV(cv::Mat
const & inputImage,
unsigned char * outImage,
size_t outw) :
1466 inImg(inputImage), outImg(outImage)
1468 inlinesize = inputImage.cols;
1469 outlinesize = outw * 2;
1472 virtual void operator()(
const cv::Range & range)
const
1474 uint16x8_t
const masklo = vdupq_n_u16(255);
1476 const uint8x8_t u8_zero = vdup_n_u8(0);
1477 const uint16x8_t u16_rounding = vdupq_n_u16(128);
1478 const int16x8_t s16_rounding = vdupq_n_s16(128);
1479 const int8x16_t s8_rounding = vdupq_n_s8(128);
1481 for (
int j = range.start; j < range.end; ++j)
1483 int const inoff = j * inlinesize;
1484 int const outoff = j * outlinesize;
1486 unsigned char const * bayer = inImg.data + inoff;
1487 unsigned char const * bayer_end = bayer + inlinesize;
1488 int const bayer_step = inlinesize;
1489 unsigned char * dst = outImg + outoff;
1496 for( ; bayer <= bayer_end - 18; bayer += 14, dst += 28 )
1498 uint16x8_t r0 = vld1q_u16((
const ushort*)bayer);
1499 uint16x8_t r1 = vld1q_u16((
const ushort*)(bayer + bayer_step));
1500 uint16x8_t r2 = vld1q_u16((
const ushort*)(bayer + bayer_step*2));
1502 uint16x8_t b1 = vaddq_u16(vandq_u16(r0, masklo), vandq_u16(r2, masklo));
1503 uint16x8_t nextb1 = vextq_u16(b1, b1, 1);
1504 uint16x8_t b0 = vaddq_u16(b1, nextb1);
1506 uint8x8x2_t bb = vzip_u8(vrshrn_n_u16(b0, 2), vrshrn_n_u16(nextb1, 1));
1507 pix.val[2] = vcombine_u8(bb.val[0], bb.val[1]);
1509 uint16x8_t g0 = vaddq_u16(vshrq_n_u16(r0, 8), vshrq_n_u16(r2, 8));
1510 uint16x8_t g1 = vandq_u16(r1, masklo);
1511 g0 = vaddq_u16(g0, vaddq_u16(g1, vextq_u16(g1, g1, 1)));
1512 g1 = vextq_u16(g1, g1, 1);
1514 uint8x8x2_t gg = vzip_u8(vrshrn_n_u16(g0, 2), vmovn_u16(g1));
1515 pix.val[1] = vcombine_u8(gg.val[0], gg.val[1]);
1517 r0 = vshrq_n_u16(r1, 8);
1518 r1 = vaddq_u16(r0, vextq_u16(r0, r0, 1));
1520 uint8x8x2_t rr = vzip_u8(vmovn_u16(r0), vrshrn_n_u16(r1, 1));
1521 pix.val[0] = vcombine_u8(rr.val[0], rr.val[1]);
1526 uint8x8_t high_r = vget_high_u8(pix.val[2]);
1527 uint8x8_t low_r = vget_low_u8(pix.val[2]);
1528 uint8x8_t high_g = vget_high_u8(pix.val[1]);
1529 uint8x8_t low_g = vget_low_u8(pix.val[1]);
1530 uint8x8_t high_b = vget_high_u8(pix.val[0]);
1531 uint8x8_t low_b = vget_low_u8(pix.val[0]);
1532 int16x8_t signed_high_r = vreinterpretq_s16_u16(vaddl_u8(high_r, u8_zero));
1533 int16x8_t signed_low_r = vreinterpretq_s16_u16(vaddl_u8(low_r, u8_zero));
1534 int16x8_t signed_high_g = vreinterpretq_s16_u16(vaddl_u8(high_g, u8_zero));
1535 int16x8_t signed_low_g = vreinterpretq_s16_u16(vaddl_u8(low_g, u8_zero));
1536 int16x8_t signed_high_b = vreinterpretq_s16_u16(vaddl_u8(high_b, u8_zero));
1537 int16x8_t signed_low_b = vreinterpretq_s16_u16(vaddl_u8(low_b, u8_zero));
1543 uint8x8_t scalar = vdup_n_u8(76);
1546 int16x8_t signed_scalar = vdupq_n_s16(-43);
1549 uint8x16x3_t pixel_yuv;
1554 high_y = vmull_u8(high_r, scalar);
1555 low_y = vmull_u8(low_r, scalar);
1557 high_u = vmulq_s16(signed_high_r, signed_scalar);
1558 low_u = vmulq_s16(signed_low_r, signed_scalar);
1560 signed_scalar = vdupq_n_s16(127);
1561 high_v = vmulq_s16(signed_high_r, signed_scalar);
1562 low_v = vmulq_s16(signed_low_r, signed_scalar);
1564 scalar = vdup_n_u8(150);
1565 high_y = vmlal_u8(high_y, high_g, scalar);
1566 low_y = vmlal_u8(low_y, low_g, scalar);
1568 signed_scalar = vdupq_n_s16(-84);
1569 high_u = vmlaq_s16(high_u, signed_high_g, signed_scalar);
1570 low_u = vmlaq_s16(low_u, signed_low_g, signed_scalar);
1572 signed_scalar = vdupq_n_s16(-106);
1573 high_v = vmlaq_s16(high_v, signed_high_g, signed_scalar);
1574 low_v = vmlaq_s16(low_v, signed_low_g, signed_scalar);
1576 scalar = vdup_n_u8(29);
1577 high_y = vmlal_u8(high_y, high_b, scalar);
1578 low_y = vmlal_u8(low_y, low_b, scalar);
1580 signed_scalar = vdupq_n_s16(127);
1581 high_u = vmlaq_s16(high_u, signed_high_b, signed_scalar);
1582 low_u = vmlaq_s16(low_u, signed_low_b, signed_scalar);
1584 signed_scalar = vdupq_n_s16(-21);
1585 high_v = vmlaq_s16(high_v, signed_high_b, signed_scalar);
1586 low_v = vmlaq_s16(low_v, signed_low_b, signed_scalar);
1590 high_y = vaddq_u16(high_y, u16_rounding);
1591 low_y = vaddq_u16(low_y, u16_rounding);
1593 high_u = vaddq_s16(high_u, s16_rounding);
1594 low_u = vaddq_s16(low_u, s16_rounding);
1596 high_v = vaddq_s16(high_v, s16_rounding);
1597 low_v = vaddq_s16(low_v, s16_rounding);
1599 pixel_yuv.val[0] = vcombine_u8(vqshrn_n_u16(low_y, 8), vqshrn_n_u16(high_y, 8));
1601 u = vcombine_s8(vqshrn_n_s16(low_u, 8), vqshrn_n_s16(high_u, 8));
1603 v = vcombine_s8(vqshrn_n_s16(low_v, 8), vqshrn_n_s16(high_v, 8));
1605 u = vaddq_s8(u, s8_rounding);
1606 pixel_yuv.val[1] = vreinterpretq_u8_s8(u);
1608 v = vaddq_s8(v, s8_rounding);
1609 pixel_yuv.val[2] = vreinterpretq_u8_s8(v);
1614 vst3q_u8(dst, pixel_yuv);
1620 cv::Mat
const & inImg;
1621 unsigned char * outImg;
1622 int inlinesize, outlinesize;
1631 if (src.
fmt != V4L2_PIX_FMT_SRGGB8)
LFATAL(
"src format must be V4L2_PIX_FMT_SRGGB8");
1632 if (dst.
fmt != V4L2_PIX_FMT_YUYV)
LFATAL(
"dst format must be V4L2_PIX_FMT_YUYV");
1637#ifdef FIXME__ARM_NEON__
1639 cv::parallel_for_(cv::Range(0, cvsrc.rows), bayerToYUYV(cvsrc, dst.
pixelsw<
unsigned char>(), dst.
width));
1643 cv::cvtColor(cvsrc, xx, cv::COLOR_BayerBG2BGR);
1644 cv::parallel_for_(cv::Range(0, xx.rows), bgrToYUYV(xx, cvdst.data, cvdst.cols));
1651 if (src.
fmt != V4L2_PIX_FMT_GREY)
LFATAL(
"src format must be V4L2_PIX_FMT_GREY");
1652 if (dst.
fmt != V4L2_PIX_FMT_YUYV)
LFATAL(
"dst format must be V4L2_PIX_FMT_YUYV");
1656 convertCvGRAYtoYUYV(cvsrc, dst);
1664 if (newdims.width == img.cols && newdims.height == img.rows)
1666 else if (newdims.width > img.cols || newdims.height > img.rows)
1667 cv::resize(img, scaled, newdims, 0, 0, cv::INTER_LINEAR);
1669 cv::resize(img, scaled, newdims, 0, 0, cv::INTER_AREA);
A raw image as coming from a V4L2 Camera and/or being sent out to a USB Gadget.
bool coordsOk(int x, int y) const
Helper function to check that coords are within image bounds.
unsigned int fmt
Pixel format as a V4L2_PIX_FMT_XXX.
unsigned int bytesize() const
Helper function to get the total number of bytes in the RawImage, i.e., width * height * bytesperpix(...
T const * pixels() const
Shortcut access to pixels, read-only.
T * pixelsw()
Shortcut access to pixels, read-write.
unsigned int width
Image width in pixels.
unsigned int bytesperpix() const
Helper function to get the number of bytes/pixel given the RawImage pixel format.
unsigned int height
Image height in pixels.
std::shared_ptr< VideoBuf > buf
The pixel data buffer.
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
cv::Mat convertToCvRGBA(RawImage const &src)
Convert RawImage to OpenCV doing color conversion from any RawImage source pixel to OpenCV RGB-A byte...
void paste(RawImage const &src, RawImage &dest, int dx, int dy)
Paste an image within another of same pixel type.
bool clipLine(int wxmin, int wymin, int wxmax, int wymax, int &x1, int &y1, int &x2, int &y2)
Clip a line to fit inside a viewport [wxmin...wxmax[ x [wymin...wymax[.
void convertCvGRAYtoCvYUYV(cv::Mat const &src, cv::Mat &dst)
OpenCV does not provide conversion from GRAY to YUYV in cvtColor(), so this function provides it.
cv::Mat cvImage(RawImage const &src)
Create an OpenCV image from the existing RawImage data, sharing the pixel memory rather than copying ...
void writeText(RawImage &img, std::string const &txt, int x, int y, unsigned int col, Font font=Font6x10)
Write some text in an image.
cv::Mat convertToCvGray(RawImage const &src)
Convert RawImage to OpenCV doing color conversion from any RawImage source pixel to OpenCV gray byte.
void convertCvBGRtoCvYUYV(cv::Mat const &src, cv::Mat &dst)
OpenCV does not provide conversion from BGR to YUYV in cvtColor(), so this function provides it.
void pasteRGBtoYUYV(cv::Mat const &src, RawImage &dst, int dx, int dy)
Paste a RGB byte image into a YUYV image.
cv::Mat convertToCvRGB(RawImage const &src)
Convert RawImage to OpenCV doing color conversion from any RawImage source pixel to OpenCV RGB byte.
void drawFilledRect(RawImage &img, int x, int y, unsigned int w, unsigned int h, unsigned int col)
Draw a filled rectangle in a YUYV image.
void drawDisk(RawImage &img, int x, int y, unsigned int rad, unsigned int col)
Draw a disk in a YUYV image.
void convertCvRGBAtoRawImage(cv::Mat const &src, RawImage &dst, int quality)
Convert an RGBA cv::Mat to RawImage with already-allocated pixels and pixel type.
cv::Mat rescaleCv(cv::Mat const &img, cv::Size const &newdims)
Rescale an OpenCV image, choosing the right kind of interpolation.
Font
Available fonts for writeText()
cv::Mat convertToCvBGR(RawImage const &src)
Convert RawImage to OpenCV doing color conversion from any RawImage source pixel to OpenCV BGR byte.
void convertCvBGRtoRawImage(cv::Mat const &src, RawImage &dst, int quality)
Convert a BGR cv::Mat to RawImage with already-allocated pixels and pixel type.
void drawLine(RawImage &img, int x1, int y1, int x2, int y2, unsigned int thick, unsigned int col)
Draw a line in a YUYV image.
void convertCvRGBtoCvYUYV(cv::Mat const &src, cv::Mat &dst)
OpenCV does not provide conversion from RGB to YUYV in cvtColor(), so this function provides it.
void convertCvRGBtoRawImage(cv::Mat const &src, RawImage &dst, int quality)
Convert a RGB cv::Mat to RawImage with already-allocated pixels and pixel type.
void unpackCvRGBAtoGrayRawImage(cv::Mat const &src, RawImage &dst)
Split an RGBA cv::Mat into a 4x taller grey RawImage with already-allocated pixels.
void drawRect(RawImage &img, int x, int y, unsigned int w, unsigned int h, unsigned int thick, unsigned int col)
Draw a rectangle in a YUYV image.
void hFlipYUYV(RawImage &img)
Flip a YUYV RawImage horizontally while preserving color information.
void roipaste(RawImage const &src, int x, int y, unsigned int w, unsigned int h, RawImage &dest, int dx, int dy)
Paste an ROI from an image to within another of same pixel type.
void byteSwap(RawImage &img)
Swap pairs of bytes in a RawImage.
void convertCvRGBAtoCvYUYV(cv::Mat const &src, cv::Mat &dst)
OpenCV does not provide conversion from RGBA to YUYV in cvtColor(), so this function provides it.
void convertCvGRAYtoRawImage(cv::Mat const &src, RawImage &dst, int quality)
Convert a Gray cv::Mat to RawImage with already-allocated pixels and pixel type.
int itext(RawImage &img, std::string const &txt, int y=3, unsigned int col=jevois::yuyv::White, Font font=Font6x10)
Shorthand to write some text in an image, with x = 3 and return the next y position.
void drawCircle(RawImage &img, int x, int y, unsigned int rad, unsigned int thick, unsigned int col)
Draw a circle in a YUYV image.
void pasteGreyToYUYV(cv::Mat const &src, RawImage &dest, int dx, int dy)
Paste a grey byte image into a YUYV image.
void pasteBGRtoYUYV(cv::Mat const &src, RawImage &dst, int dx, int dy)
Paste a BGR byte image into a YUYV image.
unsigned long compressGRAYtoJpeg(unsigned char const *src, int width, int height, unsigned char *dst, int quality=75)
Compress raw pixel buffer to jpeg.
unsigned long compressBGRtoJpeg(unsigned char const *src, int width, int height, unsigned char *dst, int quality=75)
Compress raw pixel buffer to jpeg.
unsigned long compressRGBAtoJpeg(unsigned char const *src, int width, int height, unsigned char *dst, int quality=75)
Compress raw pixel buffer to jpeg.
unsigned long compressRGBtoJpeg(unsigned char const *src, int width, int height, unsigned char *dst, int quality=75)
Compress raw pixel buffer to jpeg.
std::future< std::invoke_result_t< std::decay_t< Function >, std::decay_t< Args >... > > async(Function &&f, Args &&... args)
Async execution using a thread pool.
unsigned int v4l2BytesPerPix(unsigned int fcc)
Return the number of bytes per pixel for a given V4L2_PIX_FMT_...
std::string cvtypestr(unsigned int cvtype)
Convert cv::Mat::type() code to to a string (e.g., CV_8UC1, CV_32SC3, etc)
std::string fccstr(unsigned int fcc)
Convert a V4L2 four-cc code (V4L2_PIX_FMT_...) to a 4-char string.
const unsigned char font10x20[95][200]
const unsigned char font6x10[95][60]
const unsigned char font15x28[95][420]
const unsigned char font12x22[95][264]
const unsigned char font20x38[95][760]
const unsigned char font7x13[95][91]
const unsigned char font16x29[95][464]
const unsigned char font8x13bold[95][104]
const unsigned char font14x26[95][364]
const unsigned char font11x22[95][242]
const unsigned char font9x15bold[95][135]
const unsigned char font5x7[95][35]
void convertBayerToYUYV(RawImage const &src, RawImage &dst)
Convert from Bayer to YUYV, only used internally by Camera class.
void convertGreyToYUYV(RawImage const &src, RawImage &dst)
Convert from Grey (monochrome) to YUYV, only used internally by Camera class.
Main namespace for all JeVois classes and functions.