1234def _operate_on_images(image1: Image, image2: Image | ScalarLike, op: Callable) -> Image:
1235 """Perform an operation on two images, that may or may not be spectrally
1236 and spatially aligned.
1237
1238 Parameters
1239 ----------
1240 image1:
1241 The image on the LHS of the operation
1242 image2:
1243 The image on the RHS of the operation
1244 op:
1245 The operation used to combine the images.
1246
1247 Returns
1248 -------
1249 image:
1250 The resulting combined image.
1251 """
1252 if type(image2) in ScalarTypes:
1253 return image1.copy_with(data=op(image1.data, image2))
1254 image2 = cast(Image, image2)
1255 if image1.bands == image2.bands and image1.bbox == image2.bbox:
1256
1257 with np.errstate(divide="ignore", invalid="ignore"):
1258 result = op(image1.data, image2.data)
1259 return Image(result, bands=image1.bands, yx0=image1.yx0)
1260
1261 if op != operator.add and op != operator.sub and image1.bands != image2.bands:
1262 msg = "Images with different bands can only be combined using addition and subtraction, "
1263 msg += f"got {op}, with bands {image1.bands}, {image2.bands}"
1264 raise ValueError(msg)
1265
1266
1267 bands = image1.bands
1268
1269 bands = bands + tuple(band for band in image2.bands if band not in bands)
1270
1271 bbox = image1.bbox | image2.bbox
1272
1273 if len(bands) > 0:
1274 shape = (len(bands),) + bbox.shape
1275 else:
1276 shape = bbox.shape
1277
1278 if op == operator.add or op == operator.sub:
1279 dtype = get_combined_dtype(image1, image2)
1280 result = Image(np.zeros(shape, dtype=dtype), bands=bands, yx0=cast(tuple[int, int], bbox.origin))
1281
1282 image1.insert_into(result, operator.add)
1283
1284 image2.insert_into(result, op)
1285 else:
1286
1287 image1 = image1.project(bbox=bbox)
1288 image2 = image2.project(bbox=bbox)
1289 result = op(image1, image2)
1290 return result
1291
1292