使用OpenCV 4.8.0 LBP级联分类器时detectMultiScale函数卡顿
问题
使用OpenCV 4.8.0训练了车辆检测LBP级联分类器,调用detectMultiScale时程序卡顿,XML已成功加载,但执行到该函数时冻结。
分类器XML内容
<?xml version="1.0"?> <opencv_storage> <cascade> <stageType>BOOST</stageType> <featureType>LBP</featureType> <height>75</height> <width>100</width> <stageParams> <boostType>GAB</boostType> <minHitRate>9.9500000476837158e-01</minHitRate> <maxFalseAlarm>5.0000000000000000e-01</maxFalseAlarm> <weightTrimRate>9.4999999999999996e-01</weightTrimRate> <maxDepth>1</maxDepth> <maxWeakCount>100</maxWeakCount></stageParams> <featureParams> <maxCatCount>256</maxCatCount> <featSize>1</featSize></featureParams> <stageNum>4</stageNum> <stages> <!-- stage 0 --> <_> <maxWeakCount>3</maxWeakCount> <stageThreshold>-1.0529006719589233e+00</stageThreshold> <weakClassifiers> <_> <internalNodes> 0 -1 5 -232271405 -150405104 -2147270639 -788316039 -636434134 -922025216 -1996324149 -1170220853</internalNodes> <leafValues> -8.4758365154266357e-01 6.4864861965179443e-01</leafValues></_> <_> <internalNodes> 0 -1 8 -217326957 -779419584 -1040187376 1497449481 -2146905949 -938803005 281788605 -863116279</internalNodes> <leafValues> -8.3338397741317749e-01 6.5263098478317261e-01</leafValues></_> <_> <internalNodes> 0 -1 3 -799062757 -706575487 16961969 818069578 -872412557 -100466555 571088992 -255137189</internalNodes> <leafValues> -8.5794800519943237e-01 6.8386518955230713e-01</leafValues></_></weakClassifiers></_> <!-- stage 1 --> <_> <maxWeakCount>3</maxWeakCount> <stageThreshold>-1.1046675443649292e+00</stageThreshold> <weakClassifiers> <_> <internalNodes> 0 -1 2 -582363137 -268369599 285347019 -642973687 555 -913309688 -2013011505 -76031825</internalNodes> <leafValues> -8.5018724203109741e-01 5.8974361419677734e-01</leafValues></_> <_> <internalNodes> 0 -1 9 -984360501 -2075981309 -1860677159 -1039814568 -1987469154 165355976 155371681 -8140661</internalNodes> <leafValues> -8.7958252429962158e-01 5.8119404315948486e-01</leafValues></_> <_> <internalNodes> 0 -1 10 -1481380181 1233174855 1091111312 -1778179965 1090585999 -1442633216 1074364613 -661659159</internalNodes> <leafValues> -8.3567428588867188e-01 6.2639969587326050e-01</leafValues></_></weakClassifiers></_> <!-- stage 2 --> <_> <maxWeakCount>3</maxWeakCount> <stageThreshold>-1.0118436813354492e+00</stageThreshold> <weakClassifiers> <_> <internalNodes> 0 -1 6 -913141661 1367671040 134266899 269586464 -2147426165 -1971322496 -1577058169 -1194221141</internalNodes> <leafValues> -8.6471664905548096e-01 1.</leafValues></_> <_> <internalNodes> 0 -1 0 -779271921 -1874788352 268468224 -1322844127 8520 -2013265408 134226115 -633071478</internalNodes> <leafValues> -9.2569231986999512e-01 6.8080991506576538e-01</leafValues></_> <_> <internalNodes> 0 -1 1 -805203965 553715712 50401792 293797891 -1006632832 1158 1073774632 -1980792702</internalNodes> <leafValues> -8.2793700695037842e-01 8.2165032625198364e-01</leafValues></_></weakClassifiers></_> <!-- stage 3 --> <_> <maxWeakCount>2</maxWeakCount> <stageThreshold>7.8125000000000000e-03</stageThreshold> <weakClassifiers> <_> <internalNodes> 0 -1 7 -2147434368 0 1 805306368 160 -1610612720 3 42336256</internalNodes> <leafValues> -9.9218750000000000e-01 1.</leafValues></_> <_> <internalNodes> 0 -1 4 65538 37120 16 -2147483648 -2147483648 1 1 1208635408</internalNodes> <leafValues> -9.8839455842971802e-01 1.</leafValues></_></weakClassifiers></_></stages> <features> <_> <rect> 1 51 15 6</rect></_> <_> <rect> 3 6 9 6</rect></_> <_> <rect> 4 51 13 6</rect></_> <_> <rect> 5 54 5 4</rect></_> <_> <rect> 8 59 8 5</rect></_> <_> <rect> 14 28 24 13</rect></_> <_> <rect> 28 43 21 10</rect></_> <_> <rect> 30 53 13 4</rect></_> <_> <rect> 50 29 15 12</rect></_> <_> <rect> 66 48 8 3</rect></_> <_> <rect> 80 64 5 3</rect></_></features></cascade> </opencv_storage>
C++代码
CascadeClassifier cascade; if (!cascade.load("path\\to\\cascade.xml")) { cout << "Failed to load classifier" << endl; return -1; } Mat frame = imread("path\\to\\test\\frame.jpg"); cvtColor(frame, frame, COLOR_BGR2GRAY); equalizeHist(frame, frame); vector<Rect> cars; classifier.detectMultiScale(frame, cars); // execution freezes here for (const auto& car : cars) { rectangle(frame, car, Scalar(255, 0, 0), 2); } namedWindow("Detections", WINDOW_NORMAL); imshow("Detections", frame);
补充信息
- 调试显示
detectMultiScale调用处冻结,XML加载成功(load返回true) - 训练到第3阶段(1开始计数为第4阶段)时出现提示:
Required leaf false alarm rate achieved. Branch training terminated.,按文档说明非错误,已尝试每阶段200个正样本重新训练,问题依旧
解决方案
一、适配当前分类器的C++代码优化
- 修正变量名错误:代码中加载的分类器对象是
cascade,但调用detectMultiScale时用了classifier,这是明显错误,会导致未定义行为,先修正这个问题。 - 添加
detectMultiScale参数优化:默认参数可能导致遍历过多尺度,增加计算量,设置合理的尺度因子、最小邻居数、最小/最大检测尺寸,减少不必要的计算:
CascadeClassifier cascade; if (!cascade.load("path\\to\\cascade.xml")) { cout << "Failed to load classifier" << endl; return -1; } Mat frame = imread("path\\to\\test\\frame.jpg"); if (frame.empty()) { cout << "Failed to load image" << endl; return -1; } Mat gray; cvtColor(frame, gray, COLOR_BGR2GRAY); equalizeHist(gray, gray); vector<Rect> cars; // 优化detectMultiScale参数 cascade.detectMultiScale( gray, cars, 1.1, // 尺度因子,每次缩放10% 2, // 最小邻居数,过滤误检 0 | CASCADE_SCALE_IMAGE, // 检测标志 Size(75, 100), // 最小检测尺寸,与分类器训练尺寸一致 Size(frame.cols, frame.rows) // 最大检测尺寸 ); for (const auto& car : cars) { rectangle(frame, car, Scalar(255, 0, 0), 2); } namedWindow("Detections", WINDOW_NORMAL); imshow("Detections", frame); waitKey(0); // 添加等待按键,避免窗口一闪而过 destroyAllWindows();
- 内存与图像检查:添加图像加载成功判断,避免处理空图像导致的异常;将灰度图单独存储,保留原彩色图用于绘制框。
二、训练可用分类器的指导
- 样本集优化
- 正样本:确保至少500张以上,涵盖不同角度、光照、背景的车辆,尺寸统一为训练时的75x100,避免拉伸变形。
- 负样本:数量至少是正样本的3-5倍,选取不含车辆的场景图,尺寸大于75x100,让训练器自动裁剪。
- 训练参数调整
- 调整
maxFalseAlarm:当前每阶段0.5的假阳性率过高,建议降低到0.2-0.3,让每阶段过滤更多负样本,减少后续计算压力。 - 增加阶段数:当前仅4个阶段,建议设置为10-20个阶段,提升分类器的判别能力,同时避免过早触发终止条件。
- 调整
maxWeakCount:每阶段弱分类器数量可增加到50-100,增强每阶段的过滤效果。
- 调整
- 训练流程规范
- 使用
opencv_createsamples生成正样本vec文件时,确保参数正确,避免样本重复或变形。 - 训练时使用
opencv_traincascade,指定-numStages为目标阶段数,-minHitRate保持0.995不变,-maxFalseAlarmRate设为0.25左右。 - 若训练过早终止,可适当降低
minHitRate到0.99,或增加负样本数量,让训练器继续训练更多阶段。
- 使用
内容的提问来源于stack exchange,提问作者SNBS
相关产品推荐
相关产品推荐

