How do I capture images in OpenCV and saving in pgm format?

廉价感情. 提交于 2019-12-04 04:56:29

问题


I am brand new to programming in general, and am working on a project for which I need to capture images from my webcam (possibly using OpenCV), and save the images as pgm files.

What's the simplest way to do this? Willow Garage provides this code for image capturing:

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

Using this code as a base, how might I modify it to:

  1. capture an image from the live cam every 2 seconds
  2. save the images to a folder in pgm format

Thanks so much for any help you can provide!


回答1:


First of all, please use newer site - opencv.org. Using outdated references leads to chain effect, when new users see old references, read old docs and post old links again.

There's actually no reason to use old C API. Instead, you can use newer C++ interface, which, among other things, handles capturing video gracefully. Here's shortened version of example from docs on 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;
}

Also, if you are new to programming, consider using Python interface to OpenCV - cv2 module. Python is often considered simpler than C++, and using it you can play around with OpenCV functions right in an interactive console. Capturing video with cv2 looks something like this (adopted code from 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()



回答2:


Since ffriend's answer is only partially true, I'll add some more to it (in C++). The author of this question asks explicitly for exporting to PGM (PXM file format that stores each pixel in 8 bits) and not PNG (as ffriend describes in his/her reply). The main issue here is that the official documentation for imwrite is omho not clear about this matter at all:

For PPM, PGM, or PBM, it can be a binary format flag ( CV_IMWRITE_PXM_BINARY ), 0 or 1. Default value is 1.

If we read the sentence in normal English, we have a list of options: CV_IMWRITE_PXM_BINARY, 0 or 1. There is no mention that those can and actually are supposed to be combined! I had to experiment a little bit (I also needed to store 8-bit images for my project) and finally got to the desired solution:

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

My investigation was also fueled by this question where the author was (maybe still is) struggling with the very same issue and also by some basic information on the PXM format, which you can find here.

The result (only part of the image) is displayed below:

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 ...

Which is exactly what is required in this case. You can see the "P2" marking at the top and also the values are clearly from 0 to 255, which is exactly 8 bits per pixel.




回答3:


Read most of the answers but none of them could satisfy the need that I have. This will act as a camera and can be used to click pictures we can change the if("c") condition to a for loop to click pictures automatically after certain interval

   # -*- 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()



回答4:


If you don't need superaccurate 2seconds then simply put a sleep(2) or Sleep(2000) in the while(1) loop to wait fro 2seconds before each grab,

Write images with cvSaveImage() just put the extention .pgm on the filename and it will use pgm.




回答5:


I believe that the format is chosen from the extension of the filename - so assuming your opencv lib's are linked against the appropriate libs you can do something like: (this is from memory, might not be correct.)

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


来源:https://stackoverflow.com/questions/3115529/how-do-i-capture-images-in-opencv-and-saving-in-pgm-format

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!