如何在OpenCV中捕获图像并以pgm格式保存?

时间:2010-06-25 04:24:37

标签: opencv capture pgm

我是一般的编程新手,我正在开发一个项目,我需要从我的网络摄像头捕获图像(可能使用OpenCV),并将图像保存为pgm文件。

最简单的方法是什么? Willow Garage提供了用于图像捕获的代码:

http://opencv.willowgarage.com/wiki/CameraCapture

使用此代码作为基础,我如何将其修改为:

  1. 每2秒从实时摄像头捕捉一张图像
  2. 将图像保存为pgm格式的文件夹
  3. 非常感谢您提供的任何帮助!

5 个答案:

答案 0 :(得分:5)

首先,请使用较新的网站 - opencv.org。当新用户查看旧引用,阅读旧文档并再次发布旧链接时,使用过时的引用会导致链式效应。

实际上没有理由使用旧的C API。相反,您可以使用更新的C ++接口,除其他外,它可以优雅地处理视频捕获。以下是VideoCapture上的文档示例的缩短版本:

#include "opencv2/opencv.hpp"

using namespace cv;

int main(int, char**)
{
    VideoCapture cap(0); // open the default camera
    if(!cap.isOpened())  // check if we succeeded
        return -1;

    for(;;)
    {
        Mat frame;
        cap >> frame; // get a new frame from camera
        // do any processing
        imwrite("path/to/image.png", frame);
        if(waitKey(30) >= 0) break;   // you can increase delay to 2 seconds here
    }
    // the camera will be deinitialized automatically in VideoCapture destructor
    return 0;
}

此外,如果您不熟悉编程,请考虑将 Python接口用于OpenCV - cv2 模块。 Python通常被认为比C ++更简单,使用它可以在交互式控制台中使用OpenCV函数。使用cv2捕获视频看起来像这样(从here采用的代码):

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()
    # do what you want with frame
    #  and then save to file
    cv2.imwrite('path/to/image.png', frame)
    if cv2.waitKey(30) & 0xFF == ord('q'): # you can increase delay to 2 seconds here
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

答案 1 :(得分:4)

由于ffriend的回答只是部分正确,我将添加更多(在C ++中)。该问题的作者明确要求导出到PGM(以8位存储每个像素的PXM文件格式)而不是PNG(如ffriend在他/她的回复中所述)。这里的主要问题是official documentation for imwrite根本不清楚这个问题:

对于PPM,PGM或PBM,它可以是二进制格式标志(CV_IMWRITE_PXM_BINARY),0或1.默认值为1.

如果我们用普通英语阅读句子,我们有一个选项列表: CV_IMWRITE_PXM_BINARY,0或1 。没有提到那些可以并且实际上应该合并!我不得不进行一些实验(我还需要为我的项目存储8位图像),最后得到了所需的解决方案:

std::vector<int> compression_params; // Stores the compression parameters

compression_params.push_back(CV_IMWRITE_PXM_BINARY); // Set to PXM compression
compression_params.push_back(0); // Set type of PXM in our case PGM
const std::string imageFilename = "myPGM.pgm"; // Some file name - C++ requires an std::string

cv::imwrite(imageFilename, myImageMatrix, compression_params); // Write matrix to file

我的调查也受到this问题的推动,其中作者(可能仍在)正在努力解决同一问题以及PXM格式的一些基本信息,您可以找到here

结果(仅图像的一部分)显示在下方:

P2
32 100
255
121 237  26 102  88 143  67 224 160 164 238   8 119 195 138  16 176 244  72 106  72 211 168  45 250 161  37   1  96 130  74   8
126 122 227  86 106 120 102 150 185 218 164 232 111 230 207 191  39 222 236  78 137  71 174  96 146 122 117 175  34 245   6 125
124 121 241  67 225 203 118 209 227 168 175  40  90  19 197 190  40 254  68  90  88 242 136  32 123 201  37  35  99 179 198 163
97 161 129  35  48 140 234 237  98  73 105  77 211 234  88 176 152  12  68  93 159 184 238   5 172 252  38  68 200 130 194 216
160 188  21  53  16  79  71  54 124 234  34  92 246  49   0  17 145 102  72  42 105 252  81  63 161 146  81  16  72 104  66  41
189 100 252  37  13  91  71  40 123 246  33 157  67  96  71  59  17 196  96 110 109 116 253  30  42 203  69  53  97 188  90  68
101  36  84   5  41  59  80   8 107 160 168   9 194   8  71  55 152 132 232 102  12  96 213  24 134 208   1  55  64  43  74  22
92  77  30  44 139  96  70 152 160 146 142   8  87 243  11  91  49 196 104 250  72  67 159  44 240 225  69  29  34 115  42   2
109 176 145  90 137 172  65  25 162  57 169  92 214 211  72  94 149  20 104  56  27  67 218  17 203 182   5 124 138   2 130  48
121 225  25 106  89  76  69 189  34  25 173   8 114  83  72  52 145 154  64  40  91   2 251  53 251 237  20 124  82   2 194  42 ...

这正是本案所要求的。您可以在顶部看到“P2”标记,并且值显然是0到255,正好是每像素8位。

答案 2 :(得分:1)

阅读大多数答案,但没有一个可以满足我的需要。 这将充当相机,可用于单击图片 我们可以将if(“ c”)条件更改为for循环,以在一定间隔后自动点击图片

   # -*- coding: utf-8 -*-
"""
Created on Sun Aug 12 12:29:05 2018

@author: CodersMine
"""


import cv2
"""
Run this if you are facing invalid images issue
cap.release()

"""
cap = cv2.VideoCapture(0)#0 is internal cam : 1 is external webcam
i=0 #to save all the clicked images
while(True):
    ret, frame = cap.read()
    cv2.imshow("imshow",frame)
    key=cv2.waitKey(30)
    if key==ord('q'):
        break
    if key==ord('c'):
        i+=1
        cv2.imshow("imshow2",frame)
        cv2.imwrite('C:/Users/codersmine/desktop/image'+str(i)+'.png', frame)
        print("Wrote Image")

# release the capture
cap.release()
cv2.destroyAllWindows()

答案 3 :(得分:-1)

我认为格式是从文件名的扩展名中选择的 - 所以假设你的opencv lib与相应的lib链接,你可以做类似的事情:(这是来自内存,可能不正确。)

CvCapture* capture = cvCaptureFromCam(0);
IplImage* frame = cvQueryFrame(capture);
while (1) {
    frame = cvQueryFrame(capture);
    cvSaveImage("foo.pgm", &frame);
    sleep(2);
}
cvReleaseImage(&frame);
cvReleaseCapture(&capture);

答案 4 :(得分:-1)

如果你不需要超过2秒的时间,那么只需在while(1)循环中设置sleep(2)或Sleep(2000),等待每次抓取前2秒,

使用cvSaveImage()编写图像只需将扩展名.pgm放在文件名上,它就会使用pgm。