我是一般的编程新手,我正在开发一个项目,我需要从我的网络摄像头捕获图像(可能使用OpenCV),并将图像保存为pgm文件。
最简单的方法是什么? Willow Garage提供了用于图像捕获的代码:
http://opencv.willowgarage.com/wiki/CameraCapture
使用此代码作为基础,我如何将其修改为:
非常感谢您提供的任何帮助!
答案 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。