47 #include <visp3/core/vpConfig.h>
49 #ifndef VISP_SKIP_BAYER_CONVERSION
50 #include "private/vpBayerConversion.h"
52 #include "private/vpImageConvert_impl.h"
53 #if defined(VISP_HAVE_SIMDLIB)
54 #include <Simd/SimdLib.h>
56 #include <visp3/core/vpImageConvert.h>
59 bool vpImageConvert::YCbCrLUTcomputed =
false;
60 int vpImageConvert::vpCrr[256];
61 int vpImageConvert::vpCgb[256];
62 int vpImageConvert::vpCgr[256];
63 int vpImageConvert::vpCbb[256];
110 for (
unsigned int i = 0; i < max_xy; ++i) {
111 float val = 255.f * ((src.
bitmap[i] - min) / (max - min));
115 else if (val > 255) {
119 dest.
bitmap[i] =
static_cast<unsigned char>(val);
137 for (
unsigned int i = 0; i < srcHeight; ++i) {
138 for (
unsigned int j = 0; j < srcWidth; ++j) {
139 for (
unsigned int c = 0; c < 3; ++c) {
140 float val = 255.f * ((
reinterpret_cast<const float *
>(&(src[i][j]))[c] -
reinterpret_cast<float *
>(&min)[c]) /
141 (
reinterpret_cast<float *
>(&max)[c] -
reinterpret_cast<float *
>(&min)[c]));
143 reinterpret_cast<unsigned char *
>(&(dest[i][j]))[c] = 0;
145 else if (val > 255) {
146 reinterpret_cast<unsigned char *
>(&(dest[i][j]))[c] = 255;
149 reinterpret_cast<unsigned char *
>(&(dest[i][j]))[c] =
static_cast<unsigned char>(val);
164 const unsigned int srcSize = srcHeight * srcWidth;
165 dest.
resize(srcHeight, srcWidth);
166 for (
unsigned int i = 0; i < srcSize; ++i) {
185 for (
unsigned int i = 0; i < max_xy; ++i) {
186 double val = 255. * ((src.
bitmap[i] - min) / (max - min));
190 else if (val > 255) {
194 dest.
bitmap[i] =
static_cast<unsigned char>(val);
207 const unsigned int srcSize = src.
getSize();
210 for (
unsigned int i = 0; i < srcSize; ++i) {
211 dest.
bitmap[i] =
static_cast<unsigned char>(src.
bitmap[i] >> bitshift);
223 const unsigned int srcSize = src.
getSize();
226 for (
unsigned int i = 0; i < srcSize; ++i) {
227 dest.
bitmap[i] =
static_cast<unsigned char>(src.
bitmap[i] << bitshift);
239 const unsigned int srcSize = srcHeight * srcWidth;
240 dest.
resize(srcHeight, srcWidth);
241 for (
unsigned int i = 0; i < srcSize; ++i) {
255 vp_createDepthHistogram(src_depth, dest_rgba);
266 vp_createDepthHistogram(src_depth, dest_depth);
278 vp_createDepthHistogram(src_depth, dest_rgba);
289 vp_createDepthHistogram(src_depth, dest_depth);
324 #if defined(VISP_HAVE_SIMDLIB)
332 int lineStep = flip ? -
static_cast<int>(width * 3) :
static_cast<int>(width * 3);
335 unsigned char *src = flip ? (rgb + (width * height * 3) + lineStep) : rgb;
340 for (i = 0; i < height; ++i) {
341 unsigned char *line = src;
342 for (j = 0; j < width; ++j) {
351 #if defined(VISP_HAVE_SIMDLIB)
370 #if defined(VISP_HAVE_SIMDLIB)
371 SimdBgraToBgr(rgba, size, 1, size * 4, rgb, size * 3);
373 unsigned char *pt_input = rgba;
374 unsigned char *pt_end = rgba + (4 * size);
375 unsigned char *pt_output = rgb;
377 while (pt_input != pt_end) {
378 *(++pt_output) = *(++pt_input);
379 *(++pt_output) = *(++pt_input);
380 *(++pt_output) = *(++pt_input);
419 #if defined(VISP_HAVE_SIMDLIB)
421 SimdRgbToGray(rgb, width, height, width * 3, grey, width);
427 int lineStep = flip ? -
static_cast<int>(width * 3) :
static_cast<int>(width * 3);
430 unsigned char *src = flip ? (rgb + (width * height * 3) + lineStep) : rgb;
437 for (i = 0; i < height; ++i) {
438 unsigned char *line = src;
439 for (j = 0; j < width; ++j) {
443 *grey++ =
static_cast<unsigned char>((0.2126 * r) + (0.7152 * g) + (0.0722 * b));
449 #if defined(VISP_HAVE_SIMDLIB)
476 #if defined(VISP_HAVE_SIMDLIB)
477 const int heightAsInt =
static_cast<int>(height);
480 omp_set_num_threads(
static_cast<int>(nThreads));
482 #pragma omp parallel for
484 for (
int i = 0; i < heightAsInt; ++i) {
485 SimdRgbaToGray(rgba + (i * width * 4), width, 1, width * 4, grey + (i * width), width);
511 #if defined(VISP_HAVE_SIMDLIB)
512 SimdRgbaToGray(rgba, size, 1, size * 4, grey, size);
514 unsigned char *pt_input = rgba;
515 unsigned char *pt_end = rgba + (size * 4);
516 unsigned char *pt_output = grey;
518 while (pt_input != pt_end) {
519 *pt_output =
static_cast<unsigned char>((0.2126 * (*pt_input)) + (0.7152 * (*(pt_input + 1))) + (0.0722 * (*(pt_input + 2))));
539 #if defined(VISP_HAVE_SIMDLIB)
560 #if defined(VISP_HAVE_SIMDLIB)
563 unsigned char *pt_input = grey;
564 unsigned char *pt_end = grey + size;
565 unsigned char *pt_output = rgba;
567 while (pt_input != pt_end) {
568 unsigned char p = *pt_input;
570 *(pt_output + 1) = p;
571 *(pt_output + 2) = p;
592 #if defined(VISP_HAVE_SIMDLIB)
593 SimdGrayToBgr(grey, size, 1, size, rgb, size * 3);
595 unsigned char *pt_input = grey;
596 unsigned char *pt_end = grey + size;
597 unsigned char *pt_output = rgb;
599 while (pt_input != pt_end) {
600 unsigned char p = *pt_input;
602 *(pt_output + 1) = p;
603 *(pt_output + 2) = p;
629 #if defined(VISP_HAVE_SIMDLIB)
637 int lineStep = flip ? -
static_cast<int>(width * 3) :
static_cast<int>(width * 3);
640 unsigned char *src = flip ? (bgr + (width * height * 3) + lineStep) : bgr;
642 for (
unsigned int i = 0; i < height; ++i) {
643 unsigned char *line = src;
644 for (
unsigned int j = 0; j < width; ++j) {
645 *rgba++ = *(line + 2);
646 *rgba++ = *(line + 1);
647 *rgba++ = *(line + 0);
655 #if defined(VISP_HAVE_SIMDLIB)
677 #if defined(VISP_HAVE_SIMDLIB)
679 SimdBgraToRgba(bgra, width, height, width * 4, rgba, width * 4);
685 int lineStep = flip ? -
static_cast<int>(width * 4) :
static_cast<int>(width * 4);
688 unsigned char *src = flip ? (bgra + (width * height * 4) + lineStep) : bgra;
690 for (
unsigned int i = 0; i < height; ++i) {
691 unsigned char *line = src;
692 for (
unsigned int j = 0; j < width; ++j) {
693 *rgba++ = *(line + 2);
694 *rgba++ = *(line + 1);
695 *rgba++ = *(line + 0);
696 *rgba++ = *(line + 3);
703 #if defined(VISP_HAVE_SIMDLIB)
730 #if defined(VISP_HAVE_SIMDLIB)
731 const int heightAsInt =
static_cast<int>(height);
735 omp_set_num_threads(
static_cast<int>(nThreads));
737 #pragma omp parallel for
739 for (
int i = 0; i < heightAsInt; ++i) {
740 SimdBgrToGray(bgr + (i * width * 3), width, 1, width * 3, grey + (i * width), width);
747 int lineStep = flip ? -
static_cast<int>(width * 3) :
static_cast<int>(width * 3);
750 unsigned char *src = flip ? (bgr + (width * height * 3) + lineStep) : bgr;
752 for (
unsigned int i = 0; i < height; ++i) {
753 unsigned char *line = src;
754 for (
unsigned int j = 0; j < width; ++j) {
755 *grey++ =
static_cast<unsigned int>((0.2126 * *(line + 2)) + (0.7152 * *(line + 1)) + (0.0722 * *(line + 0)));
762 #if defined(VISP_HAVE_SIMDLIB)
765 #if !defined(VISP_HAVE_SIMDLIB) && defined(_OPENMP)
792 #if defined(VISP_HAVE_SIMDLIB)
794 const int heightAsInt =
static_cast<int>(height);
797 omp_set_num_threads(
static_cast<int>(nThreads));
799 #pragma omp parallel for
801 for (
int i = 0; i < heightAsInt; ++i) {
802 SimdBgraToGray(bgra + (i * width * 4), width, 1, width * 4, grey + (i * width), width);
809 int lineStep = flip ? -
static_cast<int>(width * 4) :
static_cast<int>(width * 4);
812 unsigned char *src = flip ? (bgra + (width * height * 4) + lineStep) : bgra;
814 for (
unsigned int i = 0; i < height; ++i) {
815 unsigned char *line = src;
816 for (
unsigned int j = 0; j < width; ++j) {
817 *grey++ =
static_cast<unsigned char>((0.2126 * *(line + 2)) + (0.7152 * *(line + 1)) + (0.0722 * *(line + 0)));
824 #if defined(VISP_HAVE_SIMDLIB)
827 #if !defined(VISP_HAVE_SIMDLIB) && defined(_OPENMP)
835 void vpImageConvert::computeYCbCrLUT()
837 if (YCbCrLUTcomputed ==
false) {
842 int aux = index - 128;
843 vpImageConvert::vpCrr[index] =
static_cast<int>((364.6610 * aux) / 256);
844 vpImageConvert::vpCgb[index] =
static_cast<int>((-89.8779 * aux) / 256);
845 vpImageConvert::vpCgr[index] =
static_cast<int>((-185.8154 * aux) / 256);
846 vpImageConvert::vpCbb[index] =
static_cast<int>((460.5724 * aux) / 256);
849 YCbCrLUTcomputed =
true;
878 unsigned char *pt_ycbcr = ycbcr;
879 unsigned char *pt_rgb = rgb;
883 vpImageConvert::computeYCbCrLUT();
888 int val_r, val_g, val_b;
894 val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
895 val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
896 val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
898 *pt_rgb++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u :
static_cast<unsigned char>(val_r));
899 *pt_rgb++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u :
static_cast<unsigned char>(val_g));
900 *pt_rgb++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u :
static_cast<unsigned char>(val_b));
936 unsigned char *pt_ycbcr = ycbcr;
937 unsigned char *pt_rgba = rgba;
941 vpImageConvert::computeYCbCrLUT();
946 int val_r, val_g, val_b;
952 val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
953 val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
954 val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
956 *pt_rgba++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u :
static_cast<unsigned char>(val_r));
957 *pt_rgba++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u :
static_cast<unsigned char>(val_g));
958 *pt_rgba++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u :
static_cast<unsigned char>(val_b));
987 unsigned int i = 0, j = 0;
988 const unsigned int doubleSize = size * 2;
989 while (j < doubleSize) {
990 grey[i++] = ycbcr[j];
991 grey[i++] = ycbcr[j + 2];
1021 unsigned char *pt_ycbcr = ycrcb;
1022 unsigned char *pt_rgb = rgb;
1026 vpImageConvert::computeYCbCrLUT();
1031 int val_r, val_g, val_b;
1037 val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
1038 val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
1039 val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
1041 *pt_rgb++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u :
static_cast<unsigned char>(val_r));
1042 *pt_rgb++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u :
static_cast<unsigned char>(val_g));
1043 *pt_rgb++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u :
static_cast<unsigned char>(val_b));
1078 unsigned char *pt_ycbcr = ycrcb;
1079 unsigned char *pt_rgba = rgba;
1083 vpImageConvert::computeYCbCrLUT();
1088 int val_r, val_g, val_b;
1094 val_r = *pt_ycbcr + vpImageConvert::vpCrr[*crv];
1095 val_g = *pt_ycbcr + vpImageConvert::vpCgb[*cbv] + vpImageConvert::vpCgr[*crv];
1096 val_b = *pt_ycbcr + vpImageConvert::vpCbb[*cbv];
1098 *pt_rgba++ = (val_r < 0) ? 0u : ((val_r > 255) ? 255u :
static_cast<unsigned char>(val_r));
1099 *pt_rgba++ = (val_g < 0) ? 0u : ((val_g > 255) ? 255u :
static_cast<unsigned char>(val_g));
1100 *pt_rgba++ = (val_b < 0) ? 0u : ((val_b > 255) ? 255u :
static_cast<unsigned char>(val_b));
1153 #if defined(VISP_HAVE_SIMDLIB)
1168 unsigned char *ptrR = pR ? pR->
bitmap :
new unsigned char[src.
getSize()];
1169 unsigned char *ptrG = pG ? pG->
bitmap :
new unsigned char[src.
getSize()];
1170 unsigned char *ptrB = pB ? pB->
bitmap :
new unsigned char[src.
getSize()];
1171 unsigned char *ptrA = pa ? pa->
bitmap :
new unsigned char[src.
getSize()];
1193 unsigned int width = src.
getWidth();
1194 unsigned char *input;
1196 const unsigned int index_0 = 0;
1197 const unsigned int index_1 = 1;
1198 const unsigned int index_2 = 2;
1199 const unsigned int index_3 = 3;
1203 tabChannel[index_0] = pR;
1204 tabChannel[index_1] = pG;
1205 tabChannel[index_2] = pB;
1206 tabChannel[index_3] = pa;
1209 const unsigned int val_4 = 4;
1210 for (
unsigned int j = 0; j < val_4; ++j) {
1211 if (tabChannel[j] !=
nullptr) {
1212 if ((tabChannel[j]->getHeight() != height) || (tabChannel[j]->getWidth() != width)) {
1213 tabChannel[j]->
resize(height, width);
1215 dst =
static_cast<unsigned char *
>(tabChannel[j]->
bitmap);
1217 input = (
unsigned char *)src.
bitmap + j;
1222 for (; i < n; i += 4) {
1239 for (; i < n; ++i) {
1263 std::map<unsigned int, unsigned int> mapOfWidths, mapOfHeights;
1284 if ((mapOfWidths.size() == 1) && (mapOfHeights.size() == 1)) {
1285 unsigned int width = mapOfWidths.begin()->first;
1286 unsigned int height = mapOfHeights.begin()->first;
1288 RGBa.
resize(height, width);
1291 #if defined(VISP_HAVE_SIMDLIB)
1292 if ((R !=
nullptr) && (G !=
nullptr) && (B !=
nullptr) && (a !=
nullptr)) {
1293 SimdInterleaveBgra(R->
bitmap, width, G->
bitmap, width, B->
bitmap, width, a->
bitmap, width, width, height,
1294 reinterpret_cast<uint8_t *
>(RGBa.
bitmap), width *
sizeof(
vpRGBa));
1298 unsigned int size = width * height;
1299 for (
unsigned int i = 0; i < size; ++i) {
1316 #if defined(VISP_HAVE_SIMDLIB)
1337 int i = (
static_cast<int>(size) * 2) - 1;
1338 int j =
static_cast<int>(size) - 1;
1341 int y = grey16[i--];
1342 grey[j--] =
static_cast<unsigned char>((y + (grey16[i] * 256)) / 256);
1360 int i = (
static_cast<int>(size) * 2) - 1;
1361 int j = (
static_cast<int>(size) * 4) - 1;
1364 int y = grey16[i--];
1365 unsigned char v =
static_cast<unsigned char>((y + (grey16[i] * 256)) / 256);
1375 #ifndef VISP_SKIP_BAYER_CONVERSION
1389 unsigned int height,
unsigned int nThreads)
1391 demosaicBGGRToRGBaBilinearTpl(bggr, rgba, width, height, nThreads);
1407 unsigned int height,
unsigned int nThreads)
1409 demosaicBGGRToRGBaBilinearTpl(bggr, rgba, width, height, nThreads);
1425 unsigned int height,
unsigned int nThreads)
1427 demosaicGBRGToRGBaBilinearTpl(gbrg, rgba, width, height, nThreads);
1443 unsigned int height,
unsigned int nThreads)
1445 demosaicGBRGToRGBaBilinearTpl(gbrg, rgba, width, height, nThreads);
1461 unsigned int height,
unsigned int nThreads)
1463 demosaicGRBGToRGBaBilinearTpl(grbg, rgba, width, height, nThreads);
1479 unsigned int height,
unsigned int nThreads)
1481 demosaicGRBGToRGBaBilinearTpl(grbg, rgba, width, height, nThreads);
1497 unsigned int height,
unsigned int nThreads)
1499 demosaicRGGBToRGBaBilinearTpl(rggb, rgba, width, height, nThreads);
1515 unsigned int height,
unsigned int nThreads)
1517 demosaicRGGBToRGBaBilinearTpl(rggb, rgba, width, height, nThreads);
1535 unsigned int height,
unsigned int nThreads)
1537 demosaicBGGRToRGBaMalvarTpl(bggr, rgba, width, height, nThreads);
1553 unsigned int height,
unsigned int nThreads)
1555 demosaicBGGRToRGBaMalvarTpl(bggr, rgba, width, height, nThreads);
1571 unsigned int height,
unsigned int nThreads)
1573 demosaicGBRGToRGBaMalvarTpl(gbrg, rgba, width, height, nThreads);
1589 unsigned int height,
unsigned int nThreads)
1591 demosaicGBRGToRGBaMalvarTpl(gbrg, rgba, width, height, nThreads);
1607 unsigned int height,
unsigned int nThreads)
1609 demosaicGRBGToRGBaMalvarTpl(grbg, rgba, width, height, nThreads);
1625 unsigned int height,
unsigned int nThreads)
1627 demosaicGRBGToRGBaMalvarTpl(grbg, rgba, width, height, nThreads);
1643 unsigned int height,
unsigned int nThreads)
1645 demosaicRGGBToRGBaMalvarTpl(rggb, rgba, width, height, nThreads);
1661 unsigned int height,
unsigned int nThreads)
1663 demosaicRGGBToRGBaMalvarTpl(rggb, rgba, width, height, nThreads);
error that can be emitted by ViSP classes.
@ dimensionError
Bad dimension.
static void MONO16ToGrey(unsigned char *grey16, unsigned char *grey, unsigned int size)
static void demosaicBGGRToRGBaBilinear(const uint8_t *bggr, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void demosaicGRBGToRGBaBilinear(const uint8_t *grbg, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void demosaicGRBGToRGBaMalvar(const uint8_t *grbg, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void demosaicGBRGToRGBaMalvar(const uint8_t *gbrg, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void merge(const vpImage< unsigned char > *R, const vpImage< unsigned char > *G, const vpImage< unsigned char > *B, const vpImage< unsigned char > *a, vpImage< vpRGBa > &RGBa)
static void demosaicBGGRToRGBaMalvar(const uint8_t *bggr, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void demosaicGBRGToRGBaBilinear(const uint8_t *gbrg, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void YCbCrToGrey(unsigned char *ycbcr, unsigned char *grey, unsigned int size)
static void split(const vpImage< vpRGBa > &src, vpImage< unsigned char > *pR, vpImage< unsigned char > *pG, vpImage< unsigned char > *pB, vpImage< unsigned char > *pa=nullptr)
static void YCrCbToRGB(unsigned char *ycrcb, unsigned char *rgb, unsigned int size)
static void YCbCrToRGBa(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void createDepthHistogram(const vpImage< uint16_t > &src_depth, vpImage< vpRGBa > &dest_rgba)
static void demosaicRGGBToRGBaMalvar(const uint8_t *rggb, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void GreyToRGBa(unsigned char *grey, unsigned char *rgba, unsigned int width, unsigned int height)
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void MONO16ToRGBa(unsigned char *grey16, unsigned char *rgba, unsigned int size)
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false)
static void RGBaToGrey(unsigned char *rgba, unsigned char *grey, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void GreyToRGB(unsigned char *grey, unsigned char *rgb, unsigned int size)
static void YCrCbToRGBa(unsigned char *ycrcb, unsigned char *rgb, unsigned int size)
static void RGBToRGBa(unsigned char *rgb, unsigned char *rgba, unsigned int size)
static void YCbCrToRGB(unsigned char *ycbcr, unsigned char *rgb, unsigned int size)
static void BGRaToGrey(unsigned char *bgra, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false, unsigned int nThreads=0)
static void BGRToGrey(unsigned char *bgr, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false, unsigned int nThreads=0)
static void BGRToRGBa(unsigned char *bgr, unsigned char *rgba, unsigned int width, unsigned int height, bool flip=false)
static void demosaicRGGBToRGBaBilinear(const uint8_t *rggb, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void BGRaToRGBa(unsigned char *bgra, unsigned char *rgba, unsigned int width, unsigned int height, bool flip=false)
static void RGBaToRGB(unsigned char *rgba, unsigned char *rgb, unsigned int size)
unsigned int getWidth() const
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
unsigned int getNumberOfPixel() const
unsigned int getSize() const
Type * bitmap
points toward the bitmap
unsigned int getHeight() const
void getMinMaxValue(Type &min, Type &max, bool onlyFiniteVal=true) const
Look for the minimum and the maximum value within the bitmap.
unsigned char B
Blue component.
unsigned char R
Red component.
unsigned char G
Green component.
unsigned char A
Additionnal component.