Ruben Brunk | 370e243 | 2014-10-14 18:33:23 -0700 | [diff] [blame] | 1 | # Copyright 2014 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 | |
| 15 | import its.image |
| 16 | import its.caps |
| 17 | import its.device |
| 18 | import its.objects |
| 19 | import os.path |
| 20 | import numpy |
| 21 | |
| 22 | def main(): |
| 23 | """Take long bursts of images and check that they're all identical. |
| 24 | |
| 25 | Assumes a static scene. Can be used to idenfity if there are sporadic |
| 26 | frames that are processed differently or have artifacts, or if 3A isn't |
| 27 | stable, since this test converges 3A at the start but doesn't lock 3A |
| 28 | throughout capture. |
| 29 | """ |
| 30 | NAME = os.path.basename(__file__).split(".")[0] |
| 31 | |
| 32 | BURST_LEN = 50 |
| 33 | BURSTS = 5 |
| 34 | FRAMES = BURST_LEN * BURSTS |
| 35 | |
| 36 | SPREAD_THRESH = 0.03 |
| 37 | |
| 38 | with its.device.ItsSession() as cam: |
| 39 | |
| 40 | # Capture at the smallest resolution. |
| 41 | props = cam.get_camera_properties() |
Yin-Chia Yeh | 9c0d926 | 2015-04-03 17:02:13 -0700 | [diff] [blame] | 42 | its.caps.skip_unless(its.caps.manual_sensor(props) and |
| 43 | its.caps.awb_lock(props)) |
Ruben Brunk | 370e243 | 2014-10-14 18:33:23 -0700 | [diff] [blame] | 44 | |
| 45 | _, fmt = its.objects.get_fastest_manual_capture_settings(props) |
| 46 | w,h = fmt["width"], fmt["height"] |
| 47 | |
| 48 | # Converge 3A prior to capture. |
| 49 | cam.do_3a(lock_ae=True, lock_awb=True) |
| 50 | |
| 51 | # After 3A has converged, lock AE+AWB for the duration of the test. |
Unsuk Jung | ff9926e | 2015-09-12 19:50:47 +0000 | [diff] [blame] | 52 | req = its.objects.fastest_auto_capture_request(props) |
Ruben Brunk | 370e243 | 2014-10-14 18:33:23 -0700 | [diff] [blame] | 53 | req["android.blackLevel.lock"] = True |
| 54 | req["android.control.awbLock"] = True |
| 55 | req["android.control.aeLock"] = True |
| 56 | |
| 57 | # Capture bursts of YUV shots. |
| 58 | # Get the mean values of a center patch for each. |
| 59 | # Also build a 4D array, which is an array of all RGB images. |
| 60 | r_means = [] |
| 61 | g_means = [] |
| 62 | b_means = [] |
| 63 | imgs = numpy.empty([FRAMES,h,w,3]) |
| 64 | for j in range(BURSTS): |
| 65 | caps = cam.do_capture([req]*BURST_LEN, [fmt]) |
| 66 | for i,cap in enumerate(caps): |
| 67 | n = j*BURST_LEN + i |
| 68 | imgs[n] = its.image.convert_capture_to_rgb_image(cap) |
| 69 | tile = its.image.get_image_patch(imgs[n], 0.45, 0.45, 0.1, 0.1) |
| 70 | means = its.image.compute_image_means(tile) |
| 71 | r_means.append(means[0]) |
| 72 | g_means.append(means[1]) |
| 73 | b_means.append(means[2]) |
| 74 | |
| 75 | # Dump all images. |
| 76 | print "Dumping images" |
| 77 | for i in range(FRAMES): |
| 78 | its.image.write_image(imgs[i], "%s_frame%03d.jpg"%(NAME,i)) |
| 79 | |
| 80 | # The mean image. |
| 81 | img_mean = imgs.mean(0) |
| 82 | its.image.write_image(img_mean, "%s_mean.jpg"%(NAME)) |
| 83 | |
| 84 | # Pass/fail based on center patch similarity. |
| 85 | for means in [r_means, g_means, b_means]: |
| 86 | spread = max(means) - min(means) |
| 87 | print spread |
| 88 | assert(spread < SPREAD_THRESH) |
| 89 | |
| 90 | if __name__ == '__main__': |
| 91 | main() |
| 92 | |