Yalantis/uCrop · error · CImgInstanceException

SVD(): Instance has invalid dimensions (depth or channels di

Error message

SVD(): Instance has invalid dimensions (depth or channels different from 1).

What it means

SVD() decomposes a 2D single-channel matrix (width x height) and rejects instances whose _depth != 1 or _spectrum != 1, since singular value decomposition is only defined for the 2D matrix stored in the x-y plane.

Source

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

       \param[out] V Third matrix of the SVD product.
       \param sorting Tells if the diagonal coefficients are sorted (in decreasing order).
       \param max_iteration Maximum number of iterations considered for the algorithm convergence.
       \param lambda Epsilon used for the algorithm convergence.
       \note The instance matrix can be computed from \c U,\c S and \c V by
       \code
       const CImg<> A; // Input matrix (assumed to contain some values)
       CImg<> U,S,V;
       A.SVD(U,S,V)
       \endcode
    **/
    template<typename t>
    const CImg<T>& SVD(CImg<t>& U, CImg<t>& S, CImg<t>& V, const bool sorting=true,
                       const unsigned int max_iteration=40, const float lambda=0) const {
      typedef _cimg_Ttfloat Ttfloat;
      const Ttfloat eps = (Ttfloat)1e-8f;
      if (is_empty()) { U.assign(); S.assign(); V.assign(); }
      else if (_depth!=1 || _spectrum!=1)
        throw CImgInstanceException(_cimg_instance
                                    "SVD(): Instance has invalid dimensions (depth or channels different from 1).",
                                    cimg_instance);
      else {
        U = *this;
        if (lambda!=0) {
          const unsigned int delta = std::min(U._width,U._height);
          for (unsigned int i = 0; i<delta; ++i) U(i,i) = (t)(U(i,i) + lambda);
        }
        if (S.size()<_width) S.assign(1,_width);
        if (V._width<_width || V._height<_height) V.assign(_width,_width);
        CImg<t> rv1(_width);
        Ttfloat anorm = 0, c, f, g = 0, h, s, scale = 0;
        int l = 0;

        cimg_forX(U,i) {
          l = i + 1;
          rv1[i] = scale*g;
          g = s = scale = 0;

View on GitHub (pinned to f788b534b4)

Solutions

  1. Extract a single 2D matrix first: img.get_slice(z).get_channel(c) before calling SVD
  2. Verify _depth==1 && _spectrum==1 (via img.depth()/img.spectrum()) as a precondition
  3. If you need SVD of many slices, loop over slices calling SVD per 2D matrix

Example fix

// before
volume.SVD(U, S, V); // depth=10
// after
CImg<float> m = volume.get_slice(0).get_channel(0);
m.SVD(U, S, V);
Defensive patterns

Strategy: validation

Validate before calling

if (img.depth() == 1 && img.spectrum() == 1) { img.SVD(U, S, V); } else { /* extract slice/channel first */ }

Type guard

bool is2DMatrix(const CImg<T>& m) { return m.depth() == 1 && m.spectrum() == 1; }

Try / catch

try { img.SVD(U, S, V); } catch (CImgInstanceException& e) { /* degrade to per-slice SVD or error out */ }

Prevention

When it happens

Trigger: Calling SVD(U,S,V) on a volumetric image (_depth>1) or a multi-channel/color image (_spectrum>1).

Common situations: Forgetting to extract one slice/channel of an RGB or 3D image before SVD; reusing code that operated on image stacks; passing a whole tensor when a single matrix was intended.

Understand the failure class

Background: Tensor shape mismatch errors ("must have shape", "expected shape ... got ..."): when tensor dimensions disagree with what an op or layer was told to expect — this error's family across 6 libraries.

Related errors


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