C++抓取摄像头实时图像

需求

实时抓取网络摄像头图像至C++ OpenCV数组,进行后续处理。

思路

原本想通过RTSP协议,使用OpenCV自带的videocapture函数截取视频流中的图像,但是发现延迟很高,差不多有3-4秒,于是放弃该思路。

咨询卖家后发现,该摄像头不仅支持RTSP协议,还提供http抓图接口,于是思路变为如何在C++里使用http接口获取图像,Google之后找到如下代码。代码中用到了openCV库和libcurl库。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/*
http://benjithian.sg/2012/12/load-image-from-memoryweb-using-opencv-and-libcurl/
Below is the C++ codes to load an image directly from a website without it being written to the hard disk.
Library used were OpenCV and Libcurl. Do tell me if there is a more efficient way to do it.
*/
#include <curl/curl.h>
#include <sstream>
#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>

//curl writefunction to be passed as a parameter
size_t write_data(char* ptr, size_t size, size_t nmemb, void* userdata) {
std::ostringstream* stream = (std::ostringstream*)userdata;
size_t count = size * nmemb;
stream->write(ptr, count);
return count;
}

//function to retrieve the image as Cv::Mat data type
cv::Mat curlImg()
{
CURL* curl;
CURLcode res;
std::ostringstream stream;
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.1.88/tmpfs/snap.jpg?usr=admin&pwd=admin"); //the img url
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); // pass the writefunction
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &stream); // pass the stream ptr when the writefunction is called
res = curl_easy_perform(curl); // start curl
std::string output = stream.str(); // convert the stream into a string
curl_easy_cleanup(curl); // cleanup
std::vector<char> data = std::vector<char>(output.begin(), output.end()); //convert string into a vector
cv::Mat data_mat = cv::Mat(data); // create the cv::Mat datatype from the vector
cv::Mat image = cv::imdecode(data_mat, 1); //read an image from memory buffer
return image;
}
int main(void)
{
cv::Mat image = curlImg();
cv::namedWindow("Image output", 0);
cv::imshow("Image output", image); //display image
cv::waitKey(0);
cv::destroyWindow("Image output");
}

摄像头

本想买一个类似openMV的开发板,但总感觉有点大材小用,再加上成本问题就没有选它。上文使用的摄像头在某宝的店铺为隆胜监控,支持的网络协议很全,接口也很好用,支持定做无畸变镜头,感觉还不错:D

附上一张各开发板对比图: