{"record":{"id":"a4ced9e628dfa434","repo":"Yalantis/uCrop","slug":"project-matrix-instance-image-is-not-a-matrix","errorCode":null,"errorMessage":"project_matrix(): Instance image is not a matrix.","messagePattern":"project_matrix\\(\\): Instance image is not a matrix\\.","errorType":"exception","errorClass":"CImgInstanceException","httpStatus":null,"severity":"error","filePath":"ucrop/src/main/jni/CImg.h","lineNumber":33735,"sourceCode":"       \\param max_iter Sets the max number of iterations processed for each signal.\n                       If set to '0' (default), 'max_iter' is set to the number of dictionary columns.\n                       (only meaningful for matching pursuit and its variants).\n       \\param max_residual Gives a stopping criterion on signal reconstruction accuracy.\n                           (only meaningful for matching pursuit and its variants).\n       \\return A matrix W whose columns correspond to the sparse weights of associated to each input matrix column.\n               Thus, the matrix product D*W is an approximation of the input matrix.\n    **/\n    template<typename t>\n    CImg<T>& project_matrix(const CImg<t>& dictionary, const unsigned int method=0,\n                            const unsigned int max_iter=0, const double max_residual=1e-6) {\n      return get_project_matrix(dictionary,method,max_iter,max_residual).move_to(*this);\n    }\n\n    template<typename t>\n    CImg<Tfloat> get_project_matrix(const CImg<t>& dictionary, const unsigned int method=0,\n                                    const unsigned int max_iter=0, const double max_residual=1e-6) const {\n      if (_depth!=1 || _spectrum!=1)\n        throw CImgInstanceException(_cimg_instance\n                                    \"project_matrix(): Instance image is not a matrix.\",\n                                    cimg_instance);\n      if (dictionary._height!=_height || dictionary._depth!=1 || dictionary._spectrum!=1)\n        throw CImgArgumentException(_cimg_instance\n                                    \"project_matrix(): Specified dictionary (%u,%u,%u,%u) has an invalid size.\",\n                                    cimg_instance,\n                                    dictionary._width,dictionary._height,dictionary._depth,dictionary._spectrum);\n      if (!method) return get_solve(dictionary);\n\n      // Compute norm of dictionary atoms.\n      CImg<Tfloat> dictionary_norm(dictionary._width);\n      cimg_pragma_openmp(parallel for\n                         cimg_openmp_if(dictionary._width>=2 && dictionary._width*dictionary._height>=32))\n      cimg_forX(dictionary_norm,atom) {\n        Tfloat norm = 0;\n        cimg_forY(dictionary,s) norm+=cimg::sqr(dictionary(atom,s));\n        dictionary_norm[atom] = std::max((Tfloat)1e-8,std::sqrt(norm));\n      }","sourceCodeStart":33717,"sourceCodeEnd":33753,"githubUrl":"https://github.com/Yalantis/uCrop/blob/f788b534b48c144edf786c8cddbf0e029e637804/ucrop/src/main/jni/CImg.h#L33717-L33753","documentation":"get_project_matrix() requires the instance to be a 2D matrix (_depth==1 and _spectrum==1). If it is a volume or multi-channel image, CImgInstanceException('project_matrix(): Instance image is not a matrix.') is thrown because the sparse-projection math only applies to 2D matrices.","triggerScenarios":"Calling get_project_matrix(dictionary, ...) on an image with depth>1 or spectrum>1 (e.g. an RGB image or 3D volume).","commonSituations":"Passing a color image where a grayscale 2D signal/matrix was required; forgetting get_channel(0) after a crop; pipeline changes that made data 3D.","solutions":["Collapse to 2D single-channel before the call: use get_channel(0) / get_slice(0)","Check img.depth()==1 && img.spectrum()==1 as a guard before calling","Average or convert channels to a single matrix if that matches your intent"],"exampleFix":"// before\nCImg<float> P = rgb.get_project_matrix(dict);\n// after\nCImg<float> m = rgb.get_channel(0);\nCImg<float> P = m.get_project_matrix(dict);","handlingStrategy":"validation","validationCode":"if (img.depth() != 1 || img.spectrum() != 1) throw std::invalid_argument(\"get_project_matrix requires a 2D single-channel matrix\");","typeGuard":"bool isMatrixImage(const CImg<T>& m) { return m.depth() == 1 && m.spectrum() == 1; }","tryCatchPattern":"try { P = img.get_project_matrix(dict); } catch (CImgInstanceException& e) { /* convert input to single-channel 2D and retry */ }","preventionTips":["Grayscale/flatten inputs before sparse-coding calls","Assert 2D-ness in helpers feeding get_project_matrix","Convert color images with get_channel() or luminance conversion early"],"tags":["cimg","project-matrix","matrix-shape","sparse-coding"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"f788b534b48c144edf786c8cddbf0e029e637804","analyzedAt":"2026-09-08T08:36:04.887Z","contentChangedAt":"2026-09-08T08:36:04.887Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}