OpenCv图像处理之图像视频摄像头读取和保存
OpenCv图像处理之图像视频摄像头读取与保存
- 使用cv::imread()读取图片
- 使用cv::imwrite()存储图片
- 使用cv::VideoCapture::open()读取视频
- 使用cv::VideoWriter::write()存储视频
- 使用cv::VideoCapture读取摄像头
- 使用互斥量、锁、多线程进行数据读取和显示
使用cv::imread()读取图片
经过上一节的学习,我们了解到opencv处理的图片其实就是对矩阵进行操作,使用cv::imread()
对图片进行读取并返回一个矩阵,来看一个例子:
#include <iostream>
#include <opencv2/highgui.hpp>using namespace std;int main() {//imread(const String &filedir,int flags)cv::Mat img = cv::imread("D:/null.jpg", 1);//另一种判空的写法:img.data == NULL;if (img.empty()) {cout << "open the file failed!" << endl;}cv::Mat gray_img = cv::imread("D:/cat.jpg", 0);if (!gray_img.empty()) {cv::imshow("gray_img", gray_img);cv::waitKey(0);}cv::Mat nochange_img = cv::imread("D:/cat.jpg", -1);if (!nochange_img.empty()) {cv::imshow("no_chang", nochange_img);cv::waitKey(0);}return 0;
}
效果显示
open the file failed!
上述代码展示了读取图片的三种不同的状态,这个状态由flags参数决定,flags=1(>0)
表示函数需要返回三通道图像,若图片不是三通道则强制转成3通道.flags=0
表示函数返回单通道图像,若图片是多通道图片则强制转成单通道.flags=-1(<0)
表示不对图像进行通道转换处理.imread()支持图像格式:jpg,jpeg,dib,bmp,png,pbm,ppm,sr,ras,tiff,exr,jp2
使用cv::imwrite()存储图片
上面我们学习了如何读取指定路径下的图片,接下来来看一下如何将处理过的图片进行指定存储.
#include <iostream>
#include <opencv2/highgui.hpp>using namespace std;
using namespace cv;int main() {Mat mat = imread("D:/cat.jpg", 1);if (!mat.empty()) {//Rect(x,y,width,height)Mat roi(mat, Rect(200, 200, 400, 500));//bool imwrite(const String &filedir,InputArray img)//imwrite("D:/cat_roi_write.jpg", roi);//imwrite("D:/cat_roi_write.bmp", roi);bool is_write = imwrite("D:/cat_roi_write.png", roi);cout << "write is succeed?:" << is_write << endl;} else {cerr << "openfile is failed" << endl;}return 0;
}
效果显示
write is succeed?:1
png
是无损图片
jpg
是压缩成的有损图片
bmp
是不压缩的无损图片,大小较大
注意并不是所有Mat对象都能存储为图片,一般来说只有8U类型的单通道和3通道矩阵可以进行图像存储,若需要保存成16U类型的图片,则只能使用png,jpeg 2000,tiff格式进行存储.
为了将其他格式的矩阵保存为图片,opencv提供了Mat::convertTo(),从v::cvtColor()
能够将矩阵转换为能够保存的类型格式,若指定目录下已经存在要保存的文件,则会对其进行覆盖.(其中cvtColor()是cv类的成员函数,需要声明头文件#include<opencv2/opencv.hpp>)
使用cv::VideoCapture::open()读取视频
VideoCapture既可以从视频文件读取图像,也可以从摄像头中读取图像.使用VideoCapture::open()打开.
#include <iostream>
#include <opencv2/highgui.hpp>using namespace std;
using namespace cv;int main() {VideoCapture capture;Mat frame;frame = capture.open("D:/test_video.mp4");if (!capture.isOpened()) {cout << "this video can not open" << endl;return -1;} else {cout << "video is successful open=" << capture.isOpened() << endl;}//窗口大小自适应,灵活调整,写在cv::imshow()之前,防止图片尺寸太大imshow显示不全,注意名字和imshow相同,不然可能会显示两个窗口namedWindow("show_frame", WINDOW_AUTOSIZE);while (capture.read(frame)) {imshow("show_frame", frame);//每一帧的等待时间,数字越小读取越快waitKey(1);}//释放视频流,手动调用虚析构函数,open()和VideoCapture的析构函数会自动调用,故可以不手动释放capture.release();return 0;
}
打印是否打开成功的结果:video is successful open=1
调用本地摄像头很容易,将capture.open("D:/test_video.mp4");
换成capture.open(0);
即可.
使用cv::VideoWriter::write()存储视频
使用opencv存储视频流,需要在初始化时设置一系列参数文件名,编解码器,帧率,宽度,高度等等
CV_FOURCC可以获取的编码格式
CV_FOURCC(‘P’, ‘I’, ‘M’, ‘1’) = MPEG-1 code
CV_FOURCC(‘M’, ‘J’, ‘P’, ‘G’) = motion-jpeg codec
CV_FOURCC(‘M’, ‘P’, ‘4’, ‘2’) = MPEG-4.2 codec
CV_FOURCC(‘D’, ‘I’, ‘V’, ‘3’) = MPEG-4.3 codec
CV_FOURCC(‘D’, ‘I’, ‘V’, ‘X’) = MPEG-4 codec
CV_FOURCC(‘U’, ‘2’, ‘6’, ‘3’) = H263 codec
CV_FOURCC(‘I’, ‘2’, ‘6’, ‘3’) = H263I codec
CV_FOURCC(‘F’, ‘L’, ‘V’, ‘1’) = FLV1 codec
MPEG-1是为CD光盘介质定制的视频和音频压缩格式.
Motion JPEG是一种视频压缩格式,其中每一帧图像都分别使用JPEG编码.
MPEG-4利用很窄的带宽,通过帧重建技术,压缩和传输数据,求出以最少的数据获得最佳的图像质量.
VideoWriter::open()函数原型CV_WRAP virtual bool open(const String& filename, int fourcc, double fps, Size frameSize, bool isColor = true);
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>using namespace std;
using namespace cv;int main() {VideoCapture capture;capture.open("D:/test_video.mp4");if (!capture.isOpened()) {cout << "can not open the video" << endl;}double fps = capture.get(CAP_PROP_FPS);int width = int(capture.get(CAP_PROP_FRAME_WIDTH));int height = int(capture.get(CAP_PROP_FRAME_HEIGHT));int fourcc_type = VideoWriter::fourcc('M', 'P', '4', '2');VideoWriter videoWriter;videoWriter.open("D:/write_video.avi", fourcc_type, fps,Size(width, height), true);if (!videoWriter.isOpened()) {cout << "video_writer can not open" << endl;return -1;}Mat frame;while (capture.read(frame)) {//videoWriter << frame;这种写法也是正确的,使用VideoWriter的输出流进行写入videoWriter.write(frame);}return 0;
}
}
效果显示
使用cv::VideoCapture读取摄像头
#include <iostream>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <thread>using namespace std;
using namespace cv;
thread::id main_thread_id = this_thread::get_id();void open_video(VideoCapture &capture_usb, const string &filename, Mat &frame) {capture_usb.open(filename);if (!capture_usb.isOpened()) {cerr << "url not exit" << endl;}if (this_thread::get_id() == main_thread_id) {cout << "this is the main thread" << endl;} else {cout << "this is not the main thread!" << endl;}capture_usb.set(CAP_PROP_FOURCC, VideoWriter::fourcc('M', 'J', 'P', 'G'));capture_usb.set(CAP_PROP_FRAME_HEIGHT, 500);capture_usb.set(CAP_PROP_FRAME_WIDTH, 500);capture_usb.set(CAP_PROP_FPS, 30);namedWindow("capture", WINDOW_AUTOSIZE);while (capture_usb.read(frame)) {imshow("capture", frame);waitKey(1000);}
}void open_video1(VideoCapture &capture_usb, const string &filename, Mat &frame) {capture_usb.open(filename);if (!capture_usb.isOpened()) {cerr << "url not exit" << endl;}if (this_thread::get_id() == main_thread_id) {cout << "this is the main thread" << endl;} else {cout << "this is not the main thread!" << endl;}//设置采集格式capture_usb.set(CAP_PROP_FOURCC, VideoWriter::fourcc('M', 'J', 'P', 'G'));//设置分辨率capture_usb.set(CAP_PROP_FRAME_HEIGHT, 500);capture_usb.set(CAP_PROP_FRAME_WIDTH, 500);//设置每秒读取的图片数量capture_usb.set(CAP_PROP_FPS, 30);namedWindow("capture1", WINDOW_AUTOSIZE);while (capture_usb.read(frame)) {imshow("capture1", frame);waitKey(1000);}
}int main() {VideoCapture capture_usb, local_video_capture, capture_usb1, capture_usb2;Mat frame, frame_video, frame1, frame2;//url为读取的视频流地址(接口)const string filename = url;const string local_file = "D:/test_video.mp4";const string filename1 = url;thread thread_1(open_video, ref(capture_usb), filename, ref(frame));thread thread_2(open_video1, ref(capture_usb1), filename1, ref(frame));thread_2.join();thread_1.detach();for (;;) {if (!capture_usb.isOpened()) {break;}if (!capture_usb1.isOpened()) {break;}capture_usb.release();capture_usb1.release();return 0;
}
capture_usb.set()
参数简介
参数 | 值 | 功能 |
---|---|---|
CV_CAP_PROP_POS_MSEC | 0 | 视频文件的当前位置(以毫秒为单位)或视频捕获时间戳 |
CV_CAP_PROP_POS_FRAMES | 1 | 基于0的索引将被解码/捕获下一帧 |
CV_CAP_PROP_POS_AVI_RATIO | 2 | 视频文件相对位置:0 - 电影的开始,电影的1 - 结束 |
CV_CAP_PROP_FRAME_WIDTH | 3 | 视频里每一帧的宽 |
CV_CAP_PROP_FRAME_HEIGHT | 4 | 视频里每一帧的高 |
CV_CAP_PROP_FPS | 5 | 视频的帧速 |
CV_CAP_PROP_FOURCC | 6 | 4个字符表示的视频编码器格式 |
CV_CAP_PROP_FRAME_COUNT | 7 | 视频的帧数 |
CV_CAP_PROP_FORMAT | 8 | byretrieve()返回的Mat对象的格式 |
CV_CAP_PROP_MODE | 9 | 指示当前捕获模式的后端特定值 |
CV_CAP_PROP_BRIGHTNESS | 10 | 图像的亮度(仅适用于相机) |
CV_CAP_PROP_CONTRAST | 11 | 图像对比度(仅适用于相机) |
CV_CAP_PROP_SATURATION | 12 | 图像的饱和度(仅适用于相机) |
CV_CAP_PROP_HUE | 13 | 图像的色相(仅适用于相机) |
CV_CAP_PROP_GAIN | 14 | 图像的增益(仅适用于相机) |
CV_CAP_PROP_EXPOSURE | 15 | 曝光(仅适用于相机) |
CV_CAP_PROP_CONVERT_RGB | 16 | 表示图像是否应转换为RGB的布尔标志 |
CV_CAP_PROP_WHITE_BALANCE | 17 | 目前不支持 |
CV_CAP_PROP_RECTIFICATION | 18 | 立体摄像机的整流标志(注意:只有当前支持DC1394 v 2.x后端) |
使用互斥量、锁、多线程进行数据读取和显示
#include <iostream>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <thread>
#include <deque>
#include <mutex>
#include <Windows.h>
#include <ctime>
using namespace std;
using namespace cv;
thread::id main_thread_id = this_thread::get_id();
deque<cv::Mat> mat_deque;
mutex mut;void open_video(VideoCapture &capture_usb, const string &filename, Mat &frame) {capture_usb.open(filename);if (!capture_usb.isOpened()) {cerr << "url not exit" << endl;}if (this_thread::get_id() == main_thread_id) {cout << "this is the main thread" << endl;} else {cout << "this is not the main thread!" << endl;}capture_usb.set(CAP_PROP_FOURCC, VideoWriter::fourcc('M', 'J', 'P', 'G'));capture_usb.set(CAP_PROP_FRAME_HEIGHT, 200);capture_usb.set(CAP_PROP_FRAME_WIDTH, 200);capture_usb.set(CAP_PROP_FPS, 300);capture_usb.set(CAP_PROP_BUFFERSIZE, 3);while (capture_usb.read(frame)) {long start_time = clock();if (waitKey(20) >= 0) { break; }//创建线程锁锁住互斥量lock_guard<mutex> lk(mut);mat_deque.push_back(frame);long end_time = clock();cout<<"read_total_time="<<end_time-start_time<<endl;}
}void get_video_data(Mat &frame) {while (true) {if (!mat_deque.empty()) {long start_time = clock();unique_lock<mutex> lk(mut);frame = mat_deque.back();long end_time = clock();cout<<"get_total_time="<<end_time-start_time<<endl;//拿到数据之后解锁lk.unlock();if (waitKey(20) >= 0) { break; }imshow("capture", frame);waitKey(1000);mat_deque.pop_back();}}
}int main() {VideoCapture capture_usb;Mat frame, frame_video, frame1, frame2;const string filename = url;const string filename1 = url;const string filename_123 = url;thread thread_1(open_video, ref(capture_usb), filename_123, ref(frame));thread thread3(get_video_data,ref(frame_video));thread_1.join();thread3.join();for (int i = 0; i < 5; ++i) {thisthread::sleepfor(2000ms);}return 0;
}
OpenCv图像处理之图像视频摄像头读取和保存相关推荐
- Java OpenCV 图像处理32.4 视频分析和对象跟踪 切换背景
Java OpenCV 图像处理32.4 视频分析和对象跟踪 切换背景 方法 含义 解释 bitwise_and "与"操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制 ...
- 《OpenCv视觉之眼》Python图像处理二十一:Opencv图像处理之图像线性变换和非线性变换的方法及原理
本专栏主要介绍如果通过OpenCv-Python进行图像处理,通过原理理解OpenCv-Python的函数处理原型,在具体情况中,针对不同的图像进行不同等级的.不同方法的处理,以达到对图像进行去噪.锐 ...
- OpenCV图像处理(十一)---图像梯度
安培定则:也叫右手螺旋定则,是表示电流和电流激发磁场的磁感线方向间关系的定则.通电直导线中的安培定则(安培定则一):用右手握住通电直导线,让大拇指指向电流的方向,那么四指指向就是磁感线的环绕方向:通电 ...
- OpenCv图像处理之图像归一化
OpenCv图像处理之图像归一化 归一化 中心化 标准化 归一化 图像处理中,图像单通道像素值为0~255之间的uchar类型,通常使用min-max归一化将其转化为0~1区间之间,既不会改变数据的分 ...
- Python OpenCV 视频的读取和保存
1. 打开本地的摄像头,读取视频的每一帧 import cv2 # 1: connect camera via USB , 0: connect camera installed in your co ...
- python使用opencv保存视频_Pythone OpenCV学习笔记之:视频文件读取与保存
# -*- coding: utf-8 -*- # 读取和保存视频 import cv2 as cv import numpy as np def decode_fourcc(v): v = int( ...
- opencv图像处理时使用stringstream批量读取图片,处理后并保存
简介: 同文件输入输出流一样,使用stringstream可以批量读取图片,处理后并进行保存.因为C++中头文件 stringstream既可以从string读数据也可向string写数据,利于其这个 ...
- python保存代码_python如何实现视频的读取与保存功能(代码实例)
本篇文章给大家带来的内容是介绍python如何实现视频读取与保存功能.有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所助. 1.打开摄像头 #打开摄像头 import cv2 cap = c ...
- python opencv —— io(帧、图像、视频的读取与保存)
0. VideoCapture VideoCapture:构造函数: 常见成员函数: open:打开视频文件,或者捕获视频设备,该函数会首先调用 release() 函数以关闭已打开的文件或设备: P ...
最新文章
- 如何用 OS X 的 Xcode 写C语言程序
- python的TCP编程
- C#计算两个日期的相隔天数
- [Warning] TIMESTAMP with implicit DEFAULT value is
- Java面向对象(五)abstract --- 抽象
- Catalog Service - 解析微软微服务架构eShopOnContainers(三)
- java不适合开发cv吗_JavaCV开发环境的配置
- C#操作Cookie
- apk android lite,APKPure Lite
- Linux ping ipv66,IPV6的测试-ipv6网卡配置-ipv6的nginx配置-ipv6的ping测试-ipv6的curl测试...
- ERP流程的一个生动的示例~~
- jupyter notebook 中添加 Julia kernel
- Ubuntu14.04下安装Samba
- SylixOS armv8 任务切换
- UCOII信号量与消息邮箱
- 《遥感原理与应用》孙家抦版知识点总结(含简答题)——第三章
- 国家代号(CountryCode) - 常用国家地区代码和国际电话代码
- 苹果授权登录,后端校验(Sign in with Apple)
- iphone申请AppleID后无法登陆App Store
- 垃圾短信相关用户细分方案