utils: raspberrypi: ctt: Fix NaNs in chromatic aberration tables

NaNs can appear if no black dots can be found and analysed in a
particular region of the calibration image. There needs to be at least
one such dot in every 8x8 cell covering the image.

This is now detected, and an error message issued. No CAC tables are
generated, so CAC is disabled.

Bug: https://github.com/raspberrypi/libcamera/issues/254
Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
Reviewed-by: Naushir Patuck <naush@raspberrypi.com>
Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
David Plowman 2025-04-28 11:36:04 +01:00 committed by Kieran Bingham
parent 36ba0e5515
commit 17e41b2a3a
2 changed files with 33 additions and 8 deletions

View file

@ -198,9 +198,12 @@ class Camera:
""" """
Write output to json Write output to json
""" """
self.json['rpi.cac']['cac'] = cacs if cacs:
self.log += '\nCAC calibration written to json file' self.json['rpi.cac']['cac'] = cacs
print('Finished CAC calibration') self.log += '\nCAC calibration written to json file'
print('Finished CAC calibration')
else:
self.log += "\nCAC calibration failed"
""" """

View file

@ -108,12 +108,29 @@ def shifts_to_yaml(red_shift, blue_shift, image_dimensions, output_grid_size=9):
ybsgrid[xgridloc][ygridloc].append(blue_shift[3]) ybsgrid[xgridloc][ygridloc].append(blue_shift[3])
# Now calculate the average pixel shift for each square in the grid # Now calculate the average pixel shift for each square in the grid
grid_incomplete = False
for x in range(output_grid_size - 1): for x in range(output_grid_size - 1):
for y in range(output_grid_size - 1): for y in range(output_grid_size - 1):
xrgrid[x, y] = np.mean(xrsgrid[x][y]) if xrsgrid[x][y]:
yrgrid[x, y] = np.mean(yrsgrid[x][y]) xrgrid[x, y] = np.mean(xrsgrid[x][y])
xbgrid[x, y] = np.mean(xbsgrid[x][y]) else:
ybgrid[x, y] = np.mean(ybsgrid[x][y]) grid_incomplete = True
if yrsgrid[x][y]:
yrgrid[x, y] = np.mean(yrsgrid[x][y])
else:
grid_incomplete = True
if xbsgrid[x][y]:
xbgrid[x, y] = np.mean(xbsgrid[x][y])
else:
grid_incomplete = True
if ybsgrid[x][y]:
ybgrid[x, y] = np.mean(ybsgrid[x][y])
else:
grid_incomplete = True
if grid_incomplete:
raise RuntimeError("\nERROR: CAC measurements do not span the image!"
"\nConsider using improved CAC images, or remove them entirely.\n")
# Next, we start to interpolate the central points of the grid that gets passed to the tuning file # Next, we start to interpolate the central points of the grid that gets passed to the tuning file
input_grids = np.array([xrgrid, yrgrid, xbgrid, ybgrid]) input_grids = np.array([xrgrid, yrgrid, xbgrid, ybgrid])
@ -219,7 +236,12 @@ def cac(Cam):
# tuning file # tuning file
print("\nCreating output grid") print("\nCreating output grid")
Cam.log += '\nCreating output grid' Cam.log += '\nCreating output grid'
rx, ry, bx, by = shifts_to_yaml(red_shift, blue_shift, image_size) try:
rx, ry, bx, by = shifts_to_yaml(red_shift, blue_shift, image_size)
except RuntimeError as e:
print(str(e))
Cam.log += "\nCAC correction failed! CAC will not be enabled."
return {}
print("CAC correction complete!") print("CAC correction complete!")
Cam.log += '\nCAC correction complete!' Cam.log += '\nCAC correction complete!'