def _masked_predictions(
        self, x_i: np.ndarray, batch_size: int = 128, **kwargs
    ) -> tuple[dict[str, np.ndarray], dict[str, np.ndarray]]:
        """
        Create masked copies of the image for each of lines following the ObjectSeeker algorithm. Then creates
        predictions on the base unmasked image and each of the masked image.

        :param x_i: A single image of shape CHW or HWC.
        :param batch_size: Batch size.
        :return: Predictions for the base unmasked image and merged predictions for the masked image.
        """
        x_mask = np.repeat(x_i[np.newaxis], self.num_lines * 4 + 1, axis=0)

        if self.channels_first:
            height = self.input_shape[1]
            width = self.input_shape[2]
        else:
            height = self.input_shape[0]
            width = self.input_shape[1]
            x_mask = np.transpose(x_mask, (0, 3, 1, 2))

        idx = 1

        # Left masks
        for k in range(1, self.num_lines + 1):
            boundary = int(width / (self.num_lines + 1) * k)
            x_mask[idx, :, :, :boundary] = 0
            idx += 1

        # Right masks
        for k in range(1, self.num_lines + 1):
            boundary = width - int(width / (self.num_lines + 1) * k)
            x_mask[idx, :, :, boundary:] = 0
            idx += 1

        # Top masks
        for k in range(1, self.num_lines + 1):
            boundary = int(height / (self.num_lines + 1) * k)
            x_mask[idx, :, :boundary, :] = 0
            idx += 1

        # Bottom masks
        for k in range(1, self.num_lines + 1):
            boundary = height - int(height / (self.num_lines + 1) * k)
            x_mask[idx, :, boundary:, :] = 0
            idx += 1

        if not self.channels_first:
            x_mask = np.transpose(x_mask, (0, 2, 3, 1))

        predictions = self.detector.predict(x=x_mask, batch_size=batch_size, **kwargs)
        filtered_predictions = [
            non_maximum_suppression(
                pred, iou_threshold=self.iou_threshold, confidence_threshold=self.confidence_threshold
            )
            for pred in predictions
        ]

        # Extract base predictions
        base_predictions = filtered_predictions[0]

        # Extract and merge masked predictions
        boxes = np.concatenate([pred["boxes"] for pred in filtered_predictions[1:]])
        labels = np.concatenate([pred["labels"] for pred in filtered_predictions[1:]])
        scores = np.concatenate([pred["scores"] for pred in filtered_predictions[1:]])
        merged_predictions = {
            "boxes": boxes,
            "labels": labels,
            "scores": scores,
        }
        masked_predictions = non_maximum_suppression(
            merged_predictions, iou_threshold=self.iou_threshold, confidence_threshold=self.confidence_threshold
        )

        return base_predictions, masked_predictions

        Create masked copies of the image for each of lines following the ObjectSeeker algorithm. Then creates
        predictions on the base unmasked image and each of the masked image.

        :param x_i: A single image of shape CHW or HWC.
        :param batch_size: Batch size.
        :return: Predictions for the base unmasked image and merged predictions for the masked image.
        
art/estimators/certification/object_seeker/pytorch.py