• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2023 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Tests for image_processing_utils."""
15
16
17import math
18import os
19import random
20import unittest
21
22import cv2
23import numpy
24
25import image_processing_utils
26
27
28class ImageProcessingUtilsTest(unittest.TestCase):
29  """Unit tests for this module."""
30  _SQRT_2 = numpy.sqrt(2)
31  _YUV_FULL_SCALE = 1023
32
33  def test_unpack_raw10_image(self):
34    """Unit test for unpack_raw10_image.
35
36    RAW10 bit packing format
37            bit 7   bit 6   bit 5   bit 4   bit 3   bit 2   bit 1   bit 0
38    Byte 0: P0[9]   P0[8]   P0[7]   P0[6]   P0[5]   P0[4]   P0[3]   P0[2]
39    Byte 1: P1[9]   P1[8]   P1[7]   P1[6]   P1[5]   P1[4]   P1[3]   P1[2]
40    Byte 2: P2[9]   P2[8]   P2[7]   P2[6]   P2[5]   P2[4]   P2[3]   P2[2]
41    Byte 3: P3[9]   P3[8]   P3[7]   P3[6]   P3[5]   P3[4]   P3[3]   P3[2]
42    Byte 4: P3[1]   P3[0]   P2[1]   P2[0]   P1[1]   P1[0]   P0[1]   P0[0]
43    """
44    # Test using a random 4x4 10-bit image
45    img_w, img_h = 4, 4
46    check_list = random.sample(range(0, 1024), img_h*img_w)
47    img_check = numpy.array(check_list).reshape(img_h, img_w)
48
49    # Pack bits
50    for row_start in range(0, len(check_list), img_w):
51      msbs = []
52      lsbs = ''
53      for pixel in range(img_w):
54        val = numpy.binary_repr(check_list[row_start+pixel], 10)
55        msbs.append(int(val[:8], base=2))
56        lsbs = val[8:] + lsbs
57      packed = msbs
58      packed.append(int(lsbs, base=2))
59      chunk_raw10 = numpy.array(packed, dtype='uint8').reshape(1, 5)
60      if row_start == 0:
61        img_raw10 = chunk_raw10
62      else:
63        img_raw10 = numpy.vstack((img_raw10, chunk_raw10))
64
65    # Unpack and check against original
66    self.assertTrue(numpy.array_equal(
67        image_processing_utils.unpack_raw10_image(img_raw10),
68        img_check))
69
70  def test_compute_image_sharpness(self):
71    """Unit test for compute_img_sharpness.
72
73    Tests by using PNG of ISO12233 chart and blurring intentionally.
74    'sharpness' should drop off by sqrt(2) for 2x blur of image.
75
76    We do one level of initial blur as PNG image is not perfect.
77    """
78    blur_levels = [2, 4, 8]
79    chart_file = os.path.join(
80        image_processing_utils.TEST_IMG_DIR, 'ISO12233.png')
81    chart = cv2.imread(chart_file, cv2.IMREAD_ANYDEPTH)
82    white_level = numpy.amax(chart).astype(float)
83    sharpness = {}
84    for blur in blur_levels:
85      chart_blurred = cv2.blur(chart, (blur, blur))
86      chart_blurred = chart_blurred[:, :, numpy.newaxis]
87      sharpness[blur] = (self._YUV_FULL_SCALE
88                         * image_processing_utils.compute_image_sharpness(
89                             chart_blurred / white_level))
90
91    for i in range(len(blur_levels)-1):
92      self.assertTrue(math.isclose(
93          sharpness[blur_levels[i]]/sharpness[blur_levels[i+1]], self._SQRT_2,
94          abs_tol=0.1))
95
96  def test_apply_lut_to_image(self):
97    """Unit test for apply_lut_to_image.
98
99    Test by using a canned set of values on a 1x1 pixel image.
100    The look-up table should double the value of the index: lut[x] = x*2
101    """
102    ref_image = [0.1, 0.2, 0.3]
103    lut_max = 65536
104    lut = numpy.array([i*2 for i in range(lut_max)])
105    x = numpy.array(ref_image).reshape((1, 1, 3))
106    y = image_processing_utils.apply_lut_to_image(x, lut).reshape(3).tolist()
107    y_ref = [i*2 for i in ref_image]
108    self.assertTrue(numpy.allclose(y, y_ref, atol=1/lut_max))
109
110
111if __name__ == '__main__':
112  unittest.main()
113