Yalantis/uCrop · error · CImgInstanceException

get_isoline3d(): Instance is not a scalar image.

Error message

get_isoline3d(): Instance is not a scalar image.

What it means

CImg::get_isoline3d() extracts 3D isolines (contours at a given isovalue) from a scalar 2D image. The instance must have a single channel; CImg throws CImgInstanceException when _spectrum>1, i.e. the image is vector-valued (e.g. RGB or RGBA).

Solutions

  1. Convert to scalar first: img.get_channel(0) or img.get_norm() / RGBtoYCbCr channel depending on intent.
  2. Verify img._spectrum==1 before calling get_isoline3d.
  3. If all channels are equal, take channel 0; if not, decide a reduction (luminance, mean, norm) and apply it.
  4. Cache the scalar conversion once instead of converting per isoline call.
  5. Wrap in try/catch on CImgInstanceException.

Example fix

// before
CImg<unsigned char> img = load("map.png"); // RGBA, _spectrum==4
img.get_isoline3d(prims, 128.0f); // throws
// after
CImg<float> gray = img.get_channel(0).get_resize(...,-100,-100,1,1); // scalar
gray.get_isoline3d(prims, 128.0f); // OK
Defensive patterns

Strategy: validation

Validate before calling

if (img._spectrum>1)
  img = img.get_channel(0); // or luminance/norm reduction
img.get_isoline3d(prims, isovalue);

Type guard

template<typename T>
const CImg<T>& require_scalar(const CImg<T>& img) {
  if (img._spectrum>1) throw std::invalid_argument("expected scalar image");
  return img;
}

Try / catch

try {
  img.get_isoline3d(prims, isovalue);
} catch (CImgInstanceException& e) {
  std::fprintf(stderr, "isoline3d needs a scalar 2D image: %s\n", e.what());
}

Prevention

When it happens

Trigger: Calling get_isoline3d directly on a color image loaded from file (spectrum 3 or 4), or on any multi-channel image, instead of a scalar (spectrum==1) image.

Common situations: Forgetting to convert an RGB height/intensity image to grayscale before contouring; applying isoline extraction to a feature stack image with several bands.

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/f6b7edfb5b0d5774. Report an issue: GitHub.

Appendix: source

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

                              (template type \e tf should be at least \e unsigned \e int).
       \param isovalue The returned list of the 3D object colors.
       \param size_x The number of subdivisions along the X-axis.
       \param size_y The number of subdisivions along the Y-axis.
       \return The N vertices (xi,yi,zi) of the 3D object as a Nx3 CImg<float> image (0<=i<=N - 1).
       \par Example
       \code
       const CImg<float> img("reference.jpg");
       CImgList<unsigned int> faces3d;
       const CImg<float> points3d = img.get_isoline3d(faces3d,100);
       CImg<unsigned char>().display_object3d("Isoline3d",points3d,faces3d,colors3d);
       \endcode
       \image html ref_isoline3d.jpg
    **/
    template<typename tf>
    CImg<floatT> get_isoline3d(CImgList<tf>& primitives, const float isovalue,
                               const int size_x=-100, const int size_y=-100) const {
      if (_spectrum>1)
        throw CImgInstanceException(_cimg_instance
                                    "get_isoline3d(): Instance is not a scalar image.",
                                    cimg_instance);
      if (_depth>1)
        throw CImgInstanceException(_cimg_instance
                                    "get_isoline3d(): Instance is not a 2D image.",
                                    cimg_instance);
      primitives.assign();
      if (is_empty()) return *this;
      CImg<floatT> vertices;
      if ((size_x==-100 && size_y==-100) || (size_x==width() && size_y==height())) {
        const _functor2d_int func(*this);
        vertices = isoline3d(primitives,func,isovalue,0,0,width() - 1.f,height() - 1.f,width(),height());
      } else {
        const _functor2d_float func(*this);
        vertices = isoline3d(primitives,func,isovalue,0,0,width() - 1.f,height() - 1.f,size_x,size_y);
      }
      return vertices;
    }

View on GitHub (pinned to f788b534b4)