本篇主要讲解通过opencv调取手机摄像头并控制其拍照保存在目标路径下。
如何通过局域网连接手机摄像头参考这里
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat frame, src;
VideoCapture cap0;//建立获取视频帧的类对象
VideoCapture cap1;
cap0.open(0);//打开电脑自带的摄像头
cap1.open("http://admin:admin@192.168.0.109:8081");//打开通过局域网连接的摄像头
if (!cap0.isOpened()) return -1;//判断电脑摄像头是否打开成功
if (!cap1.isOpened()) return -1;//判断手机摄像头是否打开成功
while (true) {//循环连续显示每一帧图像
cap0.read(src);//将读取帧图像放到指定的Mat类中进行存储
cap1.read(frame);
//cap1>>frame;
//if (frame.empty()) break;这两句和上面cap.read()的作用是一样的
imshow("window1", src);//通过imshow将电脑摄像头获取的帧图像显示出来
imshow("window2", frame);//通过imshow将手机摄像头获取的帧图像显示出来
if (waitKey(30) == 27) //按esc退出
break;
}
cap0.release();
cap1.release();
return 0;
}
OpenCV调用摄像头原理:(引用来的,觉得描述的很清晰
)
OpenCV在调用摄像头的时候和读取视频的原理是一致的,OpenCV先建立一个获取视频帧的VideoCapture类对象,然后建立一个Mat类型的容器来装载Video Capture类对象获取的一帧图像,然后通过imshow()函数显示出来,这样就能显示一帧图像了,之后通过循环,就能显示连续图像了。
梳理一下,调用摄像头大致分为以下几步:
1、建立获取帧的类对象VideoCapture cap;
2、将获取帧图像存放在Mat类型容器中cap.read();
3、将图像显示出来imshow();
循环操作以上步骤,实现了显示连续的图像。
当然,这样简单的调用摄像头是没有灵魂的,可以对存入Mat仓库中的图像进行处理后再输出。
比如可以在输出前调整颜色:
cvtCOLOR(src, src, 40);
可以做Canny边缘检测:
cvtCOLOR(src, src, COLOR_BGR2GRAY);//先转灰度
Canny(src, src, 30, 100);
如下图所示:
我们还可以调动多个摄像头(通过IP摄像头连接更过设备),同时用计算机控制其拍照,并将图片保存在设定的路径下 。以下是示例代码:
void create_images() {
Mat frame, src;
VideoCapture capture(0);
VideoCapture cap("http://用户名:密码@192.168.0.109:8081");
int index = 1;
while (true) {
bool ret = capture.read(frame);//将获取的帧图像放入frame中
bool rec = cap.read(src);
flip(frame, frame, 1);//将图片frame反转,第一个参数是输入图像,第二个参数是输出图像,第三个参数是旋转方向
flip(src, src, 1);
if (!ret || !rec) break;//若frame中没有获取图像,则退出循环
imshow("frame", frame);//显示图像
imshow("src", src);
char c = waitKey(50);
printf("%d \n", c);
if (c == 113) {//等待时间内如果按动q执行
imwrite(format("D:/succcessful/Left/%d.png", index), frame);//将图像存入路径下,format用于格式化字符串,每次更新图片的名字为(index).png
//imwrite("D:/succcessful/index.png", frame);//只会存储一张图片名为index.png
imwrite(format("D:/succcessful/Right/%d.png", index), src);
index += 1;//更新index的值
}
if (c == 27) {//esc退出
break;
}
}
capture.release();
cap.release();
return;
}