Yalantis/uCrop · error · CImgInstanceException
det(): Instance is not a square matrix.
Error message
det(): Instance is not a square matrix.
What it means
CImg::det() computes the determinant of the image viewed as a matrix, which requires a 2D square matrix: _width==_height and _depth==1 and _spectrum==1. The library throws CImgInstanceException when the instance is empty or its dimensions do not form a single-channel square matrix, because the determinant is undefined otherwise.
Source
Thrown at ucrop/src/main/jni/CImg.h:32579
//! Compute the trace of the image, viewed as a matrix.
/**
**/
double trace() const {
if (is_empty())
throw CImgInstanceException(_cimg_instance
"trace(): Empty instance.",
cimg_instance);
double res = 0;
cimg_forX(*this,k) res+=(double)(*this)(k,k);
return res;
}
//! Compute the determinant of the image, viewed as a matrix.
/**
**/
double det() const {
if (is_empty() || _width!=_height || _depth!=1 || _spectrum!=1)
throw CImgInstanceException(_cimg_instance
"det(): Instance is not a square matrix.",
cimg_instance);
switch (_width) {
case 1 : return (double)((*this)(0,0));
case 2 : return (double)((*this)(0,0))*(double)((*this)(1,1)) - (double)((*this)(0,1))*(double)((*this)(1,0));
case 3 : {
const double
a = (double)_data[0], d = (double)_data[1], g = (double)_data[2],
b = (double)_data[3], e = (double)_data[4], h = (double)_data[5],
c = (double)_data[6], f = (double)_data[7], i = (double)_data[8];
return i*a*e - a*h*f - i*b*d + b*g*f + c*d*h - c*g*e;
}
default : {
CImg<Tfloat> lu(*this,false);
CImg<uintT> indx;
bool d;
lu._LU(indx,d);View on GitHub (pinned to f788b534b4)
Solutions
- Ensure the instance is square and single-channel before calling det(): img.assign(n,n,1,1).
- Extract one channel/plane first: img.get_channel(0).det() or img.get_slice(0).det().
- For rectangular matrices, use a decomposition-based approach (e.g. SVD via get_SVD()) instead of det().
Example fix
// before CImg<float> img(3,4); // rectangular -> det() throws double d = img.det(); // after if (img.width()==img.height() && img.depth()==1 && img.spectrum()==1) double d = img.det();
Defensive patterns
Strategy: validation
Validate before calling
bool isSquareMatrix = !img.is_empty() && img.width()==img.height() && img.depth()==1 && img.spectrum()==1; if (!isSquareMatrix) img = img.get_channel(0).get_crop(0,0,img.height()-1,img.height()-1);
Type guard
bool isSquareMatrix(const CImg<T>& m){ return !m.is_empty() && m.width()==m.height() && m.depth()==1 && m.spectrum()==1; } Try / catch
try { double d = img.det(); } catch (CImgInstanceException& e) { std::cerr << e.what() << '\n'; } Prevention
- Remember CImg stores images as width x height x depth x spectrum; matrix ops need (n,n,1,1)
- Extract single channels from color images before matrix math
- Use symmetric_eigen/SVD for rectangular data instead of det()
When it happens
Trigger: Calling img.det() on a non-square width x height image, on an image with depth>1 (volumetric) or spectrum>1 (multi-channel color), or on an empty instance.
Common situations: Passing a color image (spectrum=3) instead of extracting a single channel; passing a volumetric image; passing an N x M rectangular matrix; forgetting that CImg treats an image as width x height x depth x spectrum, not rows x columns.
Related errors
- invert(): Instance is not a matrix.
- eigen(): Instance is not a square matrix.
- [cimg_appname_math_parser] CImg<%s>::%s: %s: Type of first a
- [cimg_appname_math_parser] CImg<%s>::%s: %s: Types of first
- [cimg_appname_math_parser] CImg<%s>::%s: %s: Size of first a
AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08).
Data as JSON: /api/errors/a7beef81aaa06fbb.
Report an issue: GitHub.