| /* |
| * Copyright 2023 Google LLC |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "risp4ml/isp_stages/wbg.h" |
| |
| #include "pw_unit_test/framework.h" |
| #include "risp4ml/common/constants.h" |
| #include "risp4ml/common/test_utils.h" |
| |
| static constexpr uint16_t kWbgFractional = kRawPipelineFraction; |
| static constexpr uint16_t kFrameWidth = 4; |
| static constexpr uint16_t kFrameHeight = 4; |
| |
| class WbgTest : public ::testing::Test { |
| protected: |
| void SetUp() override { |
| in_ = image_new(1, kFrameHeight, kFrameWidth); |
| out_ = image_new(1, kFrameHeight, kFrameWidth); |
| num_bytes_ = |
| in_->num_channels * in_->height * in_->width * sizeof(pixel_type_t); |
| } |
| void TearDown() override { |
| image_delete(in_); |
| image_delete(out_); |
| } |
| |
| Image* in_; |
| Image* out_; |
| uint32_t num_bytes_; |
| }; |
| |
| TEST_F(WbgTest, IdentityTest) { |
| // Use a grey input image. |
| InitImageRandom(in_, kRawPipelineMinVal, kRawPipelineMaxVal); |
| memcpy(out_->data, in_->data, num_bytes_); |
| |
| // set the params to something boring. |
| uint32_t gain = 1 << kWbgFractional; |
| WbgParams params = { |
| .enable = true, .fixed = true, .gains = {gain, gain, gain, gain}}; |
| set_wbg_params(¶ms); |
| |
| wbg_process(out_); |
| for (uint16_t y = 0; y < kFrameHeight; y++) { |
| for (uint16_t x = 0; x < kFrameWidth; x++) { |
| ASSERT_EQ(image_pixel_val(in_, 0, y, x), image_pixel_val(out_, 0, y, x)); |
| } |
| } |
| } |
| |
| TEST_F(WbgTest, BayerTest) { |
| // Use a grey input image. |
| constexpr pixel_type_t kPixelVal = 1 << kWbgFractional; |
| InitImage(in_, kPixelVal); |
| memcpy(out_->data, in_->data, num_bytes_); |
| |
| // set the params to something boring. |
| WbgParams params = {.enable = true, |
| .fixed = true, |
| .gains = {kPixelVal, kPixelVal, kPixelVal, kPixelVal}}; |
| set_wbg_params(¶ms); |
| |
| wbg_process(out_); |
| |
| for (uint16_t c1 = 0; c1 < 2; ++c1) { |
| for (uint16_t c2 = 0; c2 < 2; ++c2) { |
| for (uint16_t y = 0; y < kFrameHeight / 2; y++) { |
| for (uint16_t x = 0; x < kFrameWidth / 2; x++) { |
| ASSERT_EQ(kPixelVal, |
| image_pixel_val(out_, 0, 2 * y + c1, 2 * x + c2)); |
| } |
| } |
| } |
| } |
| } |
| |
| TEST_F(WbgTest, SaturationTest) { |
| // Use a grey input image. |
| constexpr pixel_type_t kPixelValHi = kRawPipelineMaxVal - 10; |
| InitImage(in_, kPixelValHi); |
| memcpy(out_->data, in_->data, num_bytes_); |
| |
| uint32_t gain = 2 * (1 << kWbgFractional); |
| WbgParams params = { |
| .enable = true, .fixed = true, .gains = {gain, gain, gain, gain}}; |
| set_wbg_params(¶ms); |
| |
| wbg_process(out_); |
| |
| for (uint16_t y = 0; y < kFrameHeight; y++) { |
| for (uint16_t x = 0; x < kFrameWidth; x++) { |
| ASSERT_EQ(kRawPipelineMaxVal, image_pixel_val(out_, 0, y, x)); |
| } |
| } |
| } |