Small refactor on ImageComparison utils. (#7133)
* Small refactor on ImageComparison utils. Signed-off-by: hershey5045 <43485729+hershey5045@users.noreply.github.com> * Add aznumeric cast. Signed-off-by: hershey5045 <43485729+hershey5045@users.noreply.github.com> * Correction on aznumeric cast. Signed-off-by: hershey5045 <43485729+hershey5045@users.noreply.github.com> * Add unit test for new image comparison function. Signed-off-by: hershey5045 <43485729+hershey5045@users.noreply.github.com>
This commit is contained in:
@@ -23,6 +23,9 @@ namespace AZ
|
||||
UnsupportedFormat
|
||||
};
|
||||
|
||||
//! Calculates the maximum difference of the rgb channels between two image buffers.
|
||||
int16_t CalcMaxChannelDifference(AZStd::array_view<uint8_t> bufferA, AZStd::array_view<uint8_t> bufferB, size_t index);
|
||||
|
||||
//! Compares two images and returns the RMS (root mean square) of the difference.
|
||||
//! @param buffer[A|B] the raw buffer of image data
|
||||
//! @param size[A|B] the dimensions of the image in the buffer
|
||||
|
||||
@@ -14,6 +14,16 @@ namespace AZ
|
||||
{
|
||||
namespace Utils
|
||||
{
|
||||
int16_t CalcMaxChannelDifference(AZStd::array_view<uint8_t> bufferA, AZStd::array_view<uint8_t> bufferB, size_t index)
|
||||
{
|
||||
// We use the max error from a single channel instead of accumulating the error from each channel.
|
||||
// This normalizes differences so that for example black vs red has the same weight as black vs yellow.
|
||||
const int16_t diffR = static_cast<int16_t>(abs(aznumeric_cast<int16_t>(bufferA[index]) - aznumeric_cast<int16_t>(bufferB[index])));
|
||||
const int16_t diffG = static_cast<int16_t>(abs(aznumeric_cast<int16_t>(bufferA[index + 1]) - aznumeric_cast<int16_t>(bufferB[index + 1])));
|
||||
const int16_t diffB = static_cast<int16_t>(abs(aznumeric_cast<int16_t>(bufferA[index + 2]) - aznumeric_cast<int16_t>(bufferB[index + 2])));
|
||||
return AZ::GetMax(AZ::GetMax(diffR, diffG), diffB);
|
||||
}
|
||||
|
||||
ImageDiffResultCode CalcImageDiffRms(
|
||||
AZStd::span<const uint8_t> bufferA, const RHI::Size& sizeA, RHI::Format formatA,
|
||||
AZStd::span<const uint8_t> bufferB, const RHI::Size& sizeB, RHI::Format formatB,
|
||||
@@ -67,14 +77,7 @@ namespace AZ
|
||||
|
||||
for (size_t i = 0; i < bufferA.size(); i += BytesPerPixel)
|
||||
{
|
||||
// We use the max error from a single channel instead of accumulating the error from each channel.
|
||||
// This normalizes differences so that for example black vs red has the same weight as black vs yellow.
|
||||
const int16_t diffR = static_cast<int16_t>(abs(aznumeric_cast<int16_t>(bufferA[i]) - aznumeric_cast<int16_t>(bufferB[i])));
|
||||
const int16_t diffG = static_cast<int16_t>(abs(aznumeric_cast<int16_t>(bufferA[i + 1]) - aznumeric_cast<int16_t>(bufferB[i + 1])));
|
||||
const int16_t diffB = static_cast<int16_t>(abs(aznumeric_cast<int16_t>(bufferA[i + 2]) - aznumeric_cast<int16_t>(bufferB[i + 2])));
|
||||
const int16_t maxDiff = AZ::GetMax(AZ::GetMax(diffR, diffG), diffB);
|
||||
|
||||
const float finalDiffNormalized = maxDiff / 255.0f;
|
||||
const float finalDiffNormalized = aznumeric_cast<float>(CalcMaxChannelDifference(bufferA, bufferB, i)) / 255.0f;
|
||||
const float squared = finalDiffNormalized * finalDiffNormalized;
|
||||
|
||||
if (diffScore)
|
||||
|
||||
@@ -127,6 +127,16 @@ namespace UnitTest
|
||||
EXPECT_EQ(0.0f, diffScore);
|
||||
}
|
||||
|
||||
|
||||
TEST_F(ImageComparisonTests, CheckMaxChannelDifference)
|
||||
{
|
||||
const AZStd::vector<uint8_t> imageA = { 255, 255, 255 };
|
||||
const AZStd::vector<uint8_t> imageB = { 0, 125, 255 };
|
||||
const int16_t maxChannelDiff = 255;
|
||||
const int16_t res = CalcMaxChannelDifference(imageA, imageB, 0);
|
||||
EXPECT_EQ(res, maxChannelDiff);
|
||||
}
|
||||
|
||||
TEST_F(ImageComparisonTests, CheckThreshold_SmallImagesWithDifferences)
|
||||
{
|
||||
AZ::RHI::Size size{2, 2, 1};
|
||||
|
||||
Reference in New Issue
Block a user