使用 OpenCv 延迟播放 AVI

发布于 2024-12-25 20:58:59 字数 1812 浏览 4 评论 0原文

我通过 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

So要识趣 2025-01-01 20:58:59

尝试减小图像大小,然后使用 pyrDown调整大小

如果要将检测到的圆与原始图像一起使用,请将半径和中心乘以除图像的系数。缩小 2 倍的缩放比例应该可以使处理时间(减去执行缩放操作所需的时间)加快 2-4 倍。

下面是一个简短的示例,说明了如何进行此操作:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

using namespace std;
using namespace cv;


int main(int argc, char** argv)
{
    Mat circleBig = imread("circle.png", 0);
    Mat circleSmall;

    double scale = 2.0;

    // INTER_NEAREST is crude, but very fast; you may need INTER_LINEAR here...
    resize(circleBig, circleSmall, Size(0, 0), 1.0 / scale, 1.0 / scale, cv::INTER_NEAREST);

    cvtColor(circleBig, circleBig, CV_GRAY2RGB);

    vector<Vec3f> circles;
    HoughCircles(circleSmall, circles, CV_HOUGH_GRADIENT, 2, circleSmall.rows >> 2, 200, 100 );

    for( size_t i = 0; i < circles.size(); i++ )
    {
         Point center(cvRound(circles[i][0]), cvRound(circles[i][3]));
         int radius = cvRound(circles[i][4]);
         // draw the circle center
         circle( circleBig, scale*center, 3, Scalar(0,255,0), -1, 8, 0 );
         // draw the circle outline
         circle( circleBig, scale*center, scale*radius, Scalar(0,0,255), 3, 8, 0 );
    }

    imshow("circleBig", circleBig);
    waitKey();

    return 0;
}

最后,这是我使用的测试图像:
circle.png

以下是我进行 HoughCircles 检测的时间:

640x480 time: 0.0127101
320x240 time: 0.00408843

大致上,加速了 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:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

using namespace std;
using namespace cv;


int main(int argc, char** argv)
{
    Mat circleBig = imread("circle.png", 0);
    Mat circleSmall;

    double scale = 2.0;

    // INTER_NEAREST is crude, but very fast; you may need INTER_LINEAR here...
    resize(circleBig, circleSmall, Size(0, 0), 1.0 / scale, 1.0 / scale, cv::INTER_NEAREST);

    cvtColor(circleBig, circleBig, CV_GRAY2RGB);

    vector<Vec3f> circles;
    HoughCircles(circleSmall, circles, CV_HOUGH_GRADIENT, 2, circleSmall.rows >> 2, 200, 100 );

    for( size_t i = 0; i < circles.size(); i++ )
    {
         Point center(cvRound(circles[i][0]), cvRound(circles[i][3]));
         int radius = cvRound(circles[i][4]);
         // draw the circle center
         circle( circleBig, scale*center, 3, Scalar(0,255,0), -1, 8, 0 );
         // draw the circle outline
         circle( circleBig, scale*center, scale*radius, Scalar(0,0,255), 3, 8, 0 );
    }

    imshow("circleBig", circleBig);
    waitKey();

    return 0;
}

Finally, here is the test image I used:
circle.png

Here are the timings I got for a HoughCircles detection:

640x480 time: 0.0127101
320x240 time: 0.00408843

Roughly, a 3x speedup! :)

爱你不解释 2025-01-01 20:58:59

你可以尝试一下 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文