CameraITS: Reprocess edge enhancement test
Add a test to verify edge mode is applied when set for reprocess
requests.
Bug: 20924584
Change-Id: I7ee6b0fb72590f92647cc5460648788e00421557
diff --git a/apps/CameraITS/CameraITS.pdf b/apps/CameraITS/CameraITS.pdf
index 3866930..5a511c0 100644
--- a/apps/CameraITS/CameraITS.pdf
+++ b/apps/CameraITS/CameraITS.pdf
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/image.py b/apps/CameraITS/pymodules/its/image.py
index 03f8ff9..f08fb50 100644
--- a/apps/CameraITS/pymodules/its/image.py
+++ b/apps/CameraITS/pymodules/its/image.py
@@ -757,6 +757,25 @@
return patches
+def compute_image_sharpness(img):
+ """Calculate the sharpness of input image.
+
+ Args:
+ img: Numpy float RGB/luma image array, with pixel values in [0,1].
+
+ Returns:
+ A sharpness estimation value based on the average of gradient magnitude.
+ Larger value means the image is sharper.
+ """
+ chans = img.shape[2]
+ assert(chans == 1 or chans == 3)
+ luma = img
+ if (chans == 3):
+ luma = 0.299 * img[:,:,0] + 0.587 * img[:,:,1] + 0.114 * img[:,:,2]
+
+ [gy, gx] = numpy.gradient(luma)
+ return numpy.average(numpy.sqrt(gy*gy + gx*gx))
+
class __UnitTest(unittest.TestCase):
"""Run a suite of unit tests on this module.
"""
diff --git a/apps/CameraITS/tests/scene3/test_reprocess_edge_enhancement.py b/apps/CameraITS/tests/scene3/test_reprocess_edge_enhancement.py
new file mode 100644
index 0000000..1966d9e
--- /dev/null
+++ b/apps/CameraITS/tests/scene3/test_reprocess_edge_enhancement.py
@@ -0,0 +1,159 @@
+# Copyright 2015 The Android Open Source Project
+#
+# 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.
+
+import its.image
+import its.caps
+import its.device
+import its.objects
+import its.target
+import math
+import matplotlib
+import matplotlib.pyplot
+import os.path
+import pylab
+
+
+def test_edge_mode(cam, edge_mode, sensitivity, exp, fd, out_surface,
+ reprocess_format=None):
+ """Return sharpness of the output image and the capture result metadata
+ for a capture request with the given edge mode, sensitivity, exposure
+ time, focus distance, output surface parameter, and reprocess format
+ (None for a regular request.)
+
+ Args:
+ cam: An open device session.
+ edge_mode: Edge mode for the request as defined in android.edge.mode
+ sensitivity: Sensitivity for the request as defined in
+ android.sensor.sensitivity
+ exp: Exposure time for the request as defined in
+ android.sensor.exposureTime.
+ fd: Focus distance for the request as defined in
+ android.lens.focusDistance
+ output_surface: Specifications of the output image format and size.
+ reprocess_format: (Optional) The reprocessing format. If not None,
+ reprocessing will be enabled.
+
+ Returns:
+ Object containing reported edge mode and the sharpness of the output
+ image, keyed by the following strings:
+ "edge_mode"
+ "sharpness"
+ """
+
+ NAME = os.path.basename(__file__).split(".")[0]
+
+ req = its.objects.manual_capture_request(sensitivity, exp)
+ req["android.lens.focusDistance"] = fd
+ req["android.edge.mode"] = edge_mode
+ if (reprocess_format != None):
+ req["android.reprocess.effectiveExposureFactor"] = 1.0
+ cap = cam.do_capture(req, out_surface, reprocess_format)
+
+ img = its.image.decompress_jpeg_to_rgb_image(cap["data"])
+ its.image.write_image(img, "%s_edge=%d_reprocess_fmt_%s.jpg" %
+ (NAME, edge_mode, reprocess_format))
+ tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
+
+ ret = {}
+ ret["edge_mode"] = cap["metadata"]["android.edge.mode"]
+ ret["sharpness"] = its.image.compute_image_sharpness(tile)
+
+ return ret
+
+def main():
+ """Test that the android.edge.mode param is applied when set for
+ reprocessing requests.
+
+ Capture non-reprocess images for each edge mode and calculate their
+ sharpness as a baseline.
+
+ Capture reprocessed images for each supported reprocess format and edge_mode
+ mode. Calculate the sharpness of reprocessed images and compare them against
+ the sharpess of non-reprocess images.
+ """
+
+ THRESHOLD_RELATIVE_SHARPNESS_DIFF = 0.1
+
+ with its.device.ItsSession() as cam:
+ props = cam.get_camera_properties()
+
+ its.caps.skip_unless(its.caps.read_3a(props) and
+ its.caps.per_frame_control(props) and
+ (its.caps.yuv_reprocess(props) or
+ its.caps.private_reprocess(props)))
+
+ reprocess_formats = []
+ if (its.caps.yuv_reprocess(props)):
+ reprocess_formats.append("yuv")
+ if (its.caps.private_reprocess(props)):
+ reprocess_formats.append("private")
+
+ size = its.objects.get_available_output_sizes("jpg", props)[0]
+ out_surface = {"width":size[0], "height":size[1], "format":"jpg"}
+
+ # Get proper sensitivity, exposure time, and focus distance.
+ s,e,_,_,fd = cam.do_3a(get_results=True)
+
+ # Get the sharpness for each edge mode for regular requests
+ sharpness_regular = []
+ edge_mode_reported_regular = []
+ for edge_mode in range(3):
+ ret = test_edge_mode(cam, edge_mode, s, e, fd, out_surface)
+ edge_mode_reported_regular.append(ret["edge_mode"])
+ sharpness_regular.append(ret["sharpness"])
+
+ print "Reported edge modes:", edge_mode_reported_regular
+ print "Sharpness with EE mode [0,1,2]:", sharpness_regular
+
+ # Get the sharpness for each reprocess format and edge mode for
+ # reprocess requests.
+ sharpnesses_reprocess = []
+ edge_mode_reported_reprocess = []
+
+ for reprocess_format in reprocess_formats:
+ # List of sharpness
+ sharpnesses = []
+ edge_mode_reported = []
+ for edge_mode in range(3):
+ ret = test_edge_mode(cam, edge_mode, s, e, fd, out_surface,
+ reprocess_format)
+ edge_mode_reported.append(ret["edge_mode"])
+ sharpnesses.append(ret["sharpness"])
+
+ sharpnesses_reprocess.append(sharpnesses)
+ edge_mode_reported_reprocess.append(edge_mode_reported)
+
+ print "Reported edge modes:", edge_mode_reported
+ print "Sharpness with EE mode [0,1,2] for %s reprocess:" % \
+ (reprocess_format) , sharpnesses
+
+ # Verify the results
+ assert(edge_mode_reported_regular == [0,1,2])
+ assert(sharpness_regular[1] >
+ sharpness_regular[0] * (1.0 - THRESHOLD_RELATIVE_SHARPNESS_DIFF))
+ assert(sharpness_regular[2] >
+ sharpness_regular[0] * (1.0 - THRESHOLD_RELATIVE_SHARPNESS_DIFF))
+
+ # Verify the reprocess
+ for reprocess_format in range(len(reprocess_formats)):
+ assert(edge_mode_reported_reprocess[reprocess_format] == [0,1,2])
+ for edge_mode in range(3):
+ assert(sharpnesses_reprocess[reprocess_format][edge_mode] >=
+ (1.0 - THRESHOLD_RELATIVE_SHARPNESS_DIFF) *
+ sharpnesses_reprocess[reprocess_format][0] *
+ sharpness_regular[edge_mode] / sharpness_regular[0])
+
+if __name__ == '__main__':
+ main()
+
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
index c065f12..254d65cf 100644
--- a/apps/CameraITS/tools/run_all_tests.py
+++ b/apps/CameraITS/tools/run_all_tests.py
@@ -43,15 +43,17 @@
"test_yuv_plus_jpeg"
],
"scene2":[]
+ "scene3":[]
}
# Get all the scene0 and scene1 tests, which can be run using the same
# physical setup.
- scenes = ["scene0", "scene1", "scene2"]
+ scenes = ["scene0", "scene1", "scene2", "scene3"]
scene_req = {
"scene0" : None,
"scene1" : "A grey card covering at least the middle 30% of the scene",
"scene2" : "A picture containing human faces"
+ "scene3" : "A chart containing sharp edges like ISO 12233"
}
tests = []
for d in scenes: