2012-04-02 94 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