aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorTimothy Knight <tknight@google.com>2014-10-11 12:32:51 -0700
committerTimothy Knight <tknight@google.com>2014-10-11 12:32:51 -0700
commitbbb866aa9470768fe6a4573888a0320093d736ea (patch)
treef98947662fde1f96de0c847ed9fcf31eec753d7e /apps
parentefa9ed3c6f511dd472848dab6e145384087887a4 (diff)
downloadpdk-bbb866aa9470768fe6a4573888a0320093d736ea.tar.gz
CameraITS: Fixed some test TODOs
Change-Id: I092940e510823250c8581c08133d31b89f93512b
Diffstat (limited to 'apps')
-rw-r--r--apps/CameraITS/tests/scene1/test_capture_result.py326
-rw-r--r--apps/CameraITS/tests/scene1/test_crop_regions.py16
-rw-r--r--apps/CameraITS/tests/scene1/test_raw_sensitivity.py2
-rw-r--r--apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py (renamed from apps/CameraITS/tests/scene1/test_formats.py)3
4 files changed, 175 insertions, 172 deletions
diff --git a/apps/CameraITS/tests/scene1/test_capture_result.py b/apps/CameraITS/tests/scene1/test_capture_result.py
index 56bde60..c88a2e0 100644
--- a/apps/CameraITS/tests/scene1/test_capture_result.py
+++ b/apps/CameraITS/tests/scene1/test_capture_result.py
@@ -25,171 +25,49 @@ import mpl_toolkits.mplot3d
def main():
"""Test that valid data comes back in CaptureResult objects.
"""
- NAME = os.path.basename(__file__).split(".")[0]
+ global NAME, auto_req, manual_req, w_map, h_map
+ global manual_tonemap, manual_transform, manual_gains, manual_region
+ global manual_exp_time, manual_sensitivity, manual_gains_ok
- manual_tonemap = [0,0, 1,1] # Linear
- manual_transform = its.objects.int_to_rational([1,2,3, 4,5,6, 7,8,9])
- manual_gains = [1,2,3,4]
- manual_region = [{"x":8,"y":8,"width":128,"height":128,"weight":1}]
- # TODO: Stop using hardcoded exposure values.
- manual_exp_time = 100*1000*1000
- manual_sensitivity = 100
-
- # The camera HAL may not support different gains for the two G channels.
- manual_gains_ok = [[1,2,3,4],[1,2,2,4],[1,3,3,4]]
-
- auto_req = its.objects.auto_capture_request()
- auto_req["android.statistics.lensShadingMapMode"] = 1
-
- manual_req = {
- "android.control.mode": 0,
- "android.control.aeMode": 0,
- "android.control.awbMode": 0,
- "android.control.afMode": 0,
- "android.sensor.frameDuration": 0,
- "android.sensor.sensitivity": manual_sensitivity,
- "android.sensor.exposureTime": manual_exp_time,
- "android.colorCorrection.mode": 0,
- "android.colorCorrection.transform": manual_transform,
- "android.colorCorrection.gains": manual_gains,
- "android.tonemap.mode": 0,
- "android.tonemap.curveRed": manual_tonemap,
- "android.tonemap.curveGreen": manual_tonemap,
- "android.tonemap.curveBlue": manual_tonemap,
- "android.control.aeRegions": manual_region,
- "android.control.afRegions": manual_region,
- "android.control.awbRegions": manual_region,
- "android.statistics.lensShadingMapMode":1
- }
-
- # A very loose definition for two floats being close to each other;
- # there may be different interpolation and rounding used to get the
- # two values, and all this test is looking at is whether there is
- # something obviously broken; it's not looking for a perfect match.
- def is_close_float(n1, n2):
- return abs(n1 - n2) < 0.05
-
- def is_close_rational(n1, n2):
- return is_close_float(its.objects.rational_to_float(n1),
- its.objects.rational_to_float(n2))
-
- def draw_lsc_plot(w_map, h_map, lsc_map, name):
- for ch in range(4):
- fig = matplotlib.pyplot.figure()
- ax = fig.gca(projection='3d')
- xs = numpy.array([range(w_map)] * h_map).reshape(h_map, w_map)
- ys = numpy.array([[i]*w_map for i in range(h_map)]).reshape(
- h_map, w_map)
- zs = numpy.array(lsc_map[ch::4]).reshape(h_map, w_map)
- ax.plot_wireframe(xs, ys, zs)
- matplotlib.pyplot.savefig("%s_plot_lsc_%s_ch%d.png"%(NAME,name,ch))
-
- def test_auto(cam, w_map, h_map):
- # Get 3A lock first, so the auto values in the capture result are
- # populated properly.
- rect = [[0,0,1,1,1]]
- cam.do_3a(rect, rect, rect, True, True, False)
-
- cap = cam.do_capture(auto_req)
- cap_res = cap["metadata"]
-
- gains = cap_res["android.colorCorrection.gains"]
- transform = cap_res["android.colorCorrection.transform"]
- exp_time = cap_res['android.sensor.exposureTime']
- lsc_map = cap_res["android.statistics.lensShadingMap"]
- ctrl_mode = cap_res["android.control.mode"]
-
- print "Control mode:", ctrl_mode
- print "Gains:", gains
- print "Transform:", [its.objects.rational_to_float(t)
- for t in transform]
- print "AE region:", cap_res['android.control.aeRegions']
- print "AF region:", cap_res['android.control.afRegions']
- print "AWB region:", cap_res['android.control.awbRegions']
- print "LSC map:", w_map, h_map, lsc_map[:8]
-
- assert(ctrl_mode == 1)
-
- # Color correction gain and transform must be valid.
- assert(len(gains) == 4)
- assert(len(transform) == 9)
- assert(all([g > 0 for g in gains]))
- assert(all([t["denominator"] != 0 for t in transform]))
-
- # Color correction should not match the manual settings.
- assert(any([not is_close_float(gains[i], manual_gains[i])
- for i in xrange(4)]))
- assert(any([not is_close_rational(transform[i], manual_transform[i])
- for i in xrange(9)]))
-
- # Exposure time must be valid.
- assert(exp_time > 0)
-
- # Lens shading map must be valid.
- assert(w_map > 0 and h_map > 0 and w_map * h_map * 4 == len(lsc_map))
- assert(all([m >= 1 for m in lsc_map]))
-
- draw_lsc_plot(w_map, h_map, lsc_map, "auto")
-
- return lsc_map
-
- def test_manual(cam, w_map, h_map, lsc_map_auto):
- cap = cam.do_capture(manual_req)
- cap_res = cap["metadata"]
-
- gains = cap_res["android.colorCorrection.gains"]
- transform = cap_res["android.colorCorrection.transform"]
- curves = [cap_res["android.tonemap.curveRed"],
- cap_res["android.tonemap.curveGreen"],
- cap_res["android.tonemap.curveBlue"]]
- exp_time = cap_res['android.sensor.exposureTime']
- lsc_map = cap_res["android.statistics.lensShadingMap"]
- ctrl_mode = cap_res["android.control.mode"]
-
- print "Control mode:", ctrl_mode
- print "Gains:", gains
- print "Transform:", [its.objects.rational_to_float(t)
- for t in transform]
- print "Tonemap:", curves[0][1::16]
- print "AE region:", cap_res['android.control.aeRegions']
- print "AF region:", cap_res['android.control.afRegions']
- print "AWB region:", cap_res['android.control.awbRegions']
- print "LSC map:", w_map, h_map, lsc_map[:8]
-
- assert(ctrl_mode == 0)
-
- # Color correction gain and transform must be valid.
- # Color correction gains and transform should be the same size and
- # values as the manually set values.
- assert(len(gains) == 4)
- assert(len(transform) == 9)
- assert( all([is_close_float(gains[i], manual_gains_ok[0][i])
- for i in xrange(4)]) or
- all([is_close_float(gains[i], manual_gains_ok[1][i])
- for i in xrange(4)]) or
- all([is_close_float(gains[i], manual_gains_ok[2][i])
- for i in xrange(4)]))
- assert(all([is_close_rational(transform[i], manual_transform[i])
- for i in xrange(9)]))
-
- # Tonemap must be valid.
- # The returned tonemap must be linear.
- for c in curves:
- assert(len(c) > 0)
- assert(all([is_close_float(c[i], c[i+1])
- for i in xrange(0,len(c),2)]))
-
- # Exposure time must be close to the requested exposure time.
- assert(is_close_float(exp_time/1000000.0, manual_exp_time/1000000.0))
-
- # Lens shading map must be valid.
- assert(w_map > 0 and h_map > 0 and w_map * h_map * 4 == len(lsc_map))
- assert(all([m >= 1 for m in lsc_map]))
-
- draw_lsc_plot(w_map, h_map, lsc_map, "manual")
+ NAME = os.path.basename(__file__).split(".")[0]
with its.device.ItsSession() as cam:
props = cam.get_camera_properties()
+
+ manual_tonemap = [0,0, 1,1] # Linear
+ manual_transform = its.objects.int_to_rational([1,2,3, 4,5,6, 7,8,9])
+ manual_gains = [1,2,3,4]
+ manual_region = [{"x":8,"y":8,"width":128,"height":128,"weight":1}]
+ manual_exp_time = min(props['android.sensor.info.exposureTimeRange'])
+ manual_sensitivity = min(props['android.sensor.info.sensitivityRange'])
+
+ # The camera HAL may not support different gains for two G channels.
+ manual_gains_ok = [[1,2,3,4],[1,2,2,4],[1,3,3,4]]
+
+ auto_req = its.objects.auto_capture_request()
+ auto_req["android.statistics.lensShadingMapMode"] = 1
+
+ manual_req = {
+ "android.control.mode": 0,
+ "android.control.aeMode": 0,
+ "android.control.awbMode": 0,
+ "android.control.afMode": 0,
+ "android.sensor.frameDuration": 0,
+ "android.sensor.sensitivity": manual_sensitivity,
+ "android.sensor.exposureTime": manual_exp_time,
+ "android.colorCorrection.mode": 0,
+ "android.colorCorrection.transform": manual_transform,
+ "android.colorCorrection.gains": manual_gains,
+ "android.tonemap.mode": 0,
+ "android.tonemap.curveRed": manual_tonemap,
+ "android.tonemap.curveGreen": manual_tonemap,
+ "android.tonemap.curveBlue": manual_tonemap,
+ "android.control.aeRegions": manual_region,
+ "android.control.afRegions": manual_region,
+ "android.control.awbRegions": manual_region,
+ "android.statistics.lensShadingMapMode":1
+ }
+
w_map = props["android.lens.info.shadingMapSize"]["width"]
h_map = props["android.lens.info.shadingMapSize"]["height"]
@@ -200,6 +78,132 @@ def main():
print "Testing auto capture results again"
test_auto(cam, w_map, h_map)
+# A very loose definition for two floats being close to each other;
+# there may be different interpolation and rounding used to get the
+# two values, and all this test is looking at is whether there is
+# something obviously broken; it's not looking for a perfect match.
+def is_close_float(n1, n2):
+ return abs(n1 - n2) < 0.05
+
+def is_close_rational(n1, n2):
+ return is_close_float(its.objects.rational_to_float(n1),
+ its.objects.rational_to_float(n2))
+
+def draw_lsc_plot(w_map, h_map, lsc_map, name):
+ for ch in range(4):
+ fig = matplotlib.pyplot.figure()
+ ax = fig.gca(projection='3d')
+ xs = numpy.array([range(w_map)] * h_map).reshape(h_map, w_map)
+ ys = numpy.array([[i]*w_map for i in range(h_map)]).reshape(
+ h_map, w_map)
+ zs = numpy.array(lsc_map[ch::4]).reshape(h_map, w_map)
+ ax.plot_wireframe(xs, ys, zs)
+ matplotlib.pyplot.savefig("%s_plot_lsc_%s_ch%d.png"%(NAME,name,ch))
+
+def test_auto(cam, w_map, h_map):
+ # Get 3A lock first, so the auto values in the capture result are
+ # populated properly.
+ rect = [[0,0,1,1,1]]
+ cam.do_3a(rect, rect, rect, True, True, False)
+
+ cap = cam.do_capture(auto_req)
+ cap_res = cap["metadata"]
+
+ gains = cap_res["android.colorCorrection.gains"]
+ transform = cap_res["android.colorCorrection.transform"]
+ exp_time = cap_res['android.sensor.exposureTime']
+ lsc_map = cap_res["android.statistics.lensShadingMap"]
+ ctrl_mode = cap_res["android.control.mode"]
+
+ print "Control mode:", ctrl_mode
+ print "Gains:", gains
+ print "Transform:", [its.objects.rational_to_float(t)
+ for t in transform]
+ print "AE region:", cap_res['android.control.aeRegions']
+ print "AF region:", cap_res['android.control.afRegions']
+ print "AWB region:", cap_res['android.control.awbRegions']
+ print "LSC map:", w_map, h_map, lsc_map[:8]
+
+ assert(ctrl_mode == 1)
+
+ # Color correction gain and transform must be valid.
+ assert(len(gains) == 4)
+ assert(len(transform) == 9)
+ assert(all([g > 0 for g in gains]))
+ assert(all([t["denominator"] != 0 for t in transform]))
+
+ # Color correction should not match the manual settings.
+ assert(any([not is_close_float(gains[i], manual_gains[i])
+ for i in xrange(4)]))
+ assert(any([not is_close_rational(transform[i], manual_transform[i])
+ for i in xrange(9)]))
+
+ # Exposure time must be valid.
+ assert(exp_time > 0)
+
+ # Lens shading map must be valid.
+ assert(w_map > 0 and h_map > 0 and w_map * h_map * 4 == len(lsc_map))
+ assert(all([m >= 1 for m in lsc_map]))
+
+ draw_lsc_plot(w_map, h_map, lsc_map, "auto")
+
+ return lsc_map
+
+def test_manual(cam, w_map, h_map, lsc_map_auto):
+ cap = cam.do_capture(manual_req)
+ cap_res = cap["metadata"]
+
+ gains = cap_res["android.colorCorrection.gains"]
+ transform = cap_res["android.colorCorrection.transform"]
+ curves = [cap_res["android.tonemap.curveRed"],
+ cap_res["android.tonemap.curveGreen"],
+ cap_res["android.tonemap.curveBlue"]]
+ exp_time = cap_res['android.sensor.exposureTime']
+ lsc_map = cap_res["android.statistics.lensShadingMap"]
+ ctrl_mode = cap_res["android.control.mode"]
+
+ print "Control mode:", ctrl_mode
+ print "Gains:", gains
+ print "Transform:", [its.objects.rational_to_float(t)
+ for t in transform]
+ print "Tonemap:", curves[0][1::16]
+ print "AE region:", cap_res['android.control.aeRegions']
+ print "AF region:", cap_res['android.control.afRegions']
+ print "AWB region:", cap_res['android.control.awbRegions']
+ print "LSC map:", w_map, h_map, lsc_map[:8]
+
+ assert(ctrl_mode == 0)
+
+ # Color correction gain and transform must be valid.
+ # Color correction gains and transform should be the same size and
+ # values as the manually set values.
+ assert(len(gains) == 4)
+ assert(len(transform) == 9)
+ assert( all([is_close_float(gains[i], manual_gains_ok[0][i])
+ for i in xrange(4)]) or
+ all([is_close_float(gains[i], manual_gains_ok[1][i])
+ for i in xrange(4)]) or
+ all([is_close_float(gains[i], manual_gains_ok[2][i])
+ for i in xrange(4)]))
+ assert(all([is_close_rational(transform[i], manual_transform[i])
+ for i in xrange(9)]))
+
+ # Tonemap must be valid.
+ # The returned tonemap must be linear.
+ for c in curves:
+ assert(len(c) > 0)
+ assert(all([is_close_float(c[i], c[i+1])
+ for i in xrange(0,len(c),2)]))
+
+ # Exposure time must be close to the requested exposure time.
+ assert(is_close_float(exp_time/1000000.0, manual_exp_time/1000000.0))
+
+ # Lens shading map must be valid.
+ assert(w_map > 0 and h_map > 0 and w_map * h_map * 4 == len(lsc_map))
+ assert(all([m >= 1 for m in lsc_map]))
+
+ draw_lsc_plot(w_map, h_map, lsc_map, "manual")
+
if __name__ == '__main__':
main()
diff --git a/apps/CameraITS/tests/scene1/test_crop_regions.py b/apps/CameraITS/tests/scene1/test_crop_regions.py
index d0cd70a..eee9d4a 100644
--- a/apps/CameraITS/tests/scene1/test_crop_regions.py
+++ b/apps/CameraITS/tests/scene1/test_crop_regions.py
@@ -23,9 +23,6 @@ import matplotlib.pyplot
import copy
import numpy
-# TODO: Fix this test. Currently assumes a non-supported output size in the
-# HAL-cropped images.
-
def main():
"""Test that crop regions work.
"""
@@ -47,6 +44,9 @@ def main():
e, s = its.target.get_target_exposure_combos(cam)["minSensitivity"]
print "Active sensor region (%d,%d %dx%d)" % (ax, ay, aw, ah)
+ # Uses a 2x digital zoom.
+ assert(props['android.scaler.availableMaxDigitalZoom'] >= 2)
+
# Capture a full frame.
req = its.objects.manual_capture_request(s,e)
cap_full = cam.do_capture(req)
@@ -55,9 +55,9 @@ def main():
wfull, hfull = cap_full["width"], cap_full["height"]
# Capture a burst of crop region frames.
- # Each is captured into an image 1/2x1/2 the size, which should allow
- # these crop images to be compared with 1/2x1/2 regions that are
- # cropped from the full frame.
+ # Note that each region is 1/2x1/2 of the full frame, and is digitally
+ # zoomed into the full size output image, so must be downscaled (below)
+ # by 2x when compared to a tile of the full image.
reqs = []
for x,y,w,h in REGIONS:
req = its.objects.manual_capture_request(s,e)
@@ -67,8 +67,7 @@ def main():
"right": int(ax + aw * (x + w)),
"bottom": int(ay + ah * (y + h))}
reqs.append(req)
- fmt = {"format":"yuv", "width":wfull/2, "height":hfull/2}
- caps_regions = cam.do_capture(reqs, fmt)
+ caps_regions = cam.do_capture(reqs)
match_failed = False
for i,cap in enumerate(caps_regions):
a = cap["metadata"]["android.scaler.cropRegion"]
@@ -79,6 +78,7 @@ def main():
# the full image, to find the best match (which should be
# the region that corresponds to this crop image).
img_crop = its.image.convert_capture_to_rgb_image(cap)
+ img_crop = its.image.downscale_image(img_crop, 2)
its.image.write_image(img_crop, "%s_crop%d.jpg" % (NAME, i))
min_diff = None
min_diff_region = None
diff --git a/apps/CameraITS/tests/scene1/test_raw_sensitivity.py b/apps/CameraITS/tests/scene1/test_raw_sensitivity.py
index c53dc01..9845623 100644
--- a/apps/CameraITS/tests/scene1/test_raw_sensitivity.py
+++ b/apps/CameraITS/tests/scene1/test_raw_sensitivity.py
@@ -48,7 +48,7 @@ def main():
e = int(s_e_prod / float(s))
req = its.objects.manual_capture_request(s, e)
- # TODO: Capture using raw-only, once it works reliably.
+ # Capture raw+yuv, but only look at the raw.
cap,_ = cam.do_capture(req, cam.CAP_RAW_YUV)
# Measure the variance. Each shot should be noisier than the
diff --git a/apps/CameraITS/tests/scene1/test_formats.py b/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py
index 402a3e2..aed9b66 100644
--- a/apps/CameraITS/tests/scene1/test_formats.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py
@@ -25,8 +25,7 @@ def main():
"""
NAME = os.path.basename(__file__).split(".")[0]
- # TODO: Look into why some of the RMS diffs are higher in this test.
- THRESHOLD_MAX_RMS_DIFF = 0.1
+ THRESHOLD_MAX_RMS_DIFF = 0.03
with its.device.ItsSession() as cam:
props = cam.get_camera_properties()