diff options
author | Timothy Knight <tknight@google.com> | 2014-07-30 19:30:04 -0700 |
---|---|---|
committer | Timothy Knight <tknight@google.com> | 2014-08-04 13:59:05 -0700 |
commit | 02fa436b99061db2a8772cc4625a81ddf7a332c8 (patch) | |
tree | aecdbc01dd2236d234282517ad5bd8e9d3e655a6 /apps | |
parent | a238520df755416ef6d9b9a4a3002f8a50ceaf80 (diff) | |
download | pdk-02fa436b99061db2a8772cc4625a81ddf7a332c8.tar.gz |
CameraITS: Some fixes in the DNG noise model generation script.
Change-Id: Ic269b70b5dad6ca34ec73d7b9986159f3981202f
Diffstat (limited to 'apps')
-rw-r--r-- | apps/CameraITS/pymodules/its/image.py | 67 | ||||
-rw-r--r-- | apps/CameraITS/tools/compute_dng_noise_model.py | 47 |
2 files changed, 54 insertions, 60 deletions
diff --git a/apps/CameraITS/pymodules/its/image.py b/apps/CameraITS/pymodules/its/image.py index 1ff41a3..9c82141 100644 --- a/apps/CameraITS/pymodules/its/image.py +++ b/apps/CameraITS/pymodules/its/image.py @@ -584,12 +584,8 @@ def get_color_checker_chart_patches(img, debug_fname_prefix=None): successfully. Returns: - Three tuples: - (1) The integer (x,y) coords of the center of the chart's patch (0,0). - (2) The float (dx,dy) displacement to the chart's (0,1) patch, which - is the pink patch to the right of the top-left brown patch. - (3) The float (dx,dt) displacement to the chart's (1,0) patch, which - is the orange patch below the top-left brown patch. + 6x4 list of lists of integer (x,y) coords of the center of each patch, + ordered in the "chart order" (6x4 row major). """ # Shrink the original image. @@ -674,43 +670,42 @@ def get_color_checker_chart_patches(img, debug_fname_prefix=None): vec_across = tuple([(next_center[i]-origin_center[i])/5.0 for i in [0,1]]) vec_down = tuple([(prev_center[i]-origin_center[i])/3.0 for i in [0,1]]) + # Compute the center of each patch. + patches = [[],[],[],[]] + for yi in range(4): + for xi in range(6): + x0,y0 = origin_center + dxh,dyh = vec_across + dxv,dyv = vec_down + xc = int(x0 + dxh*xi + dxv*yi) + yc = int(y0 + dyh*xi + dyv*yi) + patches[yi].append((xc,yc)) + # Sanity check: test that the R,G,B,black,white patches are correct. - patch_info = [("r",2,2), ("g",2,1), ("b",2,0), ("w",3,0), ("k",3,5)] + patch_info = [(2,2,[0]), # Red + (2,1,[1]), # Green + (2,0,[2]), # Blue + (3,0,[0,1,2]), # White + (3,5,[])] # Black for i in range(len(patch_info)): - color,yi,xi = patch_info[i] - xc = int(origin_center[0] + vec_across[0]*xi + vec_down[0]*yi) - yc = int(origin_center[1] + vec_across[1]*xi + vec_down[1]*yi) + yi,xi,high_chans = patch_info[i] + low_chans = [i for i in [0,1,2] if i not in high_chans] + xc,yc = patches[yi][xi] means = __measure_color_checker_patch(img, xc,yc, 64) - if color == "r": - high_chans = [0] - low_chans = [1,2] - elif color == "g": - high_chans = [1] - low_chans = [0,2] - elif color == "b": - high_chans = [2] - low_chans = [0,1] - elif color == "w": - high_chans = [0,1,2] - low_chans = [] - elif color == "k": - high_chans = [] - low_chans = [0,1,2] - else: - assert(False) - - # If the debug info is requested, then don't assert that the patches - # are matched, to allow the caller to see the output. - if debug_fname_prefix is not None: - img[int(yc),int(xc)] = 1.0 - else: - assert(min([means[i] for i in high_chans]+[1]) > \ - max([means[i] for i in low_chans]+[0])) + if (min([means[i] for i in high_chans]+[1]) < \ + max([means[i] for i in low_chans]+[0])): + print "Color patch sanity check failed: patch", i + # If the debug info is requested, then don't assert that the patches + # are matched, to allow the caller to see the output. + if debug_fname_prefix is None: + assert(0) if debug_fname_prefix is not None: + for (xc,yc) in sum(patches,[]): + img[yc,xc] = 1.0 write_image(img, debug_fname_prefix+"_2.jpg") - return origin_center, vec_across, vec_down + return patches class __UnitTest(unittest.TestCase): """Run a suite of unit tests on this module. diff --git a/apps/CameraITS/tools/compute_dng_noise_model.py b/apps/CameraITS/tools/compute_dng_noise_model.py index 39c890a..aff71c6 100644 --- a/apps/CameraITS/tools/compute_dng_noise_model.py +++ b/apps/CameraITS/tools/compute_dng_noise_model.py @@ -64,18 +64,14 @@ def main(): caps = cam.do_capture(reqs, cam.CAP_RAW) - # A list of the (x,y) coords of the top-left pixel of a collection of - # 64x64 pixel patches of a color checker chart. Each patch should be - # uniform, however the actual color doesn't matter. + # A list of the (x,y) coords of the center pixel of a collection of + # patches of a color checker chart. Each patch should be uniform, + # however the actual color doesn't matter. Note that the coords are + # relative to the *converted* RGB image, which is 1/2 x 1/2 of the + # full size; convert back to full. img = its.image.convert_capture_to_rgb_image(caps[0], props=props) - (x0,y0),(dxh,dyh),(dxv,dyv) = \ - its.image.get_color_checker_chart_patches(img, NAME+"_debug") - patches = [] - for xi in range(6): - for yi in range(4): - xc = int(x0 + dxh*xi + dxv*yi) - yc = int(y0 + dyh*xi + dyv*yi) - patches.append((xc-32,yc-32)) + patches = its.image.get_color_checker_chart_patches(img, NAME+"_debug") + patches = [(2*x,2*y) for (x,y) in sum(patches,[])] lines = [] for (s,cap) in zip(sens,caps): @@ -88,8 +84,8 @@ def main(): for i,plane in enumerate(planes): plane = (plane * white_level - black_levels[i]) / ( white_level - black_levels[i]) - for (x,y) in patches: - tile = plane[y/2:y/2+32,x/2:x/2+32,:] + for j,(x,y) in enumerate(patches): + tile = plane[y/2-16:y/2+16:,x/2-16:x/2+16:,::] mean = its.image.compute_image_means(tile)[0] var = its.image.compute_image_variances(tile)[0] if (mean > CLAMP_THRESH and mean < 1.0-CLAMP_THRESH): @@ -110,6 +106,7 @@ def main(): lines.append((s,m,b)) print s, "->", m, b + # TODO: Clean up these checks (which currently fail in some cases). # Some sanity checks: # * Noise levels should increase with brightness. # * Extrapolating to a black image, the noise should be positive. @@ -147,28 +144,30 @@ def main(): */ #include <stdio.h> #include <assert.h> - void compute_noise_model_entries(int sens, double *o, double *s); + double compute_noise_model_entry_S(int sens); + double compute_noise_model_entry_O(int sens); int main(void) { int sens; - double o, s; for (sens = %d; sens <= %d; sens += 100) { - compute_noise_model_entries(sens, &o, &s); + double o = compute_noise_model_entry_O(sens); + double s = compute_noise_model_entry_S(sens); printf("%%d,%%lf,%%lf\\n", sens, o, s); } return 0; } - /* Generated function to map a given sensitivity to the O and S noise + /* Generated functions to map a given sensitivity to the O and S noise * model parameters in the DNG noise model. */ - void compute_noise_model_entries(int sens, double *o, double *s) { - assert(sens >= %d && sens <= %d && o && s); - *s = %e * sens + %e; - *o = %e * sens + %e; - *s = *s < 0.0 ? 0.0 : *s; - *o = *o < 0.0 ? 0.0 : *o; + double compute_noise_model_entry_S(int sens) { + double s = %e * sens + %e; + return s < 0.0 ? 0.0 : s; } - """%(sens_min,sens_max,sens_min,sens_max,mS,bS,mO,bO) + double compute_noise_model_entry_O(int sens) { + double o = %e * sens + %e; + return o < 0.0 ? 0.0 : o; + } + """%(sens_min,sens_max,mS,bS,mO,bO) if __name__ == '__main__': main() |