C++ 如何知道图像在 OpenCV 中是否为 RGB?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26059507/
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-28 11:30:21  来源:igfitidea点击:

How can I know if a image is RGB in OpenCV?

c++opencvimage-processing

提问by Graver

I've made a program in c++ using OpenCV library. The program record video from webcam and then split it in frames. I want to know if the frames are in RGB beacuse i want to access the RGB properties of every pixel. The codec for capture is CV_FOURCC('M','J','P','G'). How can i get the frames in RGB colorspace?

我已经使用 OpenCV 库在 C++ 中制作了一个程序。该程序从网络摄像头录制视频,然后将其分割成帧。我想知道帧是否在 RGB 中,因为我想访问每个像素的 RGB 属性。捕获的编解码器是 CV_FOURCC('M','J','P','G')。如何获得 RGB 色彩空间中的帧?

int main() {

Mat image;
VideoCapture cap(0);
cap.set(CV_CAP_PROP_FPS, 10);

if ( !cap.isOpened() ) {
    cout << "ERROR : Cannot open the video file"<<endl;
    return -1;
}
namedWindow("MyWindow", CV_WINDOW_AUTOSIZE);

double dWidth   = cap.get(CV_CAP_PROP_FRAME_WIDTH);
double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
cout << "Frame size :" << dWidth << "x" << dHeight << endl;
Size frameSize(static_cast<int>(dWidth), static_cast<int>(dHeight));
VideoWriter oVideoWriter("E:/myVideo.avi", CV_FOURCC('M', 'J', 'P', 'G'), 10, frameSize, true);

if (!oVideoWriter.isOpened()) {
    cout << "ERROR : Failed to write the video"<<endl;
    return - 1;
}

while (1) {
    Mat image;
    bool bSuccess = cap.read(image);

    if (!bSuccess) {
        cout << "ERROR : Cannot read a frame from video file" << endl;
        break;
    }
    oVideoWriter.write(image);
    imshow("MyWindow", image);

    if (waitKey(10) == 27) {

        saveImages();


            cout << "ESC key is pressed by user" << endl;
            break


    }
}
return 0;
}




int saveImages() {  



CvCapture *capture = cvCaptureFromFile("E:/myVideo.avi");
if(!capture) 
{
    cout<<"!!! cvCaptureFromAVI failed (file not found?)"<<endl;
    return -1; 
}

int fps = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);


IplImage* frame = NULL;
int frame_number = 0;
char key = 0;   

while (key != 'q') 
{

    frame = cvQueryFrame(capture);       
    if (!frame) 
    {
        cout<<"!!! cvQueryFrame failed: no frame"<<endl;
        break;
    }       

    char filename[100];
    strcpy(filename, "frame_");

    char frame_id[30];
    _itoa(frame_number, frame_id, 10);
    strcat(filename, frame_id);
    strcat(filename, ".jpg");

    printf("* Saving: %s\n", filename);

    if (!cvSaveImage(filename, frame))
    {
        cout<<"!!! cvSaveImage failed"<<endl;
        break;
    }

    frame_number++;

    key = cvWaitKey(1000 / fps);
}


cvReleaseCapture(&capture);

return 0;
}

回答by karlphillip

When OpenCV loads colored images (i.e. 3 channel) from the disk, camera, or a video file, the image data will be stored in the BGRformat. This is a simple test that you can do:

当 OpenCV 从磁盘、相机或视频文件加载彩色图像(即 3 通道)时,图像数据将以BGR格式存储。这是您可以执行的简单测试:

/* Code using the C++ API */

cv::VideoCapture cap(0);
if (!cap.isOpened()) {
    std::cout << "!!! Failed to open webcam" << std::endl;
    return -1;
}

if (!cap.read(frame)) {
    std::cout << "!!! Failed to read a frame from the camera" << std::endl;
    return -1;
}

bool is_colored = false;
if (frame.channels() == 3) {
    is_colored = true;
}

// Do something with is_colored
// ...

Unless you have a weird camera, the frames will always be colored (and as result, stored as BGR).

除非你有一个奇怪的相机,否则帧将始终是彩色的(因此,存储为 BGR)。

When cv::imwrite()(C++ API) or cvSaveImage()(C API) are called, OpenCV does the proper magic tricks to ensure the data is saved in a compatible way with requested output format (JPG, PNG, AVI, etc) and during this process it automatically converts the data to RGB if it needs to.

cv::imwrite()(C++ API) 或cvSaveImage()(C API) 被调用时,OpenCV 会执行适当的魔术来确保数据以与请求的输出格式(JPG、PNG、AVI 等)兼容的方式保存,并在此过程中自动转换如果需要,将数据转换为 RGB。

Nevertheless, if for some reason you need to convert the image to RGB you can call:

尽管如此,如果由于某种原因您需要将图像转换为 RGB,您可以调用:

cv::Mat img_rgb;
cv::cvtColor(frame, img_rgb, CV_BGR2RGB);  

Please note that OpenCV has a C APIand also a C++ API, and they shouldn't be mixed:

请注意,OpenCV 有一个C API和一个C++ API,它们不应该混合使用:

  • If you use IplImagethen stick with the rest of the C API.

  • If you decide to go with cv::Mat, then keep using the C++ API.

  • 如果您使用,IplImage则坚持使用 C API 的其余部分。

  • 如果您决定使用cv::Mat,请继续使用 C++ API。

There are different ways to access the pixels of a cv::Mat, here is one of them:

有多种方法可以访问 a 的像素,以下cv::Mat是其中一种:

unsigned char* pixels = (unsigned char*)(frame.data);
for (int i = 0; i < frame.rows; i++)
{
    for (int j = 0; j < frame.cols; j++)
    {
        char b = pixels[frame.step * j + i] ;
        char g = pixels[frame.step * j + i + 1];
        char r = pixels[frame.step * j + i + 2];
    }
}