使用 OpenCv 延迟播放 AVI
我通过 opencv 播放 avi,并尝试对视频进行一些圆圈检测。仅仅播放视频就很精彩,但是当我尝试检测圆圈时,视频速度变慢。有什么办法可以让视频播放速度接近录制时的速度吗?
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#include <math.h>
int main(int argc, char** argv)
{
IplImage*img;
int key=0;
CvCapture*capture = cvCaptureFromAVI("C:\\Users\\Nathan\\Desktop\\SnookVid.wmv");
if(!capture) return 1;
int fps = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
cvNamedWindow("circles", 0);
while(key!='q'){
img = cvQueryFrame( capture );
if(!img) break;
IplImage* gray = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
//IplImage* hsv = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
CvMemStorage* storage = cvCreateMemStorage(0);
//covert to grayscale
cvCvtColor(img, gray, CV_BGR2GRAY);
// This is done so as to prevent a lot of false circles from being detected
cvSmooth(gray, gray, CV_GAUSSIAN, 3, 5);
IplImage* canny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
//IplImage* rgbcanny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3);
//cvCanny(gray, canny, 50, 70, 3);
//detect circles
CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 1, 27, 70, 40,0,0);
//cvCvtColor(canny, rgbcanny, CV_GRAY2BGR);
//cvCvtColor(img,hsv, CV_BGR2HSV);
//draw all detected circles
float* p;
CvScalar s;
int num_red = 22;
for (int i = 0; i < circles->total; i++)
{
// round the floats to an int
p = (float*)cvGetSeqElem(circles, i);
cv::Point center(cvRound(p[0]), cvRound(p[1]));
int radius = cvRound(p[2]);
//uchar* ptr;
//ptr = cvPtr2D(img, center.y, center.x, NULL);
//printf("B: %d G: %d R: %d\n", ptr[0],ptr[1],ptr[2]);
s = cvGet2D(img,center.y, center.x);//colour of circle
printf("B: %f G: %f R: %f\n",s.val[0],s.val[1],s.val[2]);
}
Im playing an avi through opencv and im trying to do some circle detection on the video. just playing the video is grand but when i try to detect circles, the video slows down. is there any way to get keep the video playing near the speed it was recorded at?
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#include <math.h>
int main(int argc, char** argv)
{
IplImage*img;
int key=0;
CvCapture*capture = cvCaptureFromAVI("C:\\Users\\Nathan\\Desktop\\SnookVid.wmv");
if(!capture) return 1;
int fps = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
cvNamedWindow("circles", 0);
while(key!='q'){
img = cvQueryFrame( capture );
if(!img) break;
IplImage* gray = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
//IplImage* hsv = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
CvMemStorage* storage = cvCreateMemStorage(0);
//covert to grayscale
cvCvtColor(img, gray, CV_BGR2GRAY);
// This is done so as to prevent a lot of false circles from being detected
cvSmooth(gray, gray, CV_GAUSSIAN, 3, 5);
IplImage* canny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
//IplImage* rgbcanny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3);
//cvCanny(gray, canny, 50, 70, 3);
//detect circles
CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 1, 27, 70, 40,0,0);
//cvCvtColor(canny, rgbcanny, CV_GRAY2BGR);
//cvCvtColor(img,hsv, CV_BGR2HSV);
//draw all detected circles
float* p;
CvScalar s;
int num_red = 22;
for (int i = 0; i < circles->total; i++)
{
// round the floats to an int
p = (float*)cvGetSeqElem(circles, i);
cv::Point center(cvRound(p[0]), cvRound(p[1]));
int radius = cvRound(p[2]);
//uchar* ptr;
//ptr = cvPtr2D(img, center.y, center.x, NULL);
//printf("B: %d G: %d R: %d\n", ptr[0],ptr[1],ptr[2]);
s = cvGet2D(img,center.y, center.x);//colour of circle
printf("B: %f G: %f R: %f\n",s.val[0],s.val[1],s.val[2]);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试减小图像大小,然后使用 pyrDown 或 调整大小。
如果要将检测到的圆与原始图像一起使用,请将半径和中心乘以除图像的系数。缩小 2 倍的缩放比例应该可以使处理时间(减去执行缩放操作所需的时间)加快 2-4 倍。
下面是一个简短的示例,说明了如何进行此操作:
最后,这是我使用的测试图像:

以下是我进行
HoughCircles
检测的时间:大致上,加速了 3 倍! :)
Try reducing the image size before processing it with
HoughCircles
with either pyrDown or resize.If you want to use the detected circles with the original image, multiply the radius and center by the factor you divided the image. A 2x scale reduction should give you a 2-4x speedup in processing time minus the time it takes to perform the scale operation.
Below is a short example of how you might go about this:
Finally, here is the test image I used:

Here are the timings I got for a
HoughCircles
detection:Roughly, a 3x speedup! :)
你可以尝试一下 mevatron 的建议,它肯定会有所作为,这就是我投票的原因。
但您需要清楚的一件事是:视频速度变慢不是源代码中的错误,也不是 OpenCV 中的错误。这种效果是由于您的 CPU 必须花费处理时间来对视频的每一帧执行圆形检测而造成的。您的 CPU 根本无法足够快地执行此任务,无法给您带来实时的感觉。
问题的标题有点误导,因为你不只是用 OpenCV 播放 AVI。
You can try mevatron's suggestion, it will certainly make a difference and that's why I upvoted it.
But one thing that needs to be clear to you is: the video slowing down is not a bug of in your source code, its also not a bug in OpenCV. This effect is caused by your CPU having to spend processing time to perform the circle detection for every frame of the video. Your CPU simply can't perform this task fast enough to give you the sensation of real-time.
The title of the question is a bit misleading since you are not just playing an AVI with OpenCV.