C++ OpenCV RGB 转灰色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9974239/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:27:30  来源:igfitidea点击:

OpenCV RGB to gray

c++opencv

提问by Ilan Reuven

I am doing a project for video monitoring.
I can't see the conversion from RGB to gray; I get a black window for the gray.
Could you please help me with the problem? (code attached)
Also, how can I get the difference between current frame and previous frame?
Thanks a lot. Ilan

我正在做一个视频监控项目。
我看不到从 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;  
}  

回答by sietschie

You need to convert each frame from color to gray scale. It does not get converted automatically if you do it once in the beginning. So you need to add

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

cvCvtColor(frame, gray, CV_BGR2GRAY);

into your while-loop after your call to cvQueryFrame.

调用后进入你的while循环cvQueryFrame

回答by karlphillip

There were a few problems with your code.

您的代码存在一些问题。

  • It was a mess and poorly idented;
  • When you need to check the return of a function, you should do it right after you call them. Ex: cvCaptureFromAVI();
  • As cvQueryFrame()might fail, you need to check it's return as well;
  • You forgot to execute the RGB -> GRAY conversion: cvCvtColor(frame, gray, CV_RGB2GRAY);before displaying the gray frame;
  • You also forgot to release the resources for the grayvideowindow;
  • 这是一团糟,很难辨认。
  • 当您需要检查函数的返回时,您应该在调用它们之后立即进行。例如:cvCaptureFromAVI();
  • 由于cvQueryFrame()可能会失败,您还需要检查它的返回值;
  • 您忘记执行 RGB -> GRAY 转换:cvCvtColor(frame, gray, CV_RGB2GRAY);在显示灰框之前;
  • 你也忘了释放grayvideo窗口的资源;

Isn't it easier to read/understand a code when it looks like this?

看起来像这样的代码是不是更容易阅读/理解?

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;  
}  

回答by Dawit

use one of below opencvfunctions based on you need:

opencv根据您的需要使用以下功能之一:

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