opencv - opencv_traincascade CvCascadeClassifier::fillPassedSamples 中的无限循环

标签 opencv computer-vision haar-wavelet

所以我一直在玩弄 opencv 最新的 LBP 级联训练器,但我一直遇到无限循环。我相信原因可能是我有限的负面(背景)图像集造成的。但是程序不应该陷入无限循环......我设法确定了无限循环的位置并对源代码进行了一些修改,不仅避免了无限循环,而且还提高了生成的级联文件中的检测性能。但是,我仍然希望了解代码的人告诉我这是否是一个正确的修复以及它为什么有效(或其他):

sample 制备: 所以我有一个正图像,并使用“createsamples”生成 100 个扭曲/旋转的正样本:

opencv_createsamples -img positive1.png -num 100 -bg neg.txt -vec samples.vec -maxidev 50 -w 100 -h 62 -maxxangle 0 -maxyangle 0.6 -maxzangle 0.4 -show 1

我在“negative”目录下只有5个负样本。然后我的训练命令:

opencv_traincascade -data cascade_result -vec samples.vec -bg neg.txt -numStages 10 -numPos 100 -numNeg 200 -featureType LBP -w 100 -h 62 -bt DAB -minHitRate 0.99 -maxFalseAlarmRate 0.2 -weightTrimRate 0.95 -maxDepth 1

请注意,我设置了 -numNeg 200,即使我在“neg.txt”中只有 5 个负片图像。后来我发现 numNeg 不需要匹配负片图像的数量,因为程序会反复从负片图像中“裁剪”出图像片段,以用于训练正片图像。

在第 4 阶段我遇到了无限循环,它位于(参见“//!!!!!”):

int CvCascadeClassifier::fillPassedSamples( int first, int count, bool isPositive, int64& consumed )
{
    int getcount = 0;
    Mat img(cascadeParams.winSize, CV_8UC1);
cout << "isPos: "<< isPositive << "; first: "<< first << "; count: "<< count << endl;
    for( int i = first; i < first + count; i++ )
    {
  int inner_count = 0;
  // !!!!! Here is the start of infinite loop
        for( ; ; )
        {
            // !!!!! This is my code to fix the infinite loop:
        /*
        inner_count++;
        if (inner_count > numNeg * 200) // there should be less than 200 crops of negative images per negative image
        {
            cout << "force exit the loop: inner count: "<< inner_count << "; consumed: " << consumed << endl;
            break;
        }
    */
            bool isGetImg = isPositive ? imgReader.getPos( img ) :
                                       imgReader.getNeg( img );
            if( !isGetImg )
                return getcount;
            consumed++;

            featureEvaluator->setImage( img, isPositive ? 1 : 0, i );
            if( predict( i ) == 1 )
            {
                getcount++;
                break;
            }
        }
    }
    return getcount;
}

我认为问题是 imgReader.getNeg(img) 一直从负集裁剪,直到满足“preduct(i) == 1”条件以退出无限循环。我不明白“predict(i)”是做什么的,但我猜想如果负数集很小且有限,它将用完“predict(i)”返回 1 的“各种”图像……所以循环永远不会结束。一种解决方案是创建负集,这是我接下来要尝试的。另一个更快的解决方案是我在//!!!!! 中添加的代码将平均每个负片图像的尝试次数限制为 200 次,然后如果没有找到合适的候选者则强制退出循环。

通过此修复,我的训练类(class)继续进行到第 5 阶段,然后停在那里。我将级联 xml 放入我的应用程序中,它的性能相当不错,比我在第 4 阶段设置停止以避免无限循环要好。

希望对代码比较了解的人多多指教...

谢谢

最佳答案

你可能会遇到和我一样的问题。

该问题是因为opencv_traincascade.exe没有正确获取图片宽高或者原始图片宽高小于训练窗口大小导致的。

可以在opencv/appa/traincascade/imagestorage.cpp中添加两行箭头指向的代码来解决问题。

bool CvCascadeImageReader::NegReader::nextImg()
{
    Point _offset = Point(0,0);
    size_t count = imgFilenames.size();
    for( size_t i = 0; i < count; i++ )
    {
        src = imread( imgFilenames[last++], 0 );
        if(src.rows<winSize.height || src.cols < winSize.width)   <-----------
            continue;                                             <-----------
        if( src.empty() )
            continue;
....

希望此解决方案对您有所帮助。

关于opencv - opencv_traincascade CvCascadeClassifier::fillPassedSamples 中的无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14554281/

相关文章:

opencv - SiftFeatureDetector .detect函数损坏?

opencv - Haar Cascades 与 LBP Cascades 在人脸检测中的对比

python - 如何将一系列颜色转换为透明?

android - OpenCV imwrite,颜色错误: Which argument for convertTo/cvColor do I use?

machine-learning - 多个独立标签的成本和激活函数

python - Scikit-image:如何减少断线段、重叠线?

c# - 访问像素和对象跟踪 : Emgu CV or Aforge. 网络?哪个更快更容易?

java - 尝试使用 OpenCV JAVA 检测图像中的人脸时出错

image-processing - 如何计算图像的逆平稳小波变换?

c++ - 多线程多队列..如何管理它?