c++ - OpenCV 卡尔曼滤波器,从 std::vector 中删除

标签 c++ opencv exc-bad-access kalman-filter

我有这个问题,看。

我正在使用 OpenCV 来跟踪视频中的一只手。使用 CascadeDetector 定位手,然后使用 CamSHIFT 进行跟踪。如果 CamShift 算法在某些帧失败,我还使用卡尔曼滤波器来校正手的位置。

问题出现了,当我试图从存储 Hands 的 std::vector 中删除一个元素时。删除的原因是由于一些问题,一张脸被误解为手,所以我正在检测人脸,如果手区域与人脸区域相交,我删除那只手。我知道,很天真,但我现在才刚刚起步。 代码如下所示:

class Hand {
...
public:
    struct 
    {
        ...
        struct {
            cv::Mat_<float> measurement;
            cv::KalmanFilter KF;
            cv::Mat state;
            cv::Mat processNoise;
        } KalmanTracker;
    } Tracker;
};
...
std::vector<Hand> hands;
...
std::vector<cv::Rect> faces;
faceCascade.detectMultiScale(frame, faces, 1.1, 2, CV_HAAR_FIND_BIGGEST_OBJECT);
// iterate through hands
for (std::vector<Hand>::iterator it = hands.begin(); it != hands.end(); ++it) {
    // iterate through faces:
    for (std::vector<cv::Rect>::iterator fc = faces.begin(); fc != faces.end(); ++fc) {
        cv::Rect intersection = (*it).handBox.boundingRect() & (*fc);
        // check if they have at leasy 75% intersection
        if (intersection.area() >= ((*it).handBox.boundingRect().area() * 0.75)) {
            // delete that hand from list
            hands.erase(it);    // this gets me a a EXC_BAD_ACCESS
        }
    }
}

hands.erase(it) line 给我一个 EXC_BAD_ACCESS同时指着我的 KalmanFilterTracker结构,以及 mat.hpp 中的这一行用EXC_i386_GPFLT :

inline void Mat::release()
{
    if( refcount && CV_XADD(refcount, -1) == 1 ) // EXC_BAD_ACCESS, code=EXC_i386_GPFLT
    ...
}

都不是hands也不faces是空的。 如果我从我的项目中完全删除卡尔曼滤波器并提及或使用它,错误就会消失。

最佳答案

vector::erase(iterator) 使被删除的迭代器无效。但它确实返回一个新的迭代器到 vector 中的下一个有效项。因此该行应该是:

it = hands.erase(it);

根据 berak 的评论进行编辑:

啊,我错过了内部循环。由于您在内循环中使 it 无效,事情变得有点复杂。您需要克服一些困难才能做到正确。

for (std::vector<Hand>::iterator it = hands.begin(); it != hands.end(); ) {
    bool found = false;
    // iterate through faces:
    for (std::vector<cv::Rect>::iterator fc = faces.begin(); fc != faces.end() && !found; ++fc) {
        cv::Rect intersection = (*it).handBox.boundingRect() & (*fc);
        // check if they have at leasy 75% intersection
        if (intersection.area() >= ((*it).handBox.boundingRect().area() * 0.75)) {
            found = true;
        }
    }

    if (found) {
        it = hands.erase(it);
    }
    else {
        ++it;
    }
}

可以将一些迭代器操作折叠到内部循环中,但将其保留在外面会使代码更清晰,更容易推理。

关于c++ - OpenCV 卡尔曼滤波器,从 std::vector 中删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25642758/

相关文章:

c++ - 基本 C++ 速度(初始化与添加)和比较速度

c++ - "EXC_BAD_ACCESS"使用数组时 C++

ios - 在 Swift 中将对象添加到 NSMutableArray 时出错

c++ - 如何从 ADO/C++ 调用 MSSQL 系统函数?

c# - Silverlight 中动态加载的程序集调用锁定文件的 DllImprot

c++ - 如何使用 qt_add_qml_module 在 CMake 中注册 QObject 类?

c++ - 我怎样才能在 OpenCV 中写 float 图像

python - 64GB 可用,超过 16GB 时 cv2/python 崩溃

python - 无需下载视频即可捕获 YouTube 视频以供进一步处理

objective-c - CGContextDrawImage 导致 EXC BAD ACCESS