我对一般的编程是全新的,并且正在从事一个项目,我需要从我的网络摄像头(可能使用 OpenCV)捕获图像,并将图像保存为 pgm 文件。
最简单的方法是什么?Willow Garage 提供以下代码用于图像捕获:
http://opencv.willowgarage.com/wiki/CameraCapture
使用此代码作为基础,我如何将其修改为:
- 每 2 秒从实时摄像头捕获一张图像
- 将图像保存到 pgm 格式的文件夹中
非常感谢您提供的任何帮助!
我对一般的编程是全新的,并且正在从事一个项目,我需要从我的网络摄像头(可能使用 OpenCV)捕获图像,并将图像保存为 pgm 文件。
最简单的方法是什么?Willow Garage 提供以下代码用于图像捕获:
http://opencv.willowgarage.com/wiki/CameraCapture
使用此代码作为基础,我如何将其修改为:
非常感谢您提供的任何帮助!
首先,请使用较新的站点 - 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()
由于 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 位。
阅读大多数答案,但没有一个能满足我的需求。这将充当相机,可用于单击图片我们可以将 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()
我相信格式是从文件名的扩展名中选择的 - 因此假设您的 opencv 库与适当的库链接,您可以执行以下操作:(这是来自内存,可能不正确。)
CvCapture* capture = cvCaptureFromCam(0);
IplImage* frame = cvQueryFrame(capture);
while (1) {
frame = cvQueryFrame(capture);
cvSaveImage("foo.pgm", &frame);
sleep(2);
}
cvReleaseImage(&frame);
cvReleaseCapture(&capture);
如果您不需要超精确的 2 秒,那么只需在 while(1) 循环中放置一个 sleep(2) 或 Sleep(2000) 以在每次抓取前等待 2 秒,
使用 cvSaveImage() 写入图像只需将扩展名 .pgm 放在文件名上,它将使用 pgm。