Yalantis/uCrop · error · CImgArgumentException

matchpatch(): Instance image and specified patch image (%u,%

Error message

matchpatch(): Instance image and specified patch image (%u,%u,%u,%u,%p) have different spectrums.

What it means

This is an internal overload of matchpatch() (patch matching) that scores patches from patch_image against the instance image. Both images must have the same number of channels (spectrum) because patch descriptors are compared channel-by-channel; a mismatch throws this CImgArgumentException, reporting the patch image's dimensions and data pointer.

Source

Thrown at ucrop/src/main/jni/CImg.h:46272

      CImg<T> matching_score;
      return _matchpatch(patch_image,patch_width,patch_height,patch_depth,
                         nb_iterations,nb_randoms,patch_penalization,guide,false,matching_score);
    }

    template<typename t1, typename t2>
    CImg<intT> _matchpatch(const CImg<T>& patch_image,
                           const unsigned int patch_width,
                           const unsigned int patch_height,
                           const unsigned int patch_depth,
                           const unsigned int nb_iterations,
                           const unsigned int nb_randoms,
                           const float patch_penalization,
                           const CImg<t1> &guide,
                           const bool is_matching_score,
                           CImg<t2> &matching_score) const {
      if (is_empty()) return CImg<intT>::const_empty();
      if (patch_image._spectrum!=_spectrum)
        throw CImgArgumentException(_cimg_instance
                                    "matchpatch(): Instance image and specified patch image (%u,%u,%u,%u,%p) "
                                    "have different spectrums.",
                                    cimg_instance,
                                    patch_image._width,patch_image._height,patch_image._depth,patch_image._spectrum,
                                    patch_image._data);
      if (patch_width>_width || patch_height>_height || patch_depth>_depth)
        throw CImgArgumentException(_cimg_instance
                                    "matchpatch(): Specified patch size %ux%ux%u is bigger than the dimensions "
                                    "of the instance image.",
                                    cimg_instance,patch_width,patch_height,patch_depth);
      if (patch_width>patch_image._width || patch_height>patch_image._height || patch_depth>patch_image._depth)
        throw CImgArgumentException(_cimg_instance
                                    "matchpatch(): Specified patch size %ux%ux%u is bigger than the dimensions "
                                    "of the patch image image (%u,%u,%u,%u,%p).",
                                    cimg_instance,patch_width,patch_height,patch_depth,
                                    patch_image._width,patch_image._height,patch_image._depth,patch_image._spectrum,
                                    patch_image._data);
      const unsigned int

View on GitHub (pinned to f788b534b4)

Solutions

  1. Match channel counts before calling: patch_image.resize(patch_image.width(),patch_image.height(),patch_image.depth(),_spectrum) or convert both to the same colorspace
  2. Convert both images to grayscale with get_norm() when color is irrelevant
  3. Guard with if (patch_image.spectrum() != img.spectrum()) and convert/abort explicitly
  4. Verify the loading pipeline so both images decode with the same channel count

Example fix

// before
CImg<unsigned char> matches = img.matchpatch(patches_gray, 7, 7, 1); // img is RGB
// after
CImg<unsigned char> matches =
  img.get_norm().matchpatch(patches_gray.get_norm(), 7, 7, 1); // both grayscale
Defensive patterns

Strategy: validation

Validate before calling

if (patch_image._spectrum != img._spectrum) {
  patch_image.resize(patch_image.width(), patch_image.height(),
                     patch_image.depth(), img.spectrum());
}
CImg<intT> matches = img.matchpatch(patch_image, pw, ph, pd);

Type guard

template<typename T, typename t>
bool sameSpectrum(const CImg<T>& a, const CImg<t>& b) {
  return a._spectrum == b._spectrum;
}

Try / catch

try {
  CImg<intT> matches = img.matchpatch(patch_image, pw, ph, pd);
} catch (CImgArgumentException& e) {
  std::fprintf(stderr, "spectrum mismatch: %s\n", e.what());
  CImg<intT> matches = img.get_norm().matchpatch(patch_image.get_norm(), pw, ph, pd);
}

Prevention

When it happens

Trigger: Calling matchpatch(patch_image, patch_width, patch_height, patch_depth, ...) where patch_image._spectrum != instance._spectrum - e.g. RGB instance with grayscale patch image, or a patch image loaded with a different channel count.

Common situations: Mixing color and grayscale images in template/patch matching, images converted differently upstream (one JPEG loaded as RGB, one as grayscale), or reusing a patch atlas built from differently-encoded sources.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/6a601e1956379e0e. Report an issue: GitHub.