Visual Servoing Platform  version 3.5.1 under development (2023-06-03)
testColorConversion.cpp

Test color conversion.

/****************************************************************************
*
* ViSP, open source Visual Servoing Platform software.
* Copyright (C) 2005 - 2019 by Inria. All rights reserved.
*
* This software is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* See the file LICENSE.txt at the root directory of this source
* distribution for additional information about the GNU GPL.
*
* For using ViSP with software that can not be combined with the GNU
* GPL, please contact Inria about acquiring a ViSP Professional
* Edition License.
*
* See http://visp.inria.fr for more information.
*
* This software was developed at:
* Inria Rennes - Bretagne Atlantique
* Campus Universitaire de Beaulieu
* 35042 Rennes Cedex
* France
*
* If you have questions regarding the use of this file, please contact
* Inria at visp@inria.fr
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Description:
* Test image conversion.
*
*****************************************************************************/
#include <visp3/core/vpConfig.h>
#if defined(VISP_HAVE_CATCH2)
#define CATCH_CONFIG_RUNNER
#include "common.hpp"
#include <catch.hpp>
#include <visp3/core/vpImageConvert.h>
#include <visp3/core/vpIoTools.h>
#include <visp3/io/vpImageIo.h>
static const double maxMeanPixelError = 1.5; // conversion to gray produce an error = 1.0
static const unsigned int width = 223, height = 151;
TEST_CASE("Gray to RGBa conversion", "[image_conversion]")
{
SECTION("Image 1x16 (SSE41 aligned=true)")
{
unsigned int h = 1, w = 16;
common_tools::fill(gray);
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::grayToRGBaRef(gray.bitmap, reinterpret_cast<unsigned char *>(rgba_ref.bitmap), gray.getSize());
CHECK((rgba == rgba_ref));
}
SECTION("Image 1x17 (SSE41 aligned=false)")
{
unsigned int h = 1, w = 17;
common_tools::fill(gray);
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::grayToRGBaRef(gray.bitmap, reinterpret_cast<unsigned char *>(rgba_ref.bitmap), gray.getSize());
CHECK((rgba == rgba_ref));
}
SECTION("Image 1x32 (AVX2 aligned=true)")
{
unsigned int h = 1, w = 32;
common_tools::fill(gray);
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::grayToRGBaRef(gray.bitmap, reinterpret_cast<unsigned char *>(rgba_ref.bitmap), gray.getSize());
CHECK((rgba == rgba_ref));
}
SECTION("Image 1x33 (AVX2 aligned=false)")
{
unsigned int h = 1, w = 33;
common_tools::fill(gray);
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::grayToRGBaRef(gray.bitmap, reinterpret_cast<unsigned char *>(rgba_ref.bitmap), gray.getSize());
CHECK((rgba == rgba_ref));
}
SECTION("Image 4x64 (general aligned = true")
{
unsigned int h = 4, w = 64;
common_tools::fill(gray);
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::grayToRGBaRef(gray.bitmap, reinterpret_cast<unsigned char *>(rgba_ref.bitmap), gray.getSize());
CHECK((rgba == rgba_ref));
}
SECTION("Image 5x65 (general aligned = false")
{
unsigned int h = 5, w = 65;
common_tools::fill(gray);
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::grayToRGBaRef(gray.bitmap, reinterpret_cast<unsigned char *>(rgba_ref.bitmap), gray.getSize());
CHECK((rgba == rgba_ref));
}
}
TEST_CASE("RGBa to Gray conversion", "[image_conversion]")
{
SECTION("Image 1x16 (SSE41 aligned=true)")
{
unsigned int h = 1, w = 16;
vpImage<vpRGBa> rgba(h, w);
common_tools::fill(rgba);
vpImage<unsigned char> gray_ref(h, w);
common_tools::RGBaToGrayRef(reinterpret_cast<unsigned char *>(rgba.bitmap), gray_ref.bitmap, rgba.getSize());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "RGBa to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 1x17 (SSE41 aligned=false)")
{
unsigned int h = 1, w = 17;
vpImage<vpRGBa> rgba(h, w);
common_tools::fill(rgba);
vpImage<unsigned char> gray_ref(h, w);
common_tools::RGBaToGrayRef(reinterpret_cast<unsigned char *>(rgba.bitmap), gray_ref.bitmap, rgba.getSize());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "RGBa to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 1x32 (AVX2 aligned=true)")
{
unsigned int h = 1, w = 32;
vpImage<vpRGBa> rgba(h, w);
common_tools::fill(rgba);
vpImage<unsigned char> gray_ref(h, w);
common_tools::RGBaToGrayRef(reinterpret_cast<unsigned char *>(rgba.bitmap), gray_ref.bitmap, rgba.getSize());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "RGBa to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 1x33 (AVX2 aligned=false)")
{
unsigned int h = 1, w = 33;
vpImage<vpRGBa> rgba(h, w);
common_tools::fill(rgba);
vpImage<unsigned char> gray_ref(h, w);
common_tools::RGBaToGrayRef(reinterpret_cast<unsigned char *>(rgba.bitmap), gray_ref.bitmap, rgba.getSize());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "RGBa to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 4x64 (general aligned = true")
{
unsigned int h = 4, w = 64;
vpImage<vpRGBa> rgba(h, w);
common_tools::fill(rgba);
vpImage<unsigned char> gray_ref(h, w);
common_tools::RGBaToGrayRef(reinterpret_cast<unsigned char *>(rgba.bitmap), gray_ref.bitmap, rgba.getSize());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "RGBa to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 5x65 (general aligned = false")
{
unsigned int h = 5, w = 65;
vpImage<vpRGBa> rgba(h, w);
common_tools::fill(rgba);
vpImage<unsigned char> gray_ref(h, w);
common_tools::RGBaToGrayRef(reinterpret_cast<unsigned char *>(rgba.bitmap), gray_ref.bitmap, rgba.getSize());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "RGBa to Gray conversion, mean error: " << error << std::endl;
}
}
TEST_CASE("RGB to Gray conversion", "[image_conversion]")
{
SECTION("Image 1x16 (SSE41 aligned=true)")
{
unsigned int h = 1, w = 16;
std::vector<unsigned char> rgb(h * w * 3);
common_tools::fill(rgb);
vpImage<unsigned char> gray_ref(h, w);
common_tools::RGBToGrayRef(rgb.data(), gray_ref.bitmap, gray_ref.getWidth(), gray_ref.getHeight(), false);
vpImageConvert::RGBToGrey(rgb.data(), gray.bitmap, w, h, false);
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "RGB to Gray conversion 1, mean error: " << error << std::endl;
vpImageConvert::RGBToGrey(rgb.data(), gray2.bitmap, w * h);
CHECK(common_tools::almostEqual(gray_ref, gray2, maxMeanPixelError, error));
std::cout << "RGB to Gray conversion 2, mean error: " << error << std::endl;
}
SECTION("Image 1x17 (SSE41 aligned=false)")
{
unsigned int h = 1, w = 17;
std::vector<unsigned char> rgb(h * w * 3);
common_tools::fill(rgb);
vpImage<unsigned char> gray_ref(h, w);
common_tools::RGBToGrayRef(rgb.data(), gray_ref.bitmap, gray_ref.getWidth(), gray_ref.getHeight(), false);
vpImageConvert::RGBToGrey(rgb.data(), gray.bitmap, w, h, false);
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "RGB to Gray conversion 1, mean error: " << error << std::endl;
vpImageConvert::RGBToGrey(rgb.data(), gray2.bitmap, w * h);
CHECK(common_tools::almostEqual(gray_ref, gray2, maxMeanPixelError, error));
std::cout << "RGB to Gray conversion 2, mean error: " << error << std::endl;
}
SECTION("Image 1x32 (AVX2 aligned=true)")
{
unsigned int h = 1, w = 32;
std::vector<unsigned char> rgb(h * w * 3);
common_tools::fill(rgb);
vpImage<unsigned char> gray_ref(h, w);
common_tools::RGBToGrayRef(rgb.data(), gray_ref.bitmap, gray_ref.getWidth(), gray_ref.getHeight(), false);
vpImageConvert::RGBToGrey(rgb.data(), gray.bitmap, w, h, false);
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "RGB to Gray conversion 1, mean error: " << error << std::endl;
vpImageConvert::RGBToGrey(rgb.data(), gray2.bitmap, w * h);
CHECK(common_tools::almostEqual(gray_ref, gray2, maxMeanPixelError, error));
std::cout << "RGB to Gray conversion 2, mean error: " << error << std::endl;
}
SECTION("Image 1x33 (AVX2 aligned=false)")
{
unsigned int h = 1, w = 33;
std::vector<unsigned char> rgb(h * w * 3);
common_tools::fill(rgb);
vpImage<unsigned char> gray_ref(h, w);
common_tools::RGBToGrayRef(rgb.data(), gray_ref.bitmap, gray_ref.getWidth(), gray_ref.getHeight(), false);
vpImageConvert::RGBToGrey(rgb.data(), gray.bitmap, w, h, false);
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "RGB to Gray conversion 1, mean error: " << error << std::endl;
vpImageConvert::RGBToGrey(rgb.data(), gray2.bitmap, w * h);
CHECK(common_tools::almostEqual(gray_ref, gray2, maxMeanPixelError, error));
std::cout << "RGB to Gray conversion 2, mean error: " << error << std::endl;
}
SECTION("Image 4x64 (general aligned = true")
{
unsigned int h = 4, w = 64;
std::vector<unsigned char> rgb(h * w * 3);
common_tools::fill(rgb);
vpImage<unsigned char> gray_ref(h, w);
common_tools::RGBToGrayRef(rgb.data(), gray_ref.bitmap, gray_ref.getWidth(), gray_ref.getHeight(), false);
vpImageConvert::RGBToGrey(rgb.data(), gray.bitmap, w, h, false);
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "RGB to Gray conversion 1, mean error: " << error << std::endl;
vpImageConvert::RGBToGrey(rgb.data(), gray2.bitmap, w * h);
CHECK(common_tools::almostEqual(gray_ref, gray2, maxMeanPixelError, error));
std::cout << "RGB to Gray conversion 2, mean error: " << error << std::endl;
}
SECTION("Image 5x65 (general aligned = false")
{
unsigned int h = 5, w = 65;
std::vector<unsigned char> rgb(h * w * 3);
common_tools::fill(rgb);
vpImage<unsigned char> gray_ref(h, w);
common_tools::RGBToGrayRef(rgb.data(), gray_ref.bitmap, gray_ref.getWidth(), gray_ref.getHeight(), false);
vpImageConvert::RGBToGrey(rgb.data(), gray.bitmap, w, h, false);
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "RGB to Gray conversion 1, mean error: " << error << std::endl;
vpImageConvert::RGBToGrey(rgb.data(), gray2.bitmap, w * h);
CHECK(common_tools::almostEqual(gray_ref, gray2, maxMeanPixelError, error));
std::cout << "RGB to Gray conversion 2, mean error: " << error << std::endl;
}
}
TEST_CASE("RGB <==> RGBa conversion", "[image_conversion]")
{
SECTION("Image 1x16 (SSE41 aligned=true)")
{
unsigned int h = 1, w = 16;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
std::vector<unsigned char> rgb(h * w * 3);
vpImageConvert::RGBaToRGB(reinterpret_cast<unsigned char *>(rgba_ref.bitmap), rgb.data(), rgba_ref.getSize());
vpImage<vpRGBa> rgba(h, w);
vpImageConvert::RGBToRGBa(rgb.data(), reinterpret_cast<unsigned char *>(rgba.bitmap), rgba_ref.getSize());
CHECK((rgba == rgba_ref));
}
SECTION("Image 1x17 (SSE41 aligned=false)")
{
unsigned int h = 1, w = 17;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
std::vector<unsigned char> rgb(h * w * 3);
vpImageConvert::RGBaToRGB(reinterpret_cast<unsigned char *>(rgba_ref.bitmap), rgb.data(), rgba_ref.getSize());
vpImage<vpRGBa> rgba(h, w);
vpImageConvert::RGBToRGBa(rgb.data(), reinterpret_cast<unsigned char *>(rgba.bitmap), rgba_ref.getSize());
CHECK((rgba == rgba_ref));
}
SECTION("Image 1x32 (AVX2 aligned=true)")
{
unsigned int h = 1, w = 32;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
std::vector<unsigned char> rgb(h * w * 3);
vpImageConvert::RGBaToRGB(reinterpret_cast<unsigned char *>(rgba_ref.bitmap), rgb.data(), rgba_ref.getSize());
vpImage<vpRGBa> rgba(h, w);
vpImageConvert::RGBToRGBa(rgb.data(), reinterpret_cast<unsigned char *>(rgba.bitmap), rgba_ref.getSize());
CHECK((rgba == rgba_ref));
}
SECTION("Image 1x33 (AVX2 aligned=false)")
{
unsigned int h = 1, w = 33;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
std::vector<unsigned char> rgb(h * w * 3);
vpImageConvert::RGBaToRGB(reinterpret_cast<unsigned char *>(rgba_ref.bitmap), rgb.data(), rgba_ref.getSize());
vpImage<vpRGBa> rgba(h, w);
vpImageConvert::RGBToRGBa(rgb.data(), reinterpret_cast<unsigned char *>(rgba.bitmap), rgba_ref.getSize());
CHECK((rgba == rgba_ref));
}
SECTION("Image 4x64 (general aligned = true")
{
unsigned int h = 4, w = 64;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
std::vector<unsigned char> rgb(h * w * 3);
vpImageConvert::RGBaToRGB(reinterpret_cast<unsigned char *>(rgba_ref.bitmap), rgb.data(), rgba_ref.getSize());
vpImage<vpRGBa> rgba(h, w);
vpImageConvert::RGBToRGBa(rgb.data(), reinterpret_cast<unsigned char *>(rgba.bitmap), rgba_ref.getSize());
CHECK((rgba == rgba_ref));
}
SECTION("Image 5x65 (general aligned = false")
{
unsigned int h = 5, w = 65;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
std::vector<unsigned char> rgb(h * w * 3);
vpImageConvert::RGBaToRGB(reinterpret_cast<unsigned char *>(rgba_ref.bitmap), rgb.data(), rgba_ref.getSize());
vpImage<vpRGBa> rgba(h, w);
vpImageConvert::RGBToRGBa(rgb.data(), reinterpret_cast<unsigned char *>(rgba.bitmap), rgba_ref.getSize());
CHECK((rgba == rgba_ref));
}
}
TEST_CASE("BGR to Gray conversion", "[image_conversion]")
{
SECTION("Image 1x16 (SSE41 aligned=true)")
{
unsigned int h = 1, w = 16;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
vpImageConvert::convert(rgba_ref, gray_ref);
std::vector<unsigned char> bgr;
common_tools::RGBaToBGR(rgba_ref, bgr);
vpImage<unsigned char> gray(gray_ref.getHeight(), gray_ref.getWidth());
vpImageConvert::BGRToGrey(bgr.data(), gray.bitmap, gray.getWidth(), gray.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "BGR to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 1x17 (SSE41 aligned=false)")
{
unsigned int h = 1, w = 17;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
vpImageConvert::convert(rgba_ref, gray_ref);
std::vector<unsigned char> bgr;
common_tools::RGBaToBGR(rgba_ref, bgr);
vpImage<unsigned char> gray(gray_ref.getHeight(), gray_ref.getWidth());
vpImageConvert::BGRToGrey(bgr.data(), gray.bitmap, gray.getWidth(), gray.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "BGR to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 1x32 (AVX2 aligned=true)")
{
unsigned int h = 1, w = 32;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
vpImageConvert::convert(rgba_ref, gray_ref);
std::vector<unsigned char> bgr;
common_tools::RGBaToBGR(rgba_ref, bgr);
vpImage<unsigned char> gray(gray_ref.getHeight(), gray_ref.getWidth());
vpImageConvert::BGRToGrey(bgr.data(), gray.bitmap, gray.getWidth(), gray.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "BGR to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 1x33 (AVX2 aligned=false)")
{
unsigned int h = 1, w = 33;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
vpImageConvert::convert(rgba_ref, gray_ref);
std::vector<unsigned char> bgr;
common_tools::RGBaToBGR(rgba_ref, bgr);
vpImage<unsigned char> gray(gray_ref.getHeight(), gray_ref.getWidth());
vpImageConvert::BGRToGrey(bgr.data(), gray.bitmap, gray.getWidth(), gray.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "BGR to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 4x64 (general aligned = true")
{
unsigned int h = 4, w = 64;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
vpImageConvert::convert(rgba_ref, gray_ref);
std::vector<unsigned char> bgr;
common_tools::RGBaToBGR(rgba_ref, bgr);
vpImage<unsigned char> gray(gray_ref.getHeight(), gray_ref.getWidth());
vpImageConvert::BGRToGrey(bgr.data(), gray.bitmap, gray.getWidth(), gray.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "BGR to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 5x65 (general aligned = false")
{
unsigned int h = 5, w = 65;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
vpImageConvert::convert(rgba_ref, gray_ref);
std::vector<unsigned char> bgr;
common_tools::RGBaToBGR(rgba_ref, bgr);
vpImage<unsigned char> gray(gray_ref.getHeight(), gray_ref.getWidth());
vpImageConvert::BGRToGrey(bgr.data(), gray.bitmap, gray.getWidth(), gray.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "BGR to Gray conversion, mean error: " << error << std::endl;
}
}
TEST_CASE("BGRa to Gray conversion", "[image_conversion]")
{
SECTION("Image 1x16 (SSE41 aligned=true)")
{
unsigned int h = 1, w = 16;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
vpImageConvert::convert(rgba_ref, gray_ref);
std::vector<unsigned char> bgra;
common_tools::RGBaToBGRa(rgba_ref, bgra);
vpImage<unsigned char> gray(gray_ref.getHeight(), gray_ref.getWidth());
vpImageConvert::BGRaToGrey(bgra.data(), gray.bitmap, gray.getWidth(), gray.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "BGRa to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 1x17 (SSE41 aligned=false)")
{
unsigned int h = 1, w = 17;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
vpImageConvert::convert(rgba_ref, gray_ref);
std::vector<unsigned char> bgra;
common_tools::RGBaToBGRa(rgba_ref, bgra);
vpImage<unsigned char> gray(gray_ref.getHeight(), gray_ref.getWidth());
vpImageConvert::BGRaToGrey(bgra.data(), gray.bitmap, gray.getWidth(), gray.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "BGRa to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 1x32 (AVX2 aligned=true)")
{
unsigned int h = 1, w = 32;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
vpImageConvert::convert(rgba_ref, gray_ref);
std::vector<unsigned char> bgra;
common_tools::RGBaToBGRa(rgba_ref, bgra);
vpImage<unsigned char> gray(gray_ref.getHeight(), gray_ref.getWidth());
vpImageConvert::BGRaToGrey(bgra.data(), gray.bitmap, gray.getWidth(), gray.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "BGRa to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 1x33 (AVX2 aligned=false)")
{
unsigned int h = 1, w = 33;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
vpImageConvert::convert(rgba_ref, gray_ref);
std::vector<unsigned char> bgra;
common_tools::RGBaToBGRa(rgba_ref, bgra);
vpImage<unsigned char> gray(gray_ref.getHeight(), gray_ref.getWidth());
vpImageConvert::BGRaToGrey(bgra.data(), gray.bitmap, gray.getWidth(), gray.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "BGRa to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 4x64 (general aligned = true")
{
unsigned int h = 4, w = 64;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
vpImageConvert::convert(rgba_ref, gray_ref);
std::vector<unsigned char> bgra;
common_tools::RGBaToBGRa(rgba_ref, bgra);
vpImage<unsigned char> gray(gray_ref.getHeight(), gray_ref.getWidth());
vpImageConvert::BGRaToGrey(bgra.data(), gray.bitmap, gray.getWidth(), gray.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "BGRa to Gray conversion, mean error: " << error << std::endl;
}
SECTION("Image 5x65 (general aligned = false")
{
unsigned int h = 5, w = 65;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
vpImageConvert::convert(rgba_ref, gray_ref);
std::vector<unsigned char> bgra;
common_tools::RGBaToBGRa(rgba_ref, bgra);
vpImage<unsigned char> gray(gray_ref.getHeight(), gray_ref.getWidth());
vpImageConvert::BGRaToGrey(bgra.data(), gray.bitmap, gray.getWidth(), gray.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "BGRa to Gray conversion, mean error: " << error << std::endl;
}
}
TEST_CASE("BGRa to RGBa conversion", "[image_conversion]")
{
SECTION("Image 1x16 (SSE41 aligned=true)")
{
unsigned int h = 1, w = 16;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
std::vector<unsigned char> bgra_ref;
common_tools::RGBaToBGRa(rgba_ref, bgra_ref);
vpImage<vpRGBa> rgba(rgba_ref.getHeight(), rgba_ref.getWidth());
vpImageConvert::BGRaToRGBa(bgra_ref.data(), reinterpret_cast<unsigned char *>(rgba.bitmap), rgba.getWidth(),
rgba.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(rgba_ref, rgba, maxMeanPixelError, error));
std::cout << "BGRa to RGBa conversion, mean error: " << error << std::endl;
}
SECTION("Image 1x17 (SSE41 aligned=false)")
{
unsigned int h = 1, w = 17;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
std::vector<unsigned char> bgra_ref;
common_tools::RGBaToBGRa(rgba_ref, bgra_ref);
vpImage<vpRGBa> rgba(rgba_ref.getHeight(), rgba_ref.getWidth());
vpImageConvert::BGRaToRGBa(bgra_ref.data(), reinterpret_cast<unsigned char *>(rgba.bitmap), rgba.getWidth(),
rgba.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(rgba_ref, rgba, maxMeanPixelError, error));
std::cout << "BGRa to RGBa conversion, mean error: " << error << std::endl;
}
SECTION("Image 1x32 (AVX2 aligned=true)")
{
unsigned int h = 1, w = 32;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
std::vector<unsigned char> bgra_ref;
common_tools::RGBaToBGRa(rgba_ref, bgra_ref);
vpImage<vpRGBa> rgba(rgba_ref.getHeight(), rgba_ref.getWidth());
vpImageConvert::BGRaToRGBa(bgra_ref.data(), reinterpret_cast<unsigned char *>(rgba.bitmap), rgba.getWidth(),
rgba.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(rgba_ref, rgba, maxMeanPixelError, error));
std::cout << "BGRa to RGBa conversion, mean error: " << error << std::endl;
}
SECTION("Image 1x33 (AVX2 aligned=false)")
{
unsigned int h = 1, w = 33;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
std::vector<unsigned char> bgra_ref;
common_tools::RGBaToBGRa(rgba_ref, bgra_ref);
vpImage<vpRGBa> rgba(rgba_ref.getHeight(), rgba_ref.getWidth());
vpImageConvert::BGRaToRGBa(bgra_ref.data(), reinterpret_cast<unsigned char *>(rgba.bitmap), rgba.getWidth(),
rgba.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(rgba_ref, rgba, maxMeanPixelError, error));
std::cout << "BGRa to RGBa conversion, mean error: " << error << std::endl;
}
SECTION("Image 4x64 (general aligned = true")
{
unsigned int h = 4, w = 64;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
std::vector<unsigned char> bgra_ref;
common_tools::RGBaToBGRa(rgba_ref, bgra_ref);
vpImage<vpRGBa> rgba(rgba_ref.getHeight(), rgba_ref.getWidth());
vpImageConvert::BGRaToRGBa(bgra_ref.data(), reinterpret_cast<unsigned char *>(rgba.bitmap), rgba.getWidth(),
rgba.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(rgba_ref, rgba, maxMeanPixelError, error));
std::cout << "BGRa to RGBa conversion, mean error: " << error << std::endl;
}
SECTION("Image 5x65 (general aligned = false")
{
unsigned int h = 5, w = 65;
vpImage<vpRGBa> rgba_ref(h, w);
common_tools::fill(rgba_ref);
std::vector<unsigned char> bgra_ref;
common_tools::RGBaToBGRa(rgba_ref, bgra_ref);
vpImage<vpRGBa> rgba(rgba_ref.getHeight(), rgba_ref.getWidth());
vpImageConvert::BGRaToRGBa(bgra_ref.data(), reinterpret_cast<unsigned char *>(rgba.bitmap), rgba.getWidth(),
rgba.getHeight());
double error = 0;
CHECK(common_tools::almostEqual(rgba_ref, rgba, maxMeanPixelError, error));
std::cout << "BGRa to RGBa conversion, mean error: " << error << std::endl;
}
}
TEST_CASE("Split <==> Merge conversion", "[image_conversion]")
{
vpImage<vpRGBa> rgba_ref(height, width);
common_tools::fill(rgba_ref);
vpImageConvert::split(rgba_ref, &R, &G, &B, &A);
vpImageConvert::merge(&R, &G, &B, &A, rgba);
CHECK((rgba == rgba_ref));
}
#if VISP_HAVE_OPENCV_VERSION >= 0x020100
TEST_CASE("OpenCV Mat <==> vpImage conversion", "[image_conversion]")
{
SECTION("CV_8UC3 to vpRGBa")
{
cv::Mat img(height, width, CV_8UC3);
common_tools::fill(img);
vpImage<vpRGBa> rgba_ref(height, width);
common_tools::BGRToRGBaRef(img.data, reinterpret_cast<unsigned char *>(rgba_ref.bitmap), img.cols, img.rows, false);
CHECK((rgba_ref == rgba));
}
SECTION("CV_8UC1 to vpRGBa")
{
cv::Mat img(height, width, CV_8UC1);
common_tools::fill(img);
vpImage<vpRGBa> rgba_ref(height, width);
common_tools::grayToRGBaRef(img.data, reinterpret_cast<unsigned char *>(rgba_ref.bitmap), height * width);
CHECK((rgba_ref == rgba));
}
SECTION("CV_8UC3 to unsigned char")
{
cv::Mat img(height, width, CV_8UC3);
common_tools::fill(img);
vpImage<unsigned char> gray_ref(height, width);
common_tools::BGRToGrayRef(img.data, gray_ref.bitmap, img.cols, img.rows, false);
double error = 0;
CHECK(common_tools::almostEqual(gray_ref, gray, maxMeanPixelError, error));
std::cout << "BGR to Gray conversion, mean error: " << error << std::endl;
}
SECTION("CV_8UC1 to unsigned char")
{
cv::Mat img(height, width, CV_8UC1);
common_tools::fill(img);
REQUIRE(gray.getHeight() == height);
REQUIRE(gray.getWidth() == width);
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
REQUIRE(img.at<uchar>(i, j) == gray[i][j]);
}
}
}
SECTION("CV_16UC1 to uint16_t")
{
// Test when data in cv::Mat is continuous
unsigned int w = 3, h = 3;
cv::Mat img = (cv::Mat_<uint16_t>(h, w) << 65, 650, 6500, 65000, 60000, 6000, 600, 60, 6);
REQUIRE(gray16.getHeight() == h);
REQUIRE(gray16.getWidth() == w);
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
REQUIRE(img.at<uint16_t>(i, j) == gray16[i][j]);
}
}
// Test when data in cv::Mat is discontinuous
cv::Mat img_col1 = img.col(1);
vpImage<uint16_t> gray16_col1;
vpImageConvert::convert(img_col1, gray16_col1);
REQUIRE(gray16_col1.getHeight() == h);
REQUIRE(gray16_col1.getWidth() == 1);
for (int i = 0; i < img_col1.rows; i++) {
for (int j = 0; j < img_col1.cols; j++) {
REQUIRE(img_col1.at<uint16_t>(i, j) == gray16_col1[i][j]);
}
}
}
}
#endif
void col2im(const std::vector<uint8_t> &buffer, vpImage<uint8_t> &I_Bayer_8U)
{
for (unsigned int i = 0; i < I_Bayer_8U.getHeight(); i++) {
for (unsigned int j = 0; j < I_Bayer_8U.getWidth(); j++) {
I_Bayer_8U[i][j] = buffer[j * I_Bayer_8U.getHeight() + i];
}
}
}
void col2im(const std::vector<uint16_t> &buffer, vpImage<uint16_t> &I_Bayer_16U)
{
for (unsigned int i = 0; i < I_Bayer_16U.getHeight(); i++) {
for (unsigned int j = 0; j < I_Bayer_16U.getWidth(); j++) {
I_Bayer_16U[i][j] = buffer[j * I_Bayer_16U.getHeight() + i];
}
}
}
void convertTo(const vpImage<uint16_t> &I_RGBA_16U, vpImage<vpRGBa> &I_RGBA_8U, int divisor = 1 << (12 - 8))
{
for (unsigned int i = 0; i < I_RGBA_8U.getHeight(); i++) {
for (unsigned int j = 0; j < I_RGBA_8U.getWidth(); j++) {
I_RGBA_8U[i][j] = vpRGBa(
vpMath::saturate<unsigned char>(I_RGBA_16U[0][(i * I_RGBA_8U.getWidth() + j) * 4 + 0] / (float)divisor),
vpMath::saturate<unsigned char>(I_RGBA_16U[0][(i * I_RGBA_8U.getWidth() + j) * 4 + 1] / (float)divisor),
vpMath::saturate<unsigned char>(I_RGBA_16U[0][(i * I_RGBA_8U.getWidth() + j) * 4 + 2] / (float)divisor));
}
}
}
double computePSNR(const vpImage<vpRGBa> &I_RGBA_8U, const vpImage<vpRGBa> &I_RGBA_8U_ref)
{
double mse = 0;
for (unsigned int i = 0; i < I_RGBA_8U.getHeight(); i++) {
for (unsigned int j = 0; j < I_RGBA_8U.getWidth(); j++) {
vpColVector err = I_RGBA_8U[i][j] - I_RGBA_8U_ref[i][j];
mse += vpMath::sqr(err[0]) + vpMath::sqr(err[1]) + vpMath::sqr(err[2]);
}
}
mse /= I_RGBA_8U.getHeight() * I_RGBA_8U.getWidth() * 3;
return 10 * std::log10(255 * 255 / mse);
}
void readBinaryFile(const std::string &filename, std::vector<uint16_t> &buffer)
{
std::FILE *f = std::fopen(filename.c_str(), "rb");
size_t sread = std::fread(&buffer[0], sizeof buffer[0], buffer.size(), f);
REQUIRE(sread == buffer.size());
#ifdef VISP_BIG_ENDIAN
std::vector<uint16_t> tmp = buffer;
for (size_t i = 0; i < tmp.size(); i++) {
buffer[i] = vpEndian::swap16bits(tmp[i]);
}
#endif
std::fclose(f);
}
#if (VISP_HAVE_DATASET_VERSION >= 0x040500)
TEST_CASE("Bayer conversion", "[image_conversion]")
{
// Load original Klimt image
vpImage<vpRGBa> I_RGBA_8U_ref;
vpImage<vpRGBa> I_RGBA_8U(I_RGBA_8U_ref.getHeight(), I_RGBA_8U_ref.getWidth());
int height = I_RGBA_8U_ref.getHeight(), width = I_RGBA_8U_ref.getWidth();
const double min_PSNR_bilinear = 21, min_PSNR_Malvar = 24;
SECTION("16-bit")
{
std::vector<uint16_t> buffer(height * width);
vpImage<uint16_t> I_Bayer_16U(height, width);
vpImage<uint16_t> I_RGBA_16U(1, I_Bayer_16U.getHeight() * I_Bayer_16U.getWidth() * 4);
SECTION("BGGR")
{
const std::string filename =
vpIoTools::createFilePath(vpIoTools::getViSPImagesDataPath(), "Bayer/Klimt_Bayer_560x558_BGGR_12bits.raw");
readBinaryFile(filename, buffer);
col2im(buffer, I_Bayer_16U);
SECTION("Bilinear")
{
vpImageConvert::demosaicBGGRToRGBaBilinear(I_Bayer_16U.bitmap, I_RGBA_16U.bitmap, I_Bayer_16U.getWidth(),
I_Bayer_16U.getHeight());
convertTo(I_RGBA_16U, I_RGBA_8U);
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "16-bit - BGGR - Bilinear - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_bilinear);
}
SECTION("Malvar")
{
vpImageConvert::demosaicBGGRToRGBaMalvar(I_Bayer_16U.bitmap, I_RGBA_16U.bitmap, I_Bayer_16U.getWidth(),
I_Bayer_16U.getHeight());
convertTo(I_RGBA_16U, I_RGBA_8U);
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "16-bit - BGGR - Malvar - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_Malvar);
}
}
SECTION("GBRG")
{
const std::string filename =
vpIoTools::createFilePath(vpIoTools::getViSPImagesDataPath(), "Bayer/Klimt_Bayer_560x558_GBRG_12bits.raw");
readBinaryFile(filename, buffer);
col2im(buffer, I_Bayer_16U);
SECTION("Bilinear")
{
vpImageConvert::demosaicGBRGToRGBaBilinear(I_Bayer_16U.bitmap, I_RGBA_16U.bitmap, I_Bayer_16U.getWidth(),
I_Bayer_16U.getHeight());
convertTo(I_RGBA_16U, I_RGBA_8U);
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "16-bit - GBRG - Bilinear - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_bilinear);
}
SECTION("Malvar")
{
vpImageConvert::demosaicGBRGToRGBaMalvar(I_Bayer_16U.bitmap, I_RGBA_16U.bitmap, I_Bayer_16U.getWidth(),
I_Bayer_16U.getHeight());
convertTo(I_RGBA_16U, I_RGBA_8U);
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "16-bit - GBRG - Malvar - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_Malvar);
}
}
SECTION("GRBG")
{
const std::string filename =
vpIoTools::createFilePath(vpIoTools::getViSPImagesDataPath(), "Bayer/Klimt_Bayer_560x558_GRBG_12bits.raw");
readBinaryFile(filename, buffer);
col2im(buffer, I_Bayer_16U);
SECTION("Bilinear")
{
vpImageConvert::demosaicGRBGToRGBaBilinear(I_Bayer_16U.bitmap, I_RGBA_16U.bitmap, I_Bayer_16U.getWidth(),
I_Bayer_16U.getHeight());
convertTo(I_RGBA_16U, I_RGBA_8U);
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "16-bit - GRBG - Bilinear - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_bilinear);
}
SECTION("Malvar")
{
vpImageConvert::demosaicGRBGToRGBaMalvar(I_Bayer_16U.bitmap, I_RGBA_16U.bitmap, I_Bayer_16U.getWidth(),
I_Bayer_16U.getHeight());
convertTo(I_RGBA_16U, I_RGBA_8U);
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "16-bit - GRBG - Malvar - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_Malvar);
}
}
SECTION("RGGB")
{
const std::string filename =
vpIoTools::createFilePath(vpIoTools::getViSPImagesDataPath(), "Bayer/Klimt_Bayer_560x558_RGGB_12bits.raw");
readBinaryFile(filename, buffer);
col2im(buffer, I_Bayer_16U);
SECTION("Bilinear")
{
vpImageConvert::demosaicRGGBToRGBaBilinear(I_Bayer_16U.bitmap, I_RGBA_16U.bitmap, I_Bayer_16U.getWidth(),
I_Bayer_16U.getHeight());
convertTo(I_RGBA_16U, I_RGBA_8U);
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "16-bit - RGGB - Bilinear - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_bilinear);
}
SECTION("Malvar")
{
vpImageConvert::demosaicRGGBToRGBaMalvar(I_Bayer_16U.bitmap, I_RGBA_16U.bitmap, I_Bayer_16U.getWidth(),
I_Bayer_16U.getHeight());
convertTo(I_RGBA_16U, I_RGBA_8U);
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "16-bit - RGGB - Malvar - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_Malvar);
}
}
}
SECTION("8-bit")
{
std::vector<uint8_t> buffer(height * width);
vpImage<uint8_t> I_Bayer_8U(height, width);
vpImage<vpRGBa> I_RGBA_8U(I_Bayer_8U.getHeight(), I_Bayer_8U.getWidth());
SECTION("BGGR")
{
const std::string filename =
vpIoTools::createFilePath(vpIoTools::getViSPImagesDataPath(), "Bayer/Klimt_Bayer_560x558_BGGR_08bits.raw");
std::FILE *f = std::fopen(filename.c_str(), "rb");
size_t sread = std::fread(&buffer[0], sizeof buffer[0], buffer.size(), f);
REQUIRE(sread == buffer.size());
col2im(buffer, I_Bayer_8U);
SECTION("Bilinear")
{
vpImageConvert::demosaicBGGRToRGBaBilinear(I_Bayer_8U.bitmap, reinterpret_cast<uint8_t *>(I_RGBA_8U.bitmap),
I_Bayer_8U.getWidth(), I_Bayer_8U.getHeight());
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "8-bit - BGGR - Bilinear - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_bilinear);
}
SECTION("Malvar")
{
vpImageConvert::demosaicBGGRToRGBaMalvar(I_Bayer_8U.bitmap, reinterpret_cast<uint8_t *>(I_RGBA_8U.bitmap),
I_Bayer_8U.getWidth(), I_Bayer_8U.getHeight());
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "8-bit - BGGR - Malvar - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_Malvar);
}
std::fclose(f);
}
SECTION("GBRG")
{
const std::string filename =
vpIoTools::createFilePath(vpIoTools::getViSPImagesDataPath(), "Bayer/Klimt_Bayer_560x558_GBRG_08bits.raw");
std::FILE *f = std::fopen(filename.c_str(), "rb");
size_t sread = std::fread(&buffer[0], sizeof buffer[0], buffer.size(), f);
REQUIRE(sread == buffer.size());
col2im(buffer, I_Bayer_8U);
SECTION("Bilinear")
{
vpImageConvert::demosaicGBRGToRGBaBilinear(I_Bayer_8U.bitmap, reinterpret_cast<uint8_t *>(I_RGBA_8U.bitmap),
I_Bayer_8U.getWidth(), I_Bayer_8U.getHeight());
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "8-bit - GBRG - Bilinear - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_bilinear);
}
SECTION("Malvar")
{
vpImageConvert::demosaicGBRGToRGBaMalvar(I_Bayer_8U.bitmap, reinterpret_cast<uint8_t *>(I_RGBA_8U.bitmap),
I_Bayer_8U.getWidth(), I_Bayer_8U.getHeight());
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "8-bit - GBRG - Malvar - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_Malvar);
}
std::fclose(f);
}
SECTION("GRBG")
{
const std::string filename =
vpIoTools::createFilePath(vpIoTools::getViSPImagesDataPath(), "Bayer/Klimt_Bayer_560x558_GRBG_08bits.raw");
std::FILE *f = std::fopen(filename.c_str(), "rb");
size_t sread = std::fread(&buffer[0], sizeof buffer[0], buffer.size(), f);
REQUIRE(sread == buffer.size());
col2im(buffer, I_Bayer_8U);
SECTION("Bilinear")
{
vpImageConvert::demosaicGRBGToRGBaBilinear(I_Bayer_8U.bitmap, reinterpret_cast<uint8_t *>(I_RGBA_8U.bitmap),
I_Bayer_8U.getWidth(), I_Bayer_8U.getHeight());
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "8-bit - GRBG - Bilinear - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_bilinear);
}
SECTION("Malvar")
{
vpImageConvert::demosaicGRBGToRGBaMalvar(I_Bayer_8U.bitmap, reinterpret_cast<uint8_t *>(I_RGBA_8U.bitmap),
I_Bayer_8U.getWidth(), I_Bayer_8U.getHeight());
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "8-bit - GRBG - Malvar - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_Malvar);
}
std::fclose(f);
}
SECTION("RGGB")
{
const std::string filename =
vpIoTools::createFilePath(vpIoTools::getViSPImagesDataPath(), "Bayer/Klimt_Bayer_560x558_RGGB_08bits.raw");
std::FILE *f = std::fopen(filename.c_str(), "rb");
size_t sread = std::fread(&buffer[0], sizeof buffer[0], buffer.size(), f);
REQUIRE(sread == buffer.size());
col2im(buffer, I_Bayer_8U);
SECTION("Bilinear")
{
vpImageConvert::demosaicRGGBToRGBaBilinear(I_Bayer_8U.bitmap, reinterpret_cast<uint8_t *>(I_RGBA_8U.bitmap),
I_Bayer_8U.getWidth(), I_Bayer_8U.getHeight());
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "8-bit - RGGB - Bilinear - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_bilinear);
}
SECTION("Malvar")
{
vpImageConvert::demosaicRGGBToRGBaMalvar(I_Bayer_8U.bitmap, reinterpret_cast<uint8_t *>(I_RGBA_8U.bitmap),
I_Bayer_8U.getWidth(), I_Bayer_8U.getHeight());
double PSNR = computePSNR(I_RGBA_8U, I_RGBA_8U_ref);
std::cout << "8-bit - RGGB - Malvar - PSNR: " << PSNR << std::endl;
CHECK(PSNR >= min_PSNR_Malvar);
}
std::fclose(f);
}
}
}
#endif
int main(int argc, char *argv[])
{
Catch::Session session; // There must be exactly one instance
// Let Catch (using Clara) parse the command line
session.applyCommandLine(argc, argv);
int numFailed = session.run();
// numFailed is clamped to 255 as some unices only use the lower 8 bits.
// This clamping has already been applied, so just return it here
// You can also do any post run clean-up here
return numFailed;
}
#else
int main() { return EXIT_SUCCESS; }
#endif
Implementation of column vector and the associated operations.
Definition: vpColVector.h:172
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 split(const vpImage< vpRGBa > &src, vpImage< unsigned char > *pR, vpImage< unsigned char > *pG, vpImage< unsigned char > *pB, vpImage< unsigned char > *pa=NULL)
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 demosaicRGGBToRGBaMalvar(const uint8_t *rggb, uint8_t *rgba, unsigned int width, unsigned int height, unsigned int nThreads=0)
static void convert(const vpImage< unsigned char > &src, vpImage< vpRGBa > &dest)
static void RGBToGrey(unsigned char *rgb, unsigned char *grey, unsigned int width, unsigned int height, bool flip=false)
static void RGBToRGBa(unsigned char *rgb, unsigned char *rgba, 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 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)
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition: vpImageIo.cpp:148
unsigned int getWidth() const
Definition: vpImage.h:247
unsigned int getSize() const
Definition: vpImage.h:228
Type * bitmap
points toward the bitmap
Definition: vpImage.h:144
unsigned int getHeight() const
Definition: vpImage.h:189
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1399
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1764
static double sqr(double x)
Definition: vpMath.h:122
Definition: vpRGBa.h:67
VISP_EXPORT uint16_t swap16bits(uint16_t val)
Definition: vpEndian.cpp:49