【发布时间】:2017-11-06 13:09:24
【问题描述】:
我有一组来自相机的二进制图像,并由相机预先设定阈值。然后我使用 OpenCV 在每个图像中查找轮廓以及轮廓中心的坐标。
但我的问题是,这种过程非常缓慢。相机以 170 fps 的速度工作,分辨率为 2048*1088。
我知道当我实时执行此操作时数据量很大。有什么好的库可以用来加速它,因为我需要的只是坐标。我需要丢弃所有灰度信息,只提取每个图像中轮廓中心的坐标。
如果有人能提供我和想法,我将不胜感激。
根据cmets的要求,我的部分代码在这里添加:
图像采集部分
#include <opencv2\opencv.hpp>
#include <stdio.h>
#include "xiApiPlusOcv.hpp"
#include <ctime>
xiAPIplusCameraOcv cam;
Mat frame;
vector<Mat> frames;
...
cam.StartAcquisition();
startTime = clock();
for (int j = 0; j < 600; j++)
{
frame = cam.GetNextImageOcvMat();
frames.push_back(frame.clone());
frame.release();
}
cam.StopAcquisition();
cam.Close();
我使用的是 XIMEA 的 CMOS 单声道相机,在这里我通过相机的 RAM 缓冲采样了 600 帧。采集种子最高可达 170 fps。以及我在此之后放置的所有其他处理:
vector<Mat> masks(frames.size());
for (int s = 0; s < frames.size(); s++)
{
cvtColor(frames[s], masks[s], CV_GRAY2BGR);
vector<Vec4i> hierarchy;
vector<vector<Point> > contours;
findContours(frames[s], contours, hierarchy, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
vector<Moments> M(contours.size());
vector<Point2f> MC(contours.size());
for (size_t i = 0; i < contours.size(); i++)
{
M[i] = moments(contours[i]);
}
for (size_t i = 0; i < contours.size(); i++)
{
MC[i] = Point2f(M[i].m10 / M[i].m00, M[i].m01 / M[i].m00);
}
for (size_t i = 0; i < contours.size(); ++i)
{
// Calculate the area of each contour
double area = contourArea(contours[i]);
// Ignore contours that are too small or too large
if (area < 1e2 || 1e5 < area) continue;
// Draw each contour only for visualisation purposes
drawContours(masks[s], contours, static_cast<int>(i), Scalar(0, 0, 255), 2, 8, hierarchy, 0);
circle(masks[s], MC[i], 4, Scalar(0, 0, 255), -1);
}
}
如果我离线查找轮廓,就像上面显示的那样,我对结果很满意。但只能录制很短的视频,比如几分钟,这意味着无法进行更长时间的监控。
如果我将处理与采集一起移动到无限循环中,它只会给我 30-40 fps,这是不可接受的。
我的 ROI 中所需的轮廓数约为 10。 我的应用程序的最终目标是在大约 50m 的距离处监视框架内的几个飞行物体。我认为它们的坐标才是最重要的。
我在配备 i7-5500U 2.4GHz CPU 的笔记本电脑上运行它。
更新: 这是在非常基本的试验期间监控大黄蜂的相机的二值化图像。在正常试验中,相机框架内可能有数十只飞虫。 one binarized frame of the captured bumble bee
【问题讨论】:
-
请提供您的环境的示例图像和详细信息。每张图片中是否有多个对象?
-
"170 fps,分辨率为 2048*1088。"我不确定它是否可以变得更快。也许如果它是多线程的或者在 GPU 上移动就更好了。
-
显示您的代码也会有所帮助
-
它使用什么接口以 3Gb/s 运行?什么 CPU 正在处理你的帧?
-
您的应用程序真的在 2K 分辨率下需要 170fps 吗?我建议您在进行任何处理之前降低 fps 或分辨率。如果需要,在处理后重新缩放和插入轮廓中心坐标。 OpenCV 可能已经是你最好的选择了。