2012-04-02 92 views
1

我正在做一个视频监控项目。
我看不到从RGB到灰色的转换;我得到一个灰色的黑色窗口。
你能帮我解决这个问题吗? (附代码)
另外,如何获得当前帧和前一帧之间的差异?
非常感谢。 宜兰OpenCV RGB到灰色

#include "stdafx.h" 
#include <stdio.h> // For printf 
#include <cv.h> 
#include <cxcore.h> 
#include <highgui.h>  

int main() 
{ 


    int key = 0; 



    CvCapture* capture = cvCaptureFromAVI("macroblock.mpg"); 
    IplImage* frame = cvQueryFrame(capture); 
    IplImage* gray = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1); 
    cvCvtColor(frame, gray, CV_RGB2GRAY); 

     if (!capture) 

    { 
     fprintf(stderr, "Cannot open AVI!\n"); 
     return 1; 
     } 
      int fps = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS); 

      cvNamedWindow("video", CV_WINDOW_AUTOSIZE); 
     cvNamedWindow("grayvideo", CV_WINDOW_AUTOSIZE); 

     while(key != 'x') 
    { 
     frame = cvQueryFrame(capture); 




    if(key==27)break; 
    cvShowImage("video",frame); 
    cvShowImage("grayvideo",gray); 


      key = cvWaitKey(1000/fps); 
    } 
      cvDestroyWindow("video"); 
    cvReleaseCapture(&capture); 

    return 0; 
} 
+0

你应该学习C++的API OpenCV的。使用cv :: Mat对象的图像,它有自己的析构函数(和ref计数器),你不需要手动释放IplImage *,你忘了你的代码。 – Eric 2012-04-02 11:48:52

+0

如果此问题已成功解答,请考虑选择正确答案,方法是单击它旁边的复选框。如果不是,请考虑添加自己的答案。 – karlphillip 2012-06-05 23:32:31

回答

3

,需要在每个帧转换从颜色到灰度。如果您在开始时执行一次,它不会自动转换。所以,你需要添加

cvCvtColor(frame, gray, CV_BGR2GRAY); 

到您的while循环您的来电cvQueryFrame后。

+0

感谢它的工作:) – 2012-04-02 19:15:37

+0

我可以做这个代码中的当前帧与前一帧之间的区别?我如何从当前帧减少前一个并在窗口上显示结果? – 2012-04-02 19:23:17

+0

我很确定BGR是OpenCV中的默认像素格式。我看到大多数示例使用CV_RGB2GRAY,但是imho(除非我非常错误),最好使用CV_BGR2GRAY – 2013-08-19 11:22:40

1

您的代码存在一些问题。

  • 这是一个混乱,很差的想法;
  • 当你需要检查一个函数的返回值时,你应该在调用它之后立即执行它。例如:cvCaptureFromAVI();
  • 由于cvQueryFrame()可能会失败,因此您需要检查它是否返回;
  • 您在显示灰色框架之前忘记了执行RGB-> GRAY转换:cvCvtColor(frame, gray, CV_RGB2GRAY);;
  • 你也忘了释放资源的grayvideo窗口;

当它看起来像这样是否更容易阅读/理解代码?

int main() 
{  
    CvCapture* capture = cvCaptureFromAVI("macroblock.mpg"); 
    if (!capture) 
    { 
     fprintf(stderr, "Cannot open AVI!\n"); 
     return 1; 
    } 

    int fps = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS); 
    printf("FPS: %d\n", fps); 

    cvNamedWindow("video", CV_WINDOW_AUTOSIZE); 
    cvNamedWindow("grayvideo", CV_WINDOW_AUTOSIZE); 

    int key = 0; 
    IplImage* gray = NULL; 
    IplImage* prev_frame = NULL; 

    while(key != 'x') 
    { 
     frame = cvQueryFrame(capture); 
     if (!frame) 
     { 
      // print error and abort the loop 
      break; 
     } 

     cvShowImage("video", frame); 

     if (!gray) // allocate space for the GRAY frame only once 
     { 
      gray = cvCreateImage(cvGetSize(frame), frame->depth,1); 
     } 
     cvCvtColor(frame, gray, CV_RGB2GRAY); // convert RGB frame to GRAY 
     cvShowImage("grayvideo", gray); 

     if (!prev_frame) // allocate space for the GRAY frame only once 
     { 
      prev_frame = cvCreateImage(cvGetSize(frame), frame->depth,1); 
      cvCopy(frame, prev_frame, 0); 
     } 

     // perform process to compute the "difference" of the current 
     // and previous frames: 
     // <add your code here> 

     // then, update prev_frame now so in the next iteration it holds the previous frame 
     cvCopy(frame, prev_frame, 0); 

     key = cvWaitKey(1000/fps); 
     if (key==27) // ESC was pressed 
      break; 
    } 

    cvDestroyWindow("video"); 
    cvDestroyWindow("grayvideo"); 

    cvReleaseCapture(&capture); 

    if (gray) 
     cvReleaseImage(&gray); 

    if (prev_frame) 
     cvReleaseImage(&prev_frame); 

    return 0; 
} 
+0

是的,但这个代码没有运行 – 2012-04-02 19:36:09

+0

你有一个想法如何做2帧之间的差异,例如当前帧与前一帧?谢谢 – 2012-04-02 19:41:45

+0

我刚刚更新了代码来存储前一帧。需要编写2帧*之间*差的计算,无论对您而言意味着什么。关于如何检测此论坛中帧之间的差异存在一系列问题。您可以使用搜索框来帮助您并找到合适的技巧。祝你好运。 – karlphillip 2012-04-02 20:07:10

0

使用下面根据你opencv功能之一需要:

subtract(img_current,img_prev, img_diff); 
absdiff(img_current, img_prev, img_diff); 
+1

嗨Dawit,你能提供更多的细节,或者你的代码的解释吗? – furins 2013-04-01 12:49:01