本篇主要讲解通过opencv调取手机摄像头并控制其拍照保存在目标路径下。如何通过局域网连接手机摄像头参考这里

利用OpenCV4调用手机摄像头和电脑摄像头参考这里

#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);

如下图所示:

android 能否同时打开两个相机设备 两个安卓手机遥控拍照_#include


我们还可以调动多个摄像头(通过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;
 }