我正在尝试使用OpenCV 2.4.9检测iOS中的人物轮廓。我使用背景减法使用高斯混合物来实现它。参考:http://personal.ee.surrey.ac.uk/Personal/R.Bowden/publications/avbs01/avbs01.pdf和http://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中的这个类是抽象的。
答案 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()
。