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>
monroegm-disable-blank-issue-2
hershey5045 4 years ago committed by GitHub
parent 63ce88a3ce
commit c514e1b490
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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};

Loading…
Cancel
Save