【问题标题】:Saving an image in OpenCV在 OpenCV 中保存图像
【发布时间】:2010-10-25 11:59:31
【问题描述】:

我是 OpenCV 的新手,正在尝试捕获图像,然后将其保存到文件中。我在下面发布代码供您参考。

正在保存 jpg 文件,但它是黑色的。

// Capture the Image from the webcam
CvCapture *pCapturedImage = cvCreateCameraCapture(0);

// Get the frame
IplImage *pSaveImg = cvQueryFrame(pCapturedImage);

// Save the frame into a file
cvSaveImage("test.jpg". ,pSaveImg); // A JPG FILE IS BEING SAVED
                                    // OF 6KB , BUT IT IS BLACK

所有功能都成功了。我在 XP 和 Vista 中都尝试过上面的代码——结果都是黑色图像。请让我知道我错过了什么。

【问题讨论】:

    标签: c++ opencv computer-vision


    【解决方案1】:

    如果你使用C++,最好使用C++接口

    using namespace cv;
    // Capture the Image from the webcam
    VideoCapture cap(0);
    
    // Get the frame
    Mat save_img; cap >> save_img;
    
    if(save_img.empty())
    {
      std::cerr << "Something is wrong with the webcam, could not get frame." << std::endl;
    }
    // Save the frame into a file
    imwrite("test.jpg", save_img); // A JPG FILE IS BEING SAVED
    

    【讨论】:

    • 我在关注 OpenCV 教程,这有什么不同吗?
    【解决方案2】:

    有时第一次调用 cvQueryFrame() 会返回一个空图像。试试:

    IplImage *pSaveImg = cvQueryFrame(pCapturedImage);
    pSaveImg = cvQueryFrame(pCapturedImage);
    

    如果不起作用,请尝试自动选择捕获设备:

    CvCapture *pCapturedImage = cvCreateCameraCapture(-1);
    

    或者您可以尝试选择其他 n=1,2,3...的捕获设备...

    CvCapture *pCapturedImage = cvCreateCameraCapture(n);
    

    PS:另外,我认为查看您的变量名时捕获的图像存在误解。变量 pCapturedImage 不是 Image 它是 Capture。您始终可以从捕获中“读取”图像。

    【讨论】:

    • 我仍然得到黑色图像。我什至在while循环中尝试过这个;按下“q”时会中断。我也使用 cvVideoWriter ,以便将捕获的帧保存到视频文件(avi)中,我仍然得到一个包含黑色内容的文件。我是否需要安装任何编解码器才能使 OpenCV 正常运行。谢谢,Sujay 我得到了一个黑色的 jpg,黑色
    • 我不确定能否进一步帮助您。
    【解决方案3】:

    根据我的经验,当SaveImage 被赋予一个位深不同于 8 位的矩阵时,OpenCV 会写入一个黑色图像。事实上,这是有记录的:

    仅 8 位单通道或 3 通道 (带有“BGR”通道顺序)图像可以 使用此功能保存。如果 格式、深度或通道顺序是 不同,使用cvCvtScalecvCvtColor 转换之前 保存,或使用通用cvSave 将图像保存为 XML 或 YAML 格式。

    在您的情况下,您可以先调查捕获的图像类型,更改捕获属性(我想CV_CAP_PROP_CONVERT_RGB 可能很重要)或之后手动转换。

    这是一个如何使用 OpenCV 转换为 8 位表示的示例。 cc 这里是CV_32FC1 类型的原始矩阵,cc8u 是它的缩放版本,实际上是由SaveImage 编写的:

    # I want to save cc here
    cc8u = CreateMat(cc.rows, cc.cols, CV_8U)
    ccmin,ccmax,minij,maxij = MinMaxLoc(cc)
    ccscale, ccshift = 255.0/(ccmax-ccmin), -ccmin
    CvtScale(cc, cc8u, ccscale, ccshift)
    SaveImage("cc.png", cc8u)
    

    (对不起,这是 Python 代码,但应该很容易翻译成 C/C++)

    【讨论】:

      【解决方案4】:

      对不起,如果这太明显了。您确定 OpenCV 可以正确看到和检测到网络摄像头吗 换句话说,当您将捕获的帧重定向到“highGui”窗口时,您会得到图像吗?比如像这样:

       frame = cvQueryFrame( capture );
       cvNamedWindow( "myWindow", CV_WINDOW_AUTOSIZE );
       cvShowImage( "myWindow", frame );
      

      【讨论】:

      • 这段代码也给了我一个黑色的图像。我需要安装编解码器,还是有任何依赖项 我的网络摄像头是 startng ,但是有一个黑色图像
      【解决方案5】:

      我知道问题所在! 你只是在“test.jpg”后面加了一个点!

      cvSaveImage("test.jpg".,pSaveImg);

      我可能错了,但我认为它不好!

      【讨论】:

        【解决方案6】:

        我的 Microsoft 网络摄像头也有类似问题。我查看了Matlab中的图像采集工具箱,发现最大支持的分辨率为640*480。

        我只是在openCV中更改了代码并添加了

        cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 352); 
        cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 288);
        

        在 cvQueryFrame 函数之前,它是下一个支持的分辨率并更改了在保存图像之前跳过了一些初始帧并最终让它工作。

        我正在分享我的工作代码

        #include "cv.h" 
        #include "highgui.h" 
        #include <stdio.h> 
        
        
        
        using namespace cv;
        using namespace std;
        
        int main() 
        {
        CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );
        cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 352); 
        cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 288)
        
        
         // Get one frame
        IplImage* frame;
        
        for (int i = 0; i < 25; i++) 
        {
        frame = cvQueryFrame( capture );
        }
        
        
        printf( "Image captured \n" );  
        //IplImage* RGB_frame = frame;
        //cvCvtColor(frame,RGB_frame,CV_YCrCb2BGR);
        //cvWaitKey(1000);
        cvSaveImage("test.jpg" ,frame);
        //cvSaveImage("cam.jpg" ,RGB_frame);
        
        printf( "Image Saved \n" );
        
        //cvWaitKey(10);
        
        // Release the capture device housekeeping
        cvReleaseCapture( &capture );
        //cvDestroyWindow( "mywindow" );
        return 0;
        }
        

        我的建议:

        1. 不要以最高分辨率抓取帧
        2. 跳过一些帧以正确初始化相机

        【讨论】:

          【解决方案7】:

          我使用以下代码来捕获图像:

          CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );
          if(!capture) error((char*)"No Capture");
          IplImage *img=cvQueryFrame(capture);
          

          我知道这肯定有效

          【讨论】:

            【解决方案8】:

            我建议你运行 OpenCV 健全性检查

            它是一系列小可执行文件,位于opencv的bin目录中。

            它会检查你的相机是否正常

            【讨论】:

            • 感谢您的信息。我会检查一下。但我认为我的相机还可以,因为使用机器人工具 RoboRealm,我可以看到我的图像和图片。我还使用网络摄像头进行视频会议,人们可以看到我。
            • 我尝试在我的上网本上运行 opencv,相机通常工作正常,但由于某种原因,它没有通过健全性检查。我也不能让它工作
            【解决方案9】:

            很抱歉提出一个旧帖子,但我想为遇到此线程的任何人提供另一个答案。

            我遇到了同样的问题。无论我做什么,图像看起来都是全黑的。我尝试对 cvQueryFrame 进行多次连续调用,并注意到当我进行 5 次或更多时,我可以看到图像。于是我开始一一删除电话,看看“断点”在哪里。我最终发现,当我删除每个呼叫时,图像变得越来越暗。只打一个电话就可以得到一个几乎全黑的图像,但如果我仔细观察,我可以辨认出我的图像。

            我连续尝试了 10 次调用来测试我的理论,果然,考虑到我在一个光线昏暗的房间里,我得到了一个非常明亮的图像。希望这与您遇到的问题相同。

            我对成像了解不多,但看起来多次连续调用 cvQueryFrame 会增加相机的曝光时间。这绝对可以解决问题,尽管它似乎不是最优雅的解决方案。我将看看是否可以找到一个可以增加曝光的参数,或者是否可以找到其他可以使我的图像变亮的参数。

            祝你好运!

            【讨论】:

            • 谢谢 Sayn,有时间我会试试的
            • 这与曝光无关;这是您的相机自动调整到当前的房间照明。由于您的相机软件补偿的光线不多,但这不是瞬时的。
            【解决方案10】:

            SaintLewis 是对的。当您使用 cvCaptureFromCAM 激活相机时,尚未调整自动白平衡(这是一个缓慢的过程),因此您可能会在第一帧上获得大部分白色或大部分黑色(取决于相机和您的光照条件)。 当场景的闪电突然变化时也会发生同样的情况。 打开相机后稍等片刻,冲洗缓冲区即可。

            【讨论】:

              【解决方案11】:

              我在 Windows Vista 上遇到了同样的问题,我只是在 cvQueryFrame 之前添加了这段代码:

              cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 720);
              cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 480);
              

              【讨论】:

                【解决方案12】:

                希望这将保存您网络摄像头中的图像

                #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()
                {
                   VideoCapture cap(0);
                
                   Mat save_img;
                
                   cap >> save_img;
                
                   char Esc = 0;
                
                   while (Esc != 27 && cap.isOpened()) {        
                    bool Frame = cap.read(save_img);        
                    if (!Frame || save_img.empty()) {       
                        cout << "error: frame not read from webcam\n";      
                        break;                                              
                    }
                    namedWindow("save_img", CV_WINDOW_NORMAL);  
                    imshow("imgOriginal", save_img);            
                    Esc = waitKey(1);
                }
                imwrite("test.jpg",save_img); 
                }
                

                【讨论】:

                  【解决方案13】:

                  根据我的经验,使用时捕获的前几帧:

                  frame = cvQueryFrame( capture );

                  往往是空白的。您可能需要稍等片刻(大约 3 秒)然后尝试捕捉图像。

                  【讨论】:

                    【解决方案14】:

                    我认为,只是相机没有在第一帧初始化。 尝试在 10 帧后保存图像。

                    【讨论】:

                      【解决方案15】:

                      在 OSX 上,仅当我提供 cvSaveImage 的完整路径时,保存视频帧和静止图像才对我有用:

                      cvSaveImage("/Users/nicc/image.jpg",img);
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2018-12-14
                        • 2017-10-13
                        相关资源
                        最近更新 更多