Yalantis/uCrop · error · CImgArgumentException

matchpatch(): Specified guide (%u,%u,%u,%u,%p) has invalid d

Error message

matchpatch(): Specified guide (%u,%u,%u,%u,%p) has invalid dimensions considering instance and patch image (%u,%u,%u,%u,%p).

What it means

matchpatch() accepts an optional guide image (typically a previous displacement field) whose spatial dimensions must equal the instance image's, and whose spectrum must be at least 2 (or 3 for volumetric patch images, _constraint). If the guide is non-empty and violates these constraints, the library throws this CImgArgumentException, printing both the guide's and patch image's dimensions.

Source

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

      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
        _constraint = patch_image._depth>1?3:2,
        constraint = guide._spectrum>_constraint?_constraint:0;

      if (guide &&
          (guide._width!=_width || guide._height!=_height || guide._depth!=_depth || guide._spectrum<_constraint))
        throw CImgArgumentException(_cimg_instance
                                    "matchpatch(): Specified guide (%u,%u,%u,%u,%p) has invalid dimensions "
                                    "considering instance and patch image (%u,%u,%u,%u,%p).",
                                    cimg_instance,
                                    guide._width,guide._height,guide._depth,guide._spectrum,guide._data,
                                    patch_image._width,patch_image._height,patch_image._depth,patch_image._spectrum,
                                    patch_image._data);

      CImg<intT> a_map(_width,_height,_depth,patch_image._depth>1?3:2);
      CImg<ucharT> is_updated(_width,_height,_depth,1,3);
      CImg<floatT> score(_width,_height,_depth), penalty;
      const float _patch_penalization = cimg::abs(patch_penalization);
      const bool allow_identity = patch_penalization>=0;
      if (_patch_penalization!=0)
        penalty.assign(patch_image._width,patch_image._height,patch_image._depth,1,0);

      const int
        psizew = (int)patch_width,  psizew1 = psizew/2, psizew2 = psizew - psizew1 - 1,
        psizeh = (int)patch_height, psizeh1 = psizeh/2, psizeh2 = psizeh - psizeh1 - 1,

View on GitHub (pinned to f788b534b4)

Solutions

  1. Ensure the guide has the same width/height/depth as the instance image
  2. Ensure guide._spectrum >= 2 (2D) or >= 3 (3D patch images) - the guide normally stores displacement components per channel
  3. Resize/rebuild the guide (guide.resize(_width,_height,_depth,needed_spectrum)) before the call
  4. Pass an empty CImg (default-constructed) if no guidance is desired - empty guides bypass the check

Example fix

// before
CImg<float> guide = previous_guide; // resized image, 5x5 vs 100x100 instance
CImg<intT> matches = img.matchpatch(patches, 7, 7, 1, guide);
// after
previous_guide.resize(img.width(), img.height(), img.depth(), previous_guide.spectrum());
CImg<intT> matches = img.matchpatch(patches, 7, 7, 1, previous_guide);
Defensive patterns

Strategy: validation

Validate before calling

const unsigned int needS = patch_image._depth > 1 ? 3 : 2;
if (guide && (guide._width != img._width || guide._height != img._height ||
              guide._depth != img._depth || guide._spectrum < needS)) {
  guide.resize(img.width(), img.height(), img.depth(), needS);
}
CImg<intT> matches = img.matchpatch(patch_image, pw, ph, pd, guide);

Type guard

template<typename T, typename t>
bool isMatchpatchGuideValid(const CImg<T>& inst, const CImg<t>& guide,
                            const CImg<t>& patch_image) {
  const unsigned int needS = patch_image._depth > 1 ? 3 : 2;
  return !guide || (guide._width == inst._width && guide._height == inst._height &&
                    guide._depth == inst._depth && guide._spectrum >= needS);
}

Try / catch

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

Prevention

When it happens

Trigger: Calling matchpatch(..., guide, ...) where guide._width/_height/_depth differ from the instance, or guide._spectrum < 2 (2D) / < 3 (3D patch images) - e.g. a scalar guide image or a guide from a differently-sized previous run.

Common situations: Feeding a single-channel prior instead of a vector-valued flow guide, reusing a guide computed on a resized/cropped version of the image, or using a 2D guide with volumetric patch matching.

Related errors


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