Clemenz Portmann | ac8a085 | 2017-11-30 16:54:28 -0800 | [diff] [blame] | 1 | # Copyright 2018 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 os.path |
| 16 | |
| 17 | import its.caps |
| 18 | import its.device |
| 19 | import its.image |
| 20 | import its.objects |
| 21 | import its.target |
| 22 | |
| 23 | import numpy as np |
| 24 | NAME = os.path.basename(__file__).split('.')[0] |
Clemenz Portmann | 8156814 | 2018-05-16 13:12:50 -0700 | [diff] [blame] | 25 | PATCH_SIZE = 0.0625 # 1/16 x 1/16 in center of image |
| 26 | PATCH_LOC = (1-PATCH_SIZE)/2 |
| 27 | THRESH_DIFF = 0.06 |
Clemenz Portmann | ac8a085 | 2017-11-30 16:54:28 -0800 | [diff] [blame] | 28 | THRESH_GAIN = 0.1 |
| 29 | THRESH_EXP = 0.05 |
| 30 | |
| 31 | |
| 32 | def main(): |
| 33 | """Test both cameras give similar RBG values for gray patch.""" |
| 34 | |
| 35 | yuv_sizes = {} |
| 36 | with its.device.ItsSession() as cam: |
| 37 | props = cam.get_camera_properties() |
Clemenz Portmann | 9d1f0d3 | 2018-09-25 17:50:23 -0700 | [diff] [blame] | 38 | its.caps.skip_unless(its.caps.per_frame_control(props) and |
Clemenz Portmann | 9d1f0d3 | 2018-09-25 17:50:23 -0700 | [diff] [blame] | 39 | its.caps.logical_multi_camera(props)) |
Clemenz Portmann | ac8a085 | 2017-11-30 16:54:28 -0800 | [diff] [blame] | 40 | ids = its.caps.logical_multi_camera_physical_ids(props) |
Clemenz Portmann | ac8a085 | 2017-11-30 16:54:28 -0800 | [diff] [blame] | 41 | for i in ids: |
| 42 | physical_props = cam.get_camera_properties_by_id(i) |
Clemenz Portmann | 32754b7 | 2018-07-10 11:47:01 -0700 | [diff] [blame] | 43 | its.caps.skip_unless(not its.caps.mono_camera(physical_props)) |
Takumi Yoshida | 83a9e73 | 2020-04-17 20:27:48 +0900 | [diff] [blame] | 44 | its.caps.skip_unless(its.caps.backward_compatible(physical_props)) |
Clemenz Portmann | ac8a085 | 2017-11-30 16:54:28 -0800 | [diff] [blame] | 45 | yuv_sizes[i] = its.objects.get_available_output_sizes( |
Clemenz Portmann | 642ed5f | 2019-03-13 17:13:09 -0700 | [diff] [blame] | 46 | 'yuv', physical_props) |
| 47 | if i == ids[0]: # get_available_output_sizes returns sorted list |
Clemenz Portmann | ac8a085 | 2017-11-30 16:54:28 -0800 | [diff] [blame] | 48 | yuv_match_sizes = yuv_sizes[i] |
| 49 | else: |
| 50 | list(set(yuv_sizes[i]).intersection(yuv_match_sizes)) |
Clemenz Portmann | 32754b7 | 2018-07-10 11:47:01 -0700 | [diff] [blame] | 51 | |
| 52 | # find matched size for captures |
Clemenz Portmann | ac8a085 | 2017-11-30 16:54:28 -0800 | [diff] [blame] | 53 | yuv_match_sizes.sort() |
| 54 | w = yuv_match_sizes[-1][0] |
| 55 | h = yuv_match_sizes[-1][1] |
Clemenz Portmann | 32754b7 | 2018-07-10 11:47:01 -0700 | [diff] [blame] | 56 | print 'Matched YUV size: (%d, %d)' % (w, h) |
| 57 | |
| 58 | # do 3a and create requests |
Clemenz Portmann | ee5058b | 2019-03-27 16:47:26 -0700 | [diff] [blame] | 59 | avail_fls = sorted(props['android.lens.info.availableFocalLengths'], |
| 60 | reverse=True) |
Clemenz Portmann | 32754b7 | 2018-07-10 11:47:01 -0700 | [diff] [blame] | 61 | cam.do_3a() |
| 62 | reqs = [] |
| 63 | for i, fl in enumerate(avail_fls): |
| 64 | reqs.append(its.objects.auto_capture_request()) |
| 65 | reqs[i]['android.lens.focalLength'] = fl |
Clemenz Portmann | ee5058b | 2019-03-27 16:47:26 -0700 | [diff] [blame] | 66 | if i > 0: |
| 67 | # Calculate the active sensor region for a non-cropped image |
| 68 | zoom = avail_fls[0] / fl |
| 69 | a = props['android.sensor.info.activeArraySize'] |
| 70 | ax, ay = a['left'], a['top'] |
| 71 | aw, ah = a['right'] - a['left'], a['bottom'] - a['top'] |
| 72 | |
| 73 | # Calculate a center crop region. |
| 74 | assert zoom >= 1 |
| 75 | cropw = aw / zoom |
| 76 | croph = ah / zoom |
| 77 | crop_region = { |
| 78 | 'left': aw / 2 - cropw / 2, |
| 79 | 'top': ah / 2 - croph / 2, |
| 80 | 'right': aw / 2 + cropw / 2, |
| 81 | 'bottom': ah / 2 + croph / 2 |
| 82 | } |
| 83 | reqs[i]['android.scaler.cropRegion'] = crop_region |
Clemenz Portmann | ac8a085 | 2017-11-30 16:54:28 -0800 | [diff] [blame] | 84 | |
| 85 | # capture YUVs |
Clemenz Portmann | 32754b7 | 2018-07-10 11:47:01 -0700 | [diff] [blame] | 86 | y_means = {} |
| 87 | msg = '' |
| 88 | fmt = [{'format': 'yuv', 'width': w, 'height': h}] |
| 89 | caps = cam.do_capture(reqs, fmt) |
Clemenz Portmann | 7b8ab0b | 2019-03-27 14:11:16 -0700 | [diff] [blame] | 90 | if not isinstance(caps, list): |
| 91 | caps = [caps] # handle canonical case where caps is not list |
Clemenz Portmann | ac8a085 | 2017-11-30 16:54:28 -0800 | [diff] [blame] | 92 | |
Clemenz Portmann | 32754b7 | 2018-07-10 11:47:01 -0700 | [diff] [blame] | 93 | for i, fl in enumerate(avail_fls): |
| 94 | img = its.image.convert_capture_to_rgb_image(caps[i], props=props) |
| 95 | its.image.write_image(img, '%s_yuv_fl=%s.jpg' % (NAME, fl)) |
| 96 | y, _, _ = its.image.convert_capture_to_planes(caps[i], props=props) |
| 97 | y_mean = its.image.compute_image_means( |
| 98 | its.image.get_image_patch(y, PATCH_LOC, PATCH_LOC, |
| 99 | PATCH_SIZE, PATCH_SIZE))[0] |
| 100 | print 'y[%s]: %.3f' % (fl, y_mean) |
| 101 | msg += 'y[%s]: %.3f, ' % (fl, y_mean) |
| 102 | y_means[fl] = y_mean |
Clemenz Portmann | ac8a085 | 2017-11-30 16:54:28 -0800 | [diff] [blame] | 103 | |
Clemenz Portmann | ac8a085 | 2017-11-30 16:54:28 -0800 | [diff] [blame] | 104 | # compare YUVs |
Clemenz Portmann | 32754b7 | 2018-07-10 11:47:01 -0700 | [diff] [blame] | 105 | msg += 'TOL=%.5f' % THRESH_DIFF |
| 106 | assert np.isclose(max(y_means.values()), min(y_means.values()), |
| 107 | rtol=THRESH_DIFF), msg |
Clemenz Portmann | ac8a085 | 2017-11-30 16:54:28 -0800 | [diff] [blame] | 108 | |
| 109 | |
| 110 | if __name__ == '__main__': |
| 111 | main() |