2

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

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

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

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

  1. 每 2 秒从实时摄像头捕获一张图像
  2. 将图像保存到 pgm 格式的文件夹中

非常感谢您提供的任何帮助!

4

5 回答 5

7

首先,请使用较新的站点 - 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看起来像这样的视频(从这里采用的代码):

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()
于 2013-12-25T01:14:01.790 回答
4

由于 ffriend 的回答只是部分正确,我将添加更多内容(在 C++ 中)。这个问题的作者明确要求导出到 PGM(以 8 位存储每个像素的 PXM 文件格式)而不是 PNG(正如 ffriend 在他/她的回复中描述的那样)。这里的主要问题是 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

我的调查也受到这个问题的推动,作者在这个问题上(也许仍然是)在同一个问题上苦苦挣扎,还有一些关于 PXM 格式的基本信息,你可以在这里找到。

结果(仅部分图像)如下所示:

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 位。

于 2014-05-22T09:06:21.760 回答
0

阅读大多数答案,但没有一个能满足我的需求。这将充当相机,可用于单击图片我们可以将 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()
于 2018-08-12T08:50:03.600 回答
-1

我相信格式是从文件名的扩展名中选择的 - 因此假设您的 opencv 库与适当的库链接,您可以执行以下操作:(这是来自内存,可能不正确。)

CvCapture* capture = cvCaptureFromCam(0);
IplImage* frame = cvQueryFrame(capture);
while (1) {
    frame = cvQueryFrame(capture);
    cvSaveImage("foo.pgm", &frame);
    sleep(2);
}
cvReleaseImage(&frame);
cvReleaseCapture(&capture);
于 2010-06-25T04:30:25.867 回答
-1

如果您不需要超精确的 2 秒,那么只需在 while(1) 循环中放置一个 sleep(2) 或 Sleep(2000) 以在每次抓取前等待 2 秒,

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

于 2010-06-25T04:30:56.873 回答