1286def _operate_on_images(image1: Image, image2: Image | ScalarLike, op: Callable) -> Image:
1287 """Perform an operation on two images, that may or may not be spectrally
1288 and spatially aligned.
1289
1290 Parameters
1291 ----------
1292 image1:
1293 The image on the LHS of the operation
1294 image2:
1295 The image on the RHS of the operation
1296 op:
1297 The operation used to combine the images.
1298
1299 Returns
1300 -------
1301 image:
1302 The resulting combined image.
1303 """
1304 if type(image2) in ScalarTypes:
1305 return image1.copy_with(data=op(image1.data, image2))
1306 image2 = cast(Image, image2)
1307 if image1.bands == image2.bands and image1.bbox == image2.bbox:
1308
1309 with np.errstate(divide="ignore", invalid="ignore"):
1310 result = op(image1.data, image2.data)
1311 return Image(result, bands=image1.bands, yx0=image1.yx0)
1312
1313 if op != operator.add and op != operator.sub and image1.bands != image2.bands:
1314 msg = "Images with different bands can only be combined using addition and subtraction, "
1315 msg += f"got {op}, with bands {image1.bands}, {image2.bands}"
1316 raise ValueError(msg)
1317
1318
1319 bands = image1.bands
1320
1321 bands = bands + tuple(band for band in image2.bands if band not in bands)
1322
1323 bbox = image1.bbox | image2.bbox
1324
1325 if len(bands) > 0:
1326 shape = (len(bands),) + bbox.shape
1327 else:
1328 shape = bbox.shape
1329
1330 if op == operator.add or op == operator.sub:
1331 dtype = get_combined_dtype(image1, image2)
1332 result =
Image(np.zeros(shape, dtype=dtype), bands=bands, yx0=cast(tuple[int, int], bbox.origin))
1333
1334 image1.insert_into(result, operator.add)
1335
1336 image2.insert_into(result, op)
1337 else:
1338
1339 image1 = image1.project(bbox=bbox)
1340 image2 = image2.project(bbox=bbox)
1341 result = op(image1, image2)
1342 return result
1343
1344