Skip to content

Commit

Permalink
Added RGGB10 Bayer to RGB48 converter
Browse files Browse the repository at this point in the history
Summary:
This converter was simply missing but now can be used to extracted the 10bit data of the Bayer mosaic image.

Added a corresponding unit test.

Reviewed By: enpe

Differential Revision: D62583184

fbshipit-source-id: d1b15a5b58d91c5c6fe0d8668e93f798503ee26b
  • Loading branch information
janherling authored and facebook-github-bot committed Sep 12, 2024
1 parent 379c2e1 commit db489ec
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 2 deletions.
1 change: 1 addition & 0 deletions impl/ocean/cv/FrameConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ FrameConverter::ConversionFunctionMap::ConversionFunctionMap()
// FORMAT_RGGB10_Packed
formatPair2FunctionWrapperMap_.emplace(ConversionTriple(FrameType::FORMAT_RGGB10_PACKED, FrameType::FORMAT_BGR24), FrameConverterRGGB10_Packed::convertRGGB10_PackedToBGR24);
formatPair2FunctionWrapperMap_.emplace(ConversionTriple(FrameType::FORMAT_RGGB10_PACKED, FrameType::FORMAT_RGB24), FrameConverterRGGB10_Packed::convertRGGB10_PackedToRGB24);
formatPair2FunctionWrapperMap_.emplace(ConversionTriple(FrameType::FORMAT_RGGB10_PACKED, FrameType::FORMAT_RGB48), FrameConverterRGGB10_Packed::convertRGGB10_PackedToRGB48);
formatPair2FunctionWrapperMap_.emplace(ConversionTriple(FrameType::FORMAT_RGGB10_PACKED, FrameType::FORMAT_RGB24, Options::OT_BLACKLEVEL_WHITEBALANCE_GAMMA), FrameConverterRGGB10_Packed::convertRGGB10_PackedToRGB24BlacklevelWhiteBalanceGammaLUT);

// FORMAT_UYVY16
Expand Down
32 changes: 30 additions & 2 deletions impl/ocean/cv/FrameConverterRGGB10_Packed.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,19 @@ class OCEAN_CV_EXPORT FrameConverterRGGB10_Packed : public FrameConverter
*/
static inline void convertRGGB10_PackedToRGB24(const uint8_t* const source, uint8_t* const target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);

/**
* Converts a RGGB10_PACKED frame to a RGB48 frame.
* @param source The source frame buffer, must be valid
* @param target The target frame buffer, must be valid
* @param width The width of the frame in pixel, with range [4, infinity), must be a multiple of 4
* @param height The height of the frame in pixel, with range [1, infinity)
* @param flag Determining the type of conversion
* @param sourcePaddingElements The number of padding elements at the end of each source row, in elements, with range [0, infinity)
* @param targetPaddingElements The number of padding elements at the end of each target row, in elements, with range [0, infinity)
* @param worker Optional worker object to distribute the computational load
*/
static inline void convertRGGB10_PackedToRGB48(const uint8_t* const source, uint16_t* const target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker = nullptr);

/**
* Converts a RGGB10_PACKED frame to a RGB24 frame with black level subtraction, white balance, and gamma encoding
* @param source The source frame buffer, must be valid
Expand Down Expand Up @@ -84,7 +97,7 @@ inline void FrameConverterRGGB10_Packed::convertRGGB10_PackedToBGR24(const uint8
int(sourcePaddingElements), int(targetPaddingElements)
};

FrameConverter::convertArbitraryPixelFormat((const void**)&source, (void**)&target, width, height, flag, 2u, FrameConverter::convertTwoRows_1PlaneMosaicPacked10Bit_To_1PlaneUnpacked3Channels8Bit<2u, 1u, 0u>, options, worker);
FrameConverter::convertArbitraryPixelFormat((const void**)(&source), (void**)(&target), width, height, flag, 2u, FrameConverter::convertTwoRows_1PlaneMosaicPacked10Bit_To_1PlaneUnpacked3Channels8Bit<2u, 1u, 0u>, options, worker);
}

inline void FrameConverterRGGB10_Packed::convertRGGB10_PackedToRGB24(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
Expand All @@ -99,7 +112,22 @@ inline void FrameConverterRGGB10_Packed::convertRGGB10_PackedToRGB24(const uint8
int(sourcePaddingElements), int(targetPaddingElements)
};

FrameConverter::convertArbitraryPixelFormat((const void**)&source, (void**)&target, width, height, flag, 2u, FrameConverter::convertTwoRows_1PlaneMosaicPacked10Bit_To_1PlaneUnpacked3Channels8Bit<0u, 1u, 2u>, options, worker);
FrameConverter::convertArbitraryPixelFormat((const void**)(&source), (void**)(&target), width, height, flag, 2u, FrameConverter::convertTwoRows_1PlaneMosaicPacked10Bit_To_1PlaneUnpacked3Channels8Bit<0u, 1u, 2u>, options, worker);
}

inline void FrameConverterRGGB10_Packed::convertRGGB10_PackedToRGB48(const uint8_t* const source, uint16_t* const target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
{
ocean_assert(source != nullptr && target != nullptr);
ocean_assert(width >= 4u && height >= 1u);
ocean_assert(width % 4u == 0u);

const int options[2] =
{
// padding parameters
int(sourcePaddingElements), int(targetPaddingElements)
};

FrameConverter::convertArbitraryPixelFormat((const void**)(&source), (void**)(&target), width, height, flag, 2u, FrameConverter::convertTwoRows_1PlaneMosaicPacked10Bit_To_1PlaneUnpacked3Channels16Bit<0u, 1u, 2u>, options, worker);
}

inline void FrameConverterRGGB10_Packed::convertRGGB10_PackedToRGB24BlacklevelWhiteBalanceGammaLUT(const uint8_t* source, uint8_t* target, const unsigned int width, const unsigned int height, const ConversionFlag flag, const uint16_t blackLevel, const float* whiteBalance, const float gamma, const unsigned int sourcePaddingElements, const unsigned int targetPaddingElements, Worker* worker)
Expand Down
54 changes: 54 additions & 0 deletions impl/ocean/test/testcv/TestFrameConverterRGGB10_Packed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,20 @@ bool TestFrameConverterRGGB10_Packed::test(const unsigned int width, const unsig
Log::info() << "-";
Log::info() << " ";

{
Log::info() << "Testing RGGB10_PACKED to RGB48 conversion with resolution " << width << "x" << height << ":";

for (const CV::FrameConverter::ConversionFlag flag : CV::FrameConverter::conversionFlags())
{
Log::info() << " ";
allSucceeded = testRGGB10_PackedToRGB48(width, height, flag, testDuration, worker) && allSucceeded;
}
}

Log::info() << " ";
Log::info() << "-";
Log::info() << " ";

{
Log::info() << "Testing RGGB10_PACKED to RGB24 conversion with black-level subtraction, white balancing, and gamma encoding at resolution " << width << "x" << height << ":";

Expand Down Expand Up @@ -135,6 +149,32 @@ TEST(TestFrameConverterRGGB10_Packed, RGGB10_PackedToRGB24FlippedMirrored)
EXPECT_TRUE(TestFrameConverterRGGB10_Packed::testRGGB10_PackedToRGB24(GTEST_TEST_IMAGE_WIDTH, GTEST_TEST_IMAGE_HEIGHT, CV::FrameConverter::CONVERT_FLIPPED_AND_MIRRORED, GTEST_TEST_DURATION, worker));
}


TEST(TestFrameConverterRGGB10_Packed, RGGB10_PackedToRGB48Normal)
{
Worker worker;
EXPECT_TRUE(TestFrameConverterRGGB10_Packed::testRGGB10_PackedToRGB48(GTEST_TEST_IMAGE_WIDTH, GTEST_TEST_IMAGE_HEIGHT, CV::FrameConverter::CONVERT_NORMAL, GTEST_TEST_DURATION, worker));
}

TEST(TestFrameConverterRGGB10_Packed, RGGB10_PackedToRGB48Flipped)
{
Worker worker;
EXPECT_TRUE(TestFrameConverterRGGB10_Packed::testRGGB10_PackedToRGB48(GTEST_TEST_IMAGE_WIDTH, GTEST_TEST_IMAGE_HEIGHT, CV::FrameConverter::CONVERT_FLIPPED, GTEST_TEST_DURATION, worker));
}

TEST(TestFrameConverterRGGB10_Packed, RGGB10_PackedToRGB48Mirrored)
{
Worker worker;
EXPECT_TRUE(TestFrameConverterRGGB10_Packed::testRGGB10_PackedToRGB48(GTEST_TEST_IMAGE_WIDTH, GTEST_TEST_IMAGE_HEIGHT, CV::FrameConverter::CONVERT_MIRRORED, GTEST_TEST_DURATION, worker));
}

TEST(TestFrameConverterRGGB10_Packed, RGGB10_PackedToRGB48FlippedMirrored)
{
Worker worker;
EXPECT_TRUE(TestFrameConverterRGGB10_Packed::testRGGB10_PackedToRGB48(GTEST_TEST_IMAGE_WIDTH, GTEST_TEST_IMAGE_HEIGHT, CV::FrameConverter::CONVERT_FLIPPED_AND_MIRRORED, GTEST_TEST_DURATION, worker));
}


TEST(TestFrameConverterRGGB10_Packed, RGGB10_PackedToRGB24BlackLevelWhiteBalanceGammaLUTNormal)
{
RandomGenerator randomGenerator;
Expand Down Expand Up @@ -199,6 +239,20 @@ bool TestFrameConverterRGGB10_Packed::testRGGB10_PackedToRGB24(const unsigned in
return TestFrameConverter::testFrameConversion(FrameType::FORMAT_RGGB10_PACKED, FrameType::FORMAT_RGB24, width, height, TestFrameConverter::FunctionWrapper(CV::FrameConverterRGGB10_Packed::convertRGGB10_PackedToRGB24), flag, TestFrameConverterRGGB10_Packed::PixelFunctorRGGB10_Packed::pixelFunctionRGGB10_Packed, TestFrameConverter::functionGenericPixel, transformationMatrix, 0.0, 255.0, testDuration, worker);
}

bool TestFrameConverterRGGB10_Packed::testRGGB10_PackedToRGB48(const unsigned int width, const unsigned int height, const CV::FrameConverter::ConversionFlag flag, const double testDuration, Worker& worker)
{
ocean_assert(testDuration > 0.0);
ocean_assert(width != 0u && height != 0u);

// | R16 | | 1.0 0.0 0.0 | | R10 |
// | G16 | = | 0.0 1.0 0.0 | * | G10 |
// | B16 | | 0.0 0.0 1.0 | | B10 |

const MatrixD transformationMatrix(3, 3, true);

return TestFrameConverter::testFrameConversion(FrameType::FORMAT_RGGB10_PACKED, FrameType::FORMAT_RGB48, width, height, TestFrameConverter::FunctionWrapper(CV::FrameConverterRGGB10_Packed::convertRGGB10_PackedToRGB48), flag, TestFrameConverterRGGB10_Packed::PixelFunctorRGGB10_Packed::pixelFunctionRGGB10_Packed, TestFrameConverter::functionGenericPixel, transformationMatrix, 0.0, 1023.0, testDuration, worker);
}

bool TestFrameConverterRGGB10_Packed::testConvertRGGB10_PackedToRGB24BlacklevelWhiteBalanceGammaLUT(RandomGenerator& randomGenerator, const unsigned int width, const unsigned int height, const CV::FrameConverter::ConversionFlag flag, const double testDuration, Worker& worker)
{
ocean_assert(testDuration > 0.0);
Expand Down
11 changes: 11 additions & 0 deletions impl/ocean/test/testcv/TestFrameConverterRGGB10_Packed.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,17 @@ class OCEAN_TEST_CV_EXPORT TestFrameConverterRGGB10_Packed
*/
static bool testRGGB10_PackedToRGB24(const unsigned int width, const unsigned int height, const CV::FrameConverter::ConversionFlag flag, const double testDuration, Worker& worker);

/**
* Tests the RGGB10_PACKED to RGB48 conversion.
* @param width The width of the original frame in pixel, with range [1, infinity)
* @param height The height of the original frame in pixel, with range [1, infinity)
* @param flag The conversion flag that has been applied during conversion
* @param testDuration Number of seconds for each test, with range (0, infinity)
* @param worker The worker object
* @return True, if succeeded
*/
static bool testRGGB10_PackedToRGB48(const unsigned int width, const unsigned int height, const CV::FrameConverter::ConversionFlag flag, const double testDuration, Worker& worker);

/**
* Tests the RGGB10_PACKED to RGB24 conversion with black-level subtraction, white balancing, and gamma encoding.
* @param randomGenerator The random generator to be used
Expand Down

0 comments on commit db489ec

Please sign in to comment.