diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 8e8a0ce4af..cea31b0b32 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -47,8 +47,8 @@ #include #include #include -#include #include +#include namespace { @@ -61,6 +61,13 @@ char *itoa(long i, char* s, int /*dummy_radix*/) // used for noisy printfs // #define WITH_DEBUG_OUT +#if defined WITH_DEBUG_OUT +# define dprintf(format, ...) \ + do { printf(format, __VA_ARGS__); } while (0) +#else +# define dprintf(format, ...) +#endif + struct Octave { int index; @@ -169,9 +176,6 @@ struct CascadeIntrinsics static float getFor(int channel, float scaling) { CV_Assert(channel < 10); -#if defined WITH_DEBUG_OUT - printf("QQQQQQQQQQQQQQQq: %f %f\n", scaling, fabs(scaling - 1.f)); -#endif if (fabs(scaling - 1.f) < FLT_EPSILON) // if (scaling == 1.f) @@ -193,9 +197,7 @@ struct CascadeIntrinsics float a = A[(int)(scaling >= 1)][(int)(channel > 6)]; float b = B[(int)(scaling >= 1)][(int)(channel > 6)]; -#if defined WITH_DEBUG_OUT - printf("!!! scaling: %f %f %f %f\n", scaling, a, b, a * pow(scaling, b)); -#endif + dprintf("scaling: %f %f %f %f\n", scaling, a, b, a * pow(scaling, b)); return a * pow(scaling, b); } }; @@ -269,6 +271,7 @@ struct Decimate { }; +// use previous stored integrals for regression testing // #define USE_REFERENCE_VALUES struct ChannelStorage @@ -279,14 +282,14 @@ struct ChannelStorage enum {HOG_BINS = 6, HOG_LUV_BINS = 10}; ChannelStorage() {} - ChannelStorage(cv::Mat& colored, int shr) : shrinkage(shr) + ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr) { hog.clear(); Decimate decimate(shr); #if defined USE_REFERENCE_VALUES - cv::FileStorage imgs("/home/kellan/testInts.xml", cv::FileStorage::READ); char buff[33]; + cv::FileStorage imgs("/home/kellan/testInts.xml", cv::FileStorage::READ); for(int i = 0; i < HOG_LUV_BINS; ++i) { @@ -310,10 +313,10 @@ struct ChannelStorage // shrink and integrate for (int i = 0; i < (int)splited.size(); i++) { - cv::Mat shrunk, sum; - decimate(splited[i], shrunk); - cv::integral(shrunk, sum, cv::noArray(), CV_32S); - luvs.push_back(sum); + cv::Mat shrunk, sum; + decimate(splited[i], shrunk); + cv::integral(shrunk, sum, cv::noArray(), CV_32S); + luvs.push_back(sum); } // convert to grey @@ -353,12 +356,12 @@ struct ChannelStorage cv::integral(shrMag, mag, cv::noArray(), CV_32S); // create hog channels - angle /= 60; + angle /= 60.f; std::vector hist; - for (int bin = 0; bin < 6; ++bin) + for (int bin = 0; bin < HOG_BINS; ++bin) { - hist.push_back(cv::Mat(colored.rows, colored.cols, CV_8UC1)); + hist.push_back(cv::Mat::zeros(saturatedMag.rows, saturatedMag.cols, CV_8UC1)); } for (int y = 0; y < saturatedMag.rows; ++y) @@ -375,7 +378,6 @@ struct ChannelStorage for(int i = 0; i < HOG_BINS; ++i) { cv::Mat shrunk, sum; - decimate(hist[i], shrunk); cv::integral(shrunk, sum, cv::noArray(), CV_32S); hog.push_back(sum); @@ -385,7 +387,6 @@ struct ChannelStorage hog.insert(hog.end(), luvs.begin(), luvs.end()); CV_Assert(hog.size() == 10); #endif - // exit(10); } float get(const int x, const int y, const int channel, const cv::Rect& area) const @@ -393,26 +394,23 @@ struct ChannelStorage CV_Assert(channel < HOG_LUV_BINS); const cv::Mat m = hog[channel]; -#if defined WITH_DEBUG_OUT - printf("feature box %d %d %d %d ", area.x, area.y, area.width, area.height); - printf("get for channel %d\n", channel); - printf("!! %d\n", m.depth()); + dprintf("feature box %d %d %d %d ", area.x, area.y, area.width, area.height); + dprintf("get for channel %d\n", channel); + dprintf("!! %d\n", m.depth()); - printf("extract feature for: [%d %d] [%d %d] [%d %d] [%d %d]\n", + dprintf("extract feature for: [%d %d] [%d %d] [%d %d] [%d %d]\n", x + area.x, y + area.y, x + area.width,y + area.y, x + area.width,y + area.height, x + area.x, y + area.height); - printf("at point %d %d with offset %d\n", x, y, 0); -#endif + dprintf("at point %d %d with offset %d\n", x, y, 0); int a = m.ptr(y + area.y)[x + area.x]; int b = m.ptr(y + area.y)[x + area.width]; int c = m.ptr(y + area.height)[x + area.width]; int d = m.ptr(y + area.height)[x + area.x]; -#if defined WITH_DEBUG_OUT - printf(" retruved integral values: %d %d %d %d\n", a, b, c, d); -#endif + dprintf(" retruved integral values: %d %d %d %d\n", a, b, c, d); + return (a - b + c - d); } }; @@ -444,12 +442,10 @@ struct cv::SoftCascade::Filds float scaling = CascadeIntrinsics::getFor(feature.channel, relScale); scaledRect = feature.rect; -#if defined WITH_DEBUG_OUT - printf("feature %d box %d %d %d %d\n", feature.channel, scaledRect.x, scaledRect.y, + dprintf("feature %d box %d %d %d %d\n", feature.channel, scaledRect.x, scaledRect.y, scaledRect.width, scaledRect.height); - std::cout << "rescale: " << feature.channel << " " << relScale << " " << scaling << std::endl; -#endif + dprintf("rescale: %d %f %f\n",feature.channel, relScale, scaling); float farea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); // rescale @@ -458,14 +454,9 @@ struct cv::SoftCascade::Filds scaledRect.width = cvRound(relScale * scaledRect.width); scaledRect.height = cvRound(relScale * scaledRect.height); -#if defined WITH_DEBUG_OUT - printf("feature %d box %d %d %d %d\n", feature.channel, scaledRect.x, scaledRect.y, + dprintf("feature %d box %d %d %d %d\n", feature.channel, scaledRect.x, scaledRect.y, scaledRect.width, scaledRect.height); - std::cout << " new rect: " << scaledRect.x << " " << scaledRect.y - << " " << scaledRect.width << " " << scaledRect.height << " "; -#endif - float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); float approx = 1.f; @@ -474,20 +465,14 @@ struct cv::SoftCascade::Filds const float expected_new_area = farea * relScale * relScale; approx = expected_new_area / sarea; -#if defined WITH_DEBUG_OUT - std::cout << " rel areas " << expected_new_area << " " << sarea << std::endl; -#endif - + dprintf(" rel areas %f %f\n", expected_new_area, sarea); } // compensation areas rounding float rootThreshold = threshold / approx; rootThreshold *= scaling; -#if defined WITH_DEBUG_OUT - std::cout << "approximation " << approx << " " << threshold << " -> " << rootThreshold - << " " << scaling << std::endl; -#endif + dprintf("approximation %f %f -> %f %f\n", approx, threshold, rootThreshold, scaling); return rootThreshold; } @@ -495,26 +480,21 @@ struct cv::SoftCascade::Filds void detectAt(const Level& level, const int dx, const int dy, const ChannelStorage& storage, std::vector& detections) const { -#if defined WITH_DEBUG_OUT - std::cout << "detect at: " << dx << " " << dy << std::endl; -#endif + dprintf("detect at: %d %d\n", dx, dy); + float detectionScore = 0.f; const Octave& octave = *(level.octave); int stBegin = octave.index * octave.stages, stEnd = stBegin + octave.stages; -#if defined WITH_DEBUG_OUT - std::cout << " octave stages: " << stBegin << " to " << stEnd << " index " << octave.index << " " - << octave.scale << " level " << level.origScale << std::endl; -#endif + dprintf(" octave stages: %d to %d index %d %f level %f\n", + stBegin, stEnd, octave.index, octave.scale, level.origScale); int st = stBegin; for(; st < stEnd; ++st) { -#if defined WITH_DEBUG_OUT - printf("index: %d\n", st); -#endif + dprintf("index: %d\n", st); const Stage& stage = stages[st]; { @@ -529,15 +509,11 @@ struct cv::SoftCascade::Filds float sum = storage.get(dx, dy, feature.channel, scaledRect); -#if defined WITH_DEBUG_OUT - printf("root feature %d %f\n",feature.channel, sum); -#endif + dprintf("root feature %d %f\n",feature.channel, sum); int next = (sum >= threshold)? 2 : 1; -#if defined WITH_DEBUG_OUT - printf("go: %d (%f >= %f)\n\n" ,next, sum, threshold); -#endif + dprintf("go: %d (%f >= %f)\n\n" ,next, sum, threshold); // leaves const Node& leaf = nodes[nId + next]; @@ -549,23 +525,24 @@ struct cv::SoftCascade::Filds int lShift = (next - 1) * 2 + ((sum >= threshold) ? 1 : 0); float impact = leaves[(st * 4) + lShift]; -#if defined WITH_DEBUG_OUT - printf("decided: %d (%f >= %f) %d %f\n\n" ,next, sum, threshold, lShift, impact); -#endif + + dprintf("decided: %d (%f >= %f) %d %f\n\n" ,next, sum, threshold, lShift, impact); + detectionScore += impact; } + dprintf("extracted stage:\n"); + dprintf("ct %f\n", stage.threshold); + dprintf("computed score %f\n\n", detectionScore); + #if defined WITH_DEBUG_OUT - printf("extracted stage:\n"); - printf("ct %f\n", stage.threshold); - printf("computed score %f\n\n", detectionScore); if (st - stBegin > 50 ) break; #endif if (detectionScore <= stage.threshold) break; } - printf("x %d y %d: %d\n", dx, dy, st - stBegin); + dprintf("x %d y %d: %d\n", dx, dy, st - stBegin); if (st == stEnd) { @@ -793,7 +770,7 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector detections; @@ -826,6 +806,8 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector