CameraITS: Cleaned up and documented script to generate DNG noise model
Bug: 18400529
Change-Id: I749c62c3ffff916d61a2b459959d1f5b5ccf005e
diff --git a/apps/CameraITS/pymodules/its/image.py b/apps/CameraITS/pymodules/its/image.py
index e2d521a..b3bdb65 100644
--- a/apps/CameraITS/pymodules/its/image.py
+++ b/apps/CameraITS/pymodules/its/image.py
@@ -540,9 +540,13 @@
img = numpy.vstack(chs).T.reshape(h/f,w/f,chans)
return img
-def __measure_color_checker_patch(img, xc,yc, patch_size):
+def __get_color_checker_patch(img, xc,yc, patch_size):
r = patch_size/2
- tile = img[yc-r:yc+r+1:, xc-r:xc+r+1:, ::]
+ tile = img[yc-r:yc+r:, xc-r:xc+r:, ::]
+ return tile
+
+def __measure_color_checker_patch(img, xc,yc, patch_size):
+ tile = __get_color_checker_patch(img, xc,yc, patch_size)
means = tile.mean(1).mean(0)
return means
@@ -570,10 +574,7 @@
debug_fname_prefix: If not None, the (string) name of a file prefix to
use to save a number of debug images for visualizing the output of
this function; can be used to see if the patches are being found
- successfully. If this argument is provided, then some of the sanity
- check assertions will be disabled to allow the function to provide
- useful debugging information, meaning that garbage data may be
- returned.
+ successfully.
Returns:
6x4 list of lists of integer (x,y) coords of the center of each patch,
@@ -674,6 +675,7 @@
patches[yi].append((xc,yc))
# Sanity check: test that the R,G,B,black,white patches are correct.
+ sanity_failed = False
patch_info = [(2,2,[0]), # Red
(2,1,[1]), # Green
(2,0,[2]), # Blue
@@ -686,16 +688,19 @@
means = __measure_color_checker_patch(img, xc,yc, 64)
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)
+ sanity_failed = True
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")
+ gridimg = numpy.zeros([4*(32+2), 6*(32+2), 3])
+ for yi in range(4):
+ for xi in range(6):
+ xc,yc = patches[yi][xi]
+ tile = __get_color_checker_patch(img, xc,yc, 32)
+ gridimg[yi*(32+2)+1:yi*(32+2)+1+32,
+ xi*(32+2)+1:xi*(32+2)+1+32, :] = tile
+ write_image(gridimg, debug_fname_prefix+"_2.png")
+
+ assert(not sanity_failed)
return patches
diff --git a/apps/CameraITS/tests/dng_noise_model/DngNoiseModel.pdf b/apps/CameraITS/tests/dng_noise_model/DngNoiseModel.pdf
new file mode 100644
index 0000000..4aa4b7f
--- /dev/null
+++ b/apps/CameraITS/tests/dng_noise_model/DngNoiseModel.pdf
Binary files differ
diff --git a/apps/CameraITS/tools/compute_dng_noise_model.py b/apps/CameraITS/tests/dng_noise_model/dng_noise_model.py
similarity index 86%
rename from apps/CameraITS/tools/compute_dng_noise_model.py
rename to apps/CameraITS/tests/dng_noise_model/dng_noise_model.py
index 1b57754..19b6c92 100644
--- a/apps/CameraITS/tools/compute_dng_noise_model.py
+++ b/apps/CameraITS/tests/dng_noise_model/dng_noise_model.py
@@ -50,7 +50,7 @@
s_e_prod *= 2
# Capture raw frames across the full sensitivity range.
- NUM_SENS_STEPS = 15
+ NUM_SENS_STEPS = 9
sens_step = int((sens_max - sens_min - 1) / float(NUM_SENS_STEPS))
reqs = []
sens = []
@@ -75,7 +75,7 @@
patches = [(2*x,2*y) for (x,y) in sum(patches,[])]
lines = []
- for (s,cap) in zip(sens,caps):
+ for iouter, (s,cap) in enumerate(zip(sens,caps)):
# For each capture, compute the mean value in each patch, for each
# Bayer plane; discard patches where pixels are close to clamped.
# Also compute the variance.
@@ -117,10 +117,17 @@
#assert(m > 0)
#assert(b >= 0)
- # Draw a plot.
- pylab.plot(xs, ys, 'r')
- pylab.plot([0,xs[-1]],[b,m*xs[-1]+b],'b')
- matplotlib.pyplot.savefig("%s_plot_mean_vs_variance.png" % (NAME))
+ if iouter == 0:
+ pylab.plot(xs, ys, 'r', label="Measured")
+ pylab.plot([0,xs[-1]],[b,m*xs[-1]+b],'b', label="Fit")
+ else:
+ pylab.plot(xs, ys, 'r')
+ pylab.plot([0,xs[-1]],[b,m*xs[-1]+b],'b')
+
+ pylab.xlabel("Mean")
+ pylab.ylabel("Variance")
+ pylab.legend()
+ matplotlib.pyplot.savefig("%s_plot_mean_vs_variance.png" % (NAME))
# Now fit a line across the (m,b) line parameters for each sensitivity.
# The gradient (m) params are fit to the "S" line, and the offset (b)
@@ -132,11 +139,16 @@
mO,bO = numpy.polyfit(gains, Os, 1)
# Plot curve "O" as 10x, so it fits in the same scale as curve "S".
- pylab.plot(gains, [10*o for o in Os], 'r')
+ fig = matplotlib.pyplot.figure()
+ pylab.plot(gains, [10*o for o in Os], 'r', label="Measured")
pylab.plot([gains[0],gains[-1]],
- [10*mO*gains[0]+10*bO, 10*mO*gains[-1]+10*bO], 'b')
- pylab.plot(gains, Ss, 'r')
- pylab.plot([gains[0],gains[-1]], [mS*gains[0]+bS, mS*gains[-1]+bS], 'b')
+ [10*mO*gains[0]+10*bO, 10*mO*gains[-1]+10*bO],'r--',label="Fit")
+ pylab.plot(gains, Ss, 'b', label="Measured")
+ pylab.plot([gains[0],gains[-1]], [mS*gains[0]+bS,mS*gains[-1]+bS],'b--',
+ label="Fit")
+ pylab.xlabel("Sensitivity")
+ pylab.ylabel("Model parameter: S (blue), O x10 (red)")
+ pylab.legend()
matplotlib.pyplot.savefig("%s_plot_S_O.png" % (NAME))
print """