【发布时间】:2017-04-07 23:10:11
【问题描述】:
我正在开发一个 iOS 项目。我需要检测实时视频上的彩色圆圈。
我正在使用CvVideoCameraDelegate。这是我的代码:
-(void)processImage:(cv::Mat &)image{
cv::medianBlur(image, image, 3);
Mat hvs;
cvtColor(image, hvs, COLOR_BGR2HSV);
Mat lower_red;
Mat upper_red;
inRange(hvs, Scalar(0, 100, 100), Scalar(10, 255, 255), lower_red);
inRange(hvs, Scalar(160, 100, 100), Scalar(179, 255, 255), upper_red);
Mat red_hue;
addWeighted(lower_red, 1, upper_red, 1, 0, red_hue);
GaussianBlur(red_hue, red_hue, cv::Size(9,9), 2,2);
HoughCircles(red_hue, circles, CV_HOUGH_GRADIENT, 1, red_hue.rows/8,100,20,0,0);
if(circles.size() != 0){
for(cv::String::size_type current = 0;current<circles.size();++current){
cv::Point center(std::round(circles[current][0]),std::round(circles[current][1]));
int radius = std::round(circles[current][2]);
cv::circle(image, center, radius, cv::Scalar(0, 255, 0), 5);
}
}
}
效果很好,但需要很多时间,而且视频有点滞后。
我想将我的代码放在另一个队列中,但我开始在这一行获得 EXC_BAD_ACCESS:cv::medianBlur(image, image, 3);。
我开始为这个项目使用objective-c,所以我有点难以理解幕后发生的事情,但我意识到image变量保存了那个Mat的地址(至少那是我的 C++ 知识说)所以当我到了执行代码的地步时,它不再存在。 (我说的对吗?)
比我试图解决这个问题。我已经添加了这个
Mat m;
image.copyTo(m);
在我的队列之前。但这导致了内存泄漏。 (为什么不自动释放呢?(再次,没有太多的obj-c知识)
然后我有了最后一个想法。我在队列的第一行添加了这一行:Mat m = image;。通过这种方式,我开始从 cv::Mat 内部获取 EXC_BAD_ACCES 并且它仍然滞后。这是我的代码现在的样子:
-(void)processImage:(cv::Mat &)image{
//First attempt
//Mat m;
//image.copyTo(m);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
Mat m = image; // second one
cv::medianBlur(m, m, 3);
Mat hvs;
cvtColor(m, hvs, COLOR_BGR2HSV);
Mat lower_red;
Mat upper_red;
inRange(hvs, Scalar(0, 100, 100), Scalar(10, 255, 255), lower_red);
inRange(hvs, Scalar(160, 100, 100), Scalar(179, 255, 255), upper_red);
Mat red_hue;
addWeighted(lower_red, 1, upper_red, 1, 0, red_hue);
GaussianBlur(red_hue, red_hue, cv::Size(9,9), 2,2);
HoughCircles(red_hue, circles, CV_HOUGH_GRADIENT, 1, red_hue.rows/8,100,20,0,0);
if(circles.size() != 0){
for(cv::String::size_type current = 0;current<circles.size();++current){
cv::Point center(std::round(circles[current][0]),std::round(circles[current][1]));
int radius = std::round(circles[current][2]);
cv::circle(m, center, radius, cv::Scalar(0, 255, 0), 5);
}
}
});
}
我将不胜感激任何有关 iOS 中视频处理的帮助或教程,因为我发现的所有内容都使用其他环境,或者没有花费足够的处理时间来需要优化。
【问题讨论】:
标签: ios objective-c opencv video-processing