Problem with cv::cuda::CascadeClassifier

Hi, I have trained my own haar cascade classifier using opencv version 3.2 and after checking its performance I tried to use the cuda functions to perform some tests, however I encountered the following error:

terminate called after throwing an instance of 'cv::Exception'what():  OpenCV(4.4.0) /tmp/build_opencv/opencv_contrib/modules/cudalegacy/src/cuda/ error: (-215:Assertion failed) haar.ClassifierSize.height > 0 && haar.ClassifierSize.width > 0 in function 'loadFromXML'

I am currently using opencv version 4.4 on a jetson nano and applying the detectMultiScale function as follows:

         cv::cuda::GpuMat gframe, obj;
         std::vector<cv::Rect> rect;
         std::string cascadePath = "./cascade.xml"
         Ptr<cuda::CascadeClassifier> cascade = cv::cuda::CascadeClassifier::create(cascadePath);

         cascade->detectMultiScale(gframe, obj);
         cascade->convert(obj, rect);

I appreciate any information.

The assertion failure informs you that an object with a least one non-positive dimension was encountered. It seems natural that the classifier width and height are expected to be positive. If you cannot determine by simple code inspection why that happens, methodically trace the issue backwards, starting at the point of failure indicated in the error message, all the way back to the root cause. That’s a standard debugging approach.

That doesn’t look right to me.

I thought the error might be in the file path, but that was not the case.

I commented this part of the code, since detectMultiScale can work without it and the result was the same error.

The error message says the assertion failure occurs in function 'loadFromXML'.

I am not familiar with the code base you are using. Given the name, it is possible that the incorrect values detected are not directly triggered by function argument(s) passed to loadFromXML, but by data retrieved from XML. I don’t know how XML is presented to this function. It may be a string, or being loaded from a file. Maybe that XML input contains incorrect data, or it is missing a value (pair), causing a default value like zero to be used instead.

What I would do here is find where in loadFromXML the assertion triggers, and put a printf() in front of it that prints width and height. Maybe the actual data value reported for those will already allow you to recognize something about a potential source of the unexpected value (e.g. overflowed integer computation). Or may be not.

In that case, going upstream, find the closest setter of those data items, and insert a printf() there, including a printout of any source data they maybe computed from. The output of these printf() calls will form a nice log every time you run the app. Keep on tracing backward until you find the initial source of bad data.

In my career, I have been able to debug pretty much every bug ever encountered by printing data to a log, including environments where a slow serial port was the only connection to the (embedded) system, and bugs where colleagues had already given up on debugging. this debugging by data logging might get tricky in the presence of a Heisenbug, but nothing here suggests that this is the situation you are facing.

1 Like

I have been doing quite a few tests, but without success.

Regarding the xml file, I have tried the code without the cuda functions and the same .xml file and it works without problems.

Is it possible that there is a formatting problem between the .xml files generated by opencv_traincascade or cascade trainer GUI and what cuda::CascadeClasiffier is looking for?

Thank you very much for your answers.

I come back to say that I have solved the problem. It appears to be a compatibility problem. I used opencv version 3.4 and the opencv_traincascade function with its -baseFormatSave argument to train with the old .xml format and it worked.

However, when comparing this classifier in its cpu version (with cv::detectMultiScale) versus gpu (with cv::cuda::detectMultiScale), the detection results are very different between them.