iOS中的剪影检测

时间:2014-11-19 00:14:00

标签: ios objective-c opencv

我正在尝试使用OpenCV 2.4.9检测iOS中的人物轮廓。我使用背景减法使用高斯混合物来实现它。参考:http://personal.ee.surrey.ac.uk/Personal/R.Bowden/publications/avbs01/avbs01.pdfhttp://docs.opencv.org/modules/video/doc/motion_analysis_and_object_tracking.html#backgroundsubtractormog

这是我的代码段;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    //UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Hello!"      message:@"Welcome to OpenCV" delegate:self cancelButtonTitle:@"Continue" otherButtonTitles:nil];
    //[alert show];

    self.videoCamera = [[CvVideoCamera alloc] initWithParentView:imageView]; // Sets up the camera
    self.videoCamera.defaultAVCaptureDevicePosition = AVCaptureDevicePositionFront; // Back-Front  Camera
    self.videoCamera.defaultAVCaptureSessionPreset = AVCaptureSessionPreset352x288;
    self.videoCamera.defaultAVCaptureVideoOrientation = AVCaptureVideoOrientationPortrait;
    self.videoCamera.defaultFPS = 30; // FPS
    self.videoCamera.delegate = self;
    //self.videoCamera.grayscale = NO; 
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)processImage:(Mat&)image
{
    cvtColor( image, image, COLOR_BGR2GRAY );
    vector<vector<cv::Point> > contours;
    vector<Vec4i> hierarchy;

    // Canny edge detector ...
    Canny(image, image, 100, 300); // Adjust thresholds 
    threshold(image, image, 100, 255, THRESH_BINARY_INV);
    // find contours
    findContours(image, contours, hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_SIMPLE,     cv::Point(0,0));

    int idx = 0;
    for (; idx >= 0; idx = hierarchy[idx][0] )
    {
        drawContours( image, contours, idx, 255, 1, 4, hierarchy ); 
    }
    bitwise_not(image, image);

    Ptr<BackgroundSubtractorMOG2> B = Algorithm::create<BackgroundSubtractorMOG2>("BackgroundSubtractor.MOG2");

    B->setDetectShadows(false);
    B->setNMixtures(3);

    B->createBackgroundSubtractorMOG2(image,fore);
    B->apply(image,fore);
    B->getBackgroundImage(bg);
    erode(fore, fore, Mat());
    dilate(fore, fore, Mat());

    findContours(fore, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
    drawContours(image, contours, -1, Scalar(0,255,0),2);
}

我在

获得了一个Thread7:EXC_BAD_ACCESS(代码= 1,地址= 0x0)
B->setDetectShadows(false);

意思是我的B是NULL。

我做了一些调试,发现B首先被初始化,然后在OpenCV中设置为NULL;

inline
String::String(const char* s)
    : cstr_(0), len_(0)
{
    if (!s) return;
    size_t len = strlen(s);
    memcpy(allocate(len), s, len);
}


template<typename _Tp> inline
Ptr<_Tp> Algorithm::create(const String& name)
{
    return _create(name).dynamicCast<_Tp>();
}

template<typename T>
template<typename Y>
Ptr<Y> Ptr<T>::dynamicCast() const
{
    return Ptr<Y>(*this, dynamic_cast<Y*>(stored));
}

然后最终设置为NULL!?

template<typename T>
void Ptr<T>::release()
{
    if (owner) owner->decRef();
    owner = NULL;
    stored = NULL;
}

我做错了什么和/或如何纠正?

我以前在C ++中使用Visual Studio和OpenCV 2.3完成了这个项目,我可以创建一个BackgroundSubtractorMOG2类型的对象,只需使用setNMixtures等等。但由于某些原因,iOS中的这个类是抽象的。

1 个答案:

答案 0 :(得分:0)

The doc on Algorithm::create包含注释:

  

注意这是关于Algorithm::create()在返回NULL时看似神秘的行为的重要说明,而不应该。原因很简单 - Algorithm::create()驻留在OpenCV的核心模块中,算法在其他模块中实现。如果您动态创建算法,C ++链接器可能会决定丢弃实现实际算法的模块,因为您不会从模块中调用任何函数。要避免此问题,您需要在Algorithm :: create()之前的程序开头的某处调用initModule_<modulename>();。例如,调用initModule_nonfree()以使用SURF / SIFT,调用initModule_ml()以使用期望最大化等。

所以我相信你的情况,你必须在创建算法之前调用initModule_video()