写点什么

C++ 结合 opencv 读取图片与视频

作者:向阳逐梦
  • 2023-07-21
    四川
  • 本文字数:4632 字

    阅读完需:约 15 分钟

C++ 结合 opencv读取图片与视频

一、安装 opencv

  • 操作系统: Linux(采用远程服务器主机进行代码编写)

  • 需提前配置(安装)cmake

  • 远程连接服务器进行操作, 直接新建立的终端输入

sudo apt install libopencv-dev
复制代码

二 、配置文件准备

2.1 新建立文件夹

  • 建立一个新的文件夹,并在文件夹下面建立如下面的子文件夹

  • 其中 CMakeLists.txt 是 txt 形式的文件

  • .vscode 里面放的是配置文件

  • media 放的图片和视频

  • output 是输出的文件夹路径

  • src 放的是源代码 cpp 文件

2.2 .vscode 文件下配置文件

(1)配置 tasks.json 文件

{	"version": "2.0.0",	"tasks": [		// 1.cmake 配置		{			"type": "cppbuild",			"label": "cmake配置",			"command": "cmake",                         // cmake命令			"args": [				"-S .",                                 // 源码目录        		"-B build",                             // 编译目录        		"-DCMAKE_BUILD_TYPE=Debug"              // 编译类型			],			"options": {				"cwd": "${workspaceFolder}"             // 工作目录			},			"problemMatcher": [				"$gcc"			],			"group": "build",		},		// 2.cmake 编译		{			"type": "cppbuild",      		"label": "CMake编译",      		"command": "cmake",                // cmake命令      		"args": [        		"--build",                     // 编译        		"build",                       // 编译目录      		],      		"options": {        		"cwd": "${workspaceFolder}"    // 工作目录      		},      		"problemMatcher": [        		"$gcc"      		],      		"group": "build",      		"dependsOn": [        		"CMake配置"                    // 依赖CMake配置,先执行CMake配置      		]		},		// 3.删除build目录		{			"type": "shell",			"label": "删除build目录",			"command": "rm -rf build",			"options": {				"cwd": "${workspaceFolder}"     // 工作目录			},			"problemMatcher": [				"$gcc"			],			"group": "build",			},		// 4.运行可执行文件		{			"label": "运行可执行文件",			"type": "shell",			"command": "./build/demo_${fileBasenameNoExtension}",			"problemMatcher": [],			"group": {				"kind": "build",				"isDefault": true			},			"options": {				"cwd": "${workspaceFolder}"   			},			"dependsOn": [				"cmake构建"			]		}	]}
复制代码

(2)配置 launch.json

{    // 使用 IntelliSense 了解相关属性。     // 悬停以查看现有属性的描述。    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387    "version": "0.2.0",    "configurations": [        {            "name": "C++ Cmake Debug",            "type": "cppdbg",            "request": "launch",            "program": "${workspaceFolder}/build/demo_${fileBasenameNoExtension}",    // 编译后的程序,需要结合CMakeLists.txt中的add_executable()函数            "args": [],            "stopAtEntry": false,            "cwd": "${workspaceFolder}",            "environment": [],            "externalConsole": false,            "MIMode": "gdb",            "miDebuggerPath": "/usr/bin/gdb",            "setupCommands": [                {                    "description": "Enable pretty-printing for gdb",                    "text": "-enable-pretty-printing",                    "ignoreFailures": true                }            ],            "preLaunchTask": "CMake编译"        }    ]}
复制代码

三 、src 文件下代码编写

3.1 图片的读取和显示(代码文件:1.img.cpp)

  • 在导入 #include"opencv2/opencv.hpp" 会出现错误, 鼠标点击头文件并按住 ctrl 键,界面会出现配置,添加配置即可, 配置文件自动生成放在.vscode 文件下。

  • 由于是远程服务器主机, 所以无法显示图片,只能另存为。

// 图片的读取和显示// 导入 opencv 头文件#include"opencv2/opencv.hpp"#include<iostream>int main(int argc, char** argv){    // 读取图片    // 读取的数据保存在 Mat 类型的变量 image 中, Mat是 opencv 中的图像数据结构,类似 numpy 中的 ndarray    cv :: Mat image = cv :: imread("./media/cat.jpg");    // 判断图片是否读取成功, 读取不成功, 运行 if 语句直接退出主函数    if(image.empty())    {        std :: cout << "Could not read the image: " << std :: endl;        return 1;    }    // 打印图片宽度和高度    std :: cout << "图片高度: " << image.rows << "图片宽度: " << image.cols << std :: endl;    // 打印图片数据    // 以 numpy 的方式打印    std :: cout << "图片的 data: " << cv :: format(image, cv :: Formatter :: FMT_NUMPY) << std :: endl;    // 以 python list 格式输出    std :: cout << "图片的 data: " << cv :: format(image, cv :: Formatter :: FMT_PYTHON) << std :: endl;    // 创建一个gray 图    cv :: Mat gray;    // 创建一个 hsv 图    cv :: Mat hsv;    // 创建一个 rgb 图    cv :: Mat rgb;    // BGR --> Gray    cv :: cvtColor(image, gray, cv :: COLOR_BGR2GRAY);    // BGR --> HSV    cv :: cvtColor(image, hsv, cv :: COLOR_BGR2HSV);    // BGR --> RGB    cv :: cvtColor(image, rgb, cv :: COLOR_BGR2RGB);    // 保存 gray 图: 格式: (文件路径, Mat 矩阵变量)    cv :: imwrite("./output/gray.jpg", gray);    // 显示图片    // cv :: imshow("图片", image);    // 等待按键    // cv :: waitKey(0);    // 显示多张图片, 同时出现在两个窗口    // cv :: imshow("原图", image);    // cv :: imshow("灰度图", gray);    // cv :: waitKey(0);    return 0;}
复制代码

3.2 视频流的读取(代码文件:2.video.cpp)

// opencv 读取视频流#include"opencv2/opencv.hpp"#include<iostream>#include<gflags/gflags.h>                            // 导入 gflags 库int main(int argc, char **argv){    // 解析命令行参数    gflags :: ParseCommandLineFlags(&argc, &argv, true);    // 创建一个 VideoCapture 对象, 参数为视频路径    cv :: VideoCapture capture("./media/dog.mp4");    // 判断视频是否读取成功, 返回 True 表示成功    if(!capture.isOpened())    {        std :: cout << "无法读取视频" << std :: endl;        return 1;    }    // 读取视频帧, 使用 Mat 类型的 frame 存储返回的帧    cv :: Mat frame;    // 定义灰度图    cv :: Mat gray;    // 循环读取视频    while(true)    {        // 读取视频帧, 使用 >> 运算符 或者 read()函数, 他的参数是返回的帧        capture.read(frame);        // capture >> frame;        // 判断是否读取成功        if(frame.empty())        {            std :: cout << "文件读取完毕: " << std :: endl;            break;        }        // 将视频的帧转为灰度图        cv :: cvtColor(frame, gray, cv :: COLOR_BGR2GRAY);        // 显示视频帧        cv :: imshow("raw demo", frame);        cv :: imshow("gray demo", gray);        // 等待按键, 延迟 30ms, 否则视频播放太快        int k = cv :: waitKey(30);        // 按下Esc键退出        if(k == 27)        {            std :: cout << "退出" << std :: endl;            break;        }    }    return 0;}
复制代码

3.3 视频流的读取并保存(代码文件:3.write.cpp)

// opencv 读取视频流#include"opencv2/opencv.hpp"#include<iostream>#include<gflags/gflags.h>                            // 导入 gflags 库int main(int argc, char **argv){    // 解析命令行参数    gflags :: ParseCommandLineFlags(&argc, &argv, true);    // 创建一个 VideoCapture 对象, 参数为视频路径    cv :: VideoCapture capture("./media/dog.mp4");    // 判断视频是否读取成功, 返回 True 表示成功    if(!capture.isOpened())    {        std :: cout << "无法读取视频" << std :: endl;        return 1;    }    int frame_width = capture.get(cv :: CAP_PROP_FRAME_WIDTH);	int frame_height = capture.get(cv :: CAP_PROP_FRAME_HEIGHT);	double fps = capture.get(cv :: CAP_PROP_FPS);    std :: cout << "图像宽度: " << frame_width << std :: endl;    std :: cout << "图像高度: " << frame_height << std :: endl;    std :: cout << "图像帧率: " << fps << std :: endl;    // 读取视频帧, 使用 Mat 类型的 frame 存储返回的帧    cv :: Mat frame;    // 定义灰度图    cv :: Mat gray;    //写入MP4文件,参数分别是:文件名,编码格式,帧率,帧大小     cv::VideoWriter writer("./output/record.avi", cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), fps, cv::Size(frame_width, frame_height));    // 循环读取视频    while(true)    {        // 读取视频帧, 使用 >> 运算符 或者 read()函数, 他的参数是返回的帧        capture.read(frame);        // capture >> frame;        // 判断是否读取成功        if(frame.empty())        {            std :: cout << "文件读取完毕: " << std :: endl;            break;        }        // std :: cout << "图片高度: " << frame.rows << "图片宽度: " << frame.cols << std :: endl;        // 将视频的帧转为灰度图        cv :: cvtColor(frame, gray, cv :: COLOR_BGR2GRAY);        // 将 gray 写入         writer.write(frame);    }    return 0;}
复制代码

四、cmake 配置

在 CMakeLists.txt 文件中进行配置

# 最低版本要求cmake_minimum_required(VERSION 3.10)# 项目信息project(opencv_demo)# 使用find_package命令查找OpenCV库find_package(OpenCV REQUIRED)find_package(gflags REQUIRED)if (OpenCV_FOUND)    message(STATUS "OpenCV library status:")    message(STATUS "    version: ${OpenCV_VERSION}")    message(STATUS "    libraries: ${OpenCV_LIBS}")    message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")else()    message(FATAL_ERROR "Could not find OpenCV library")endif()# 添加头文件include_directories(${OpenCV_INCLUDE_DIRS} ${gflags_INCLUDE_DIRS})# 链接库link_libraries(${OpenCV_LIBS} ${gflags_LIBRARIES})# 添加可执行文件add_executable(demo_1.img src/1.img.cpp)add_executable(demo_2.video src/2.video.cpp)add_executable(demo_3.write src/3.write.cpp)
复制代码

五、运行

运行 1.img.cpp,终端选项 – 运行任务

会出现下列界面, 依次点击 删除 build 目录表,在选择终端 – 运行任务 – cmake 配置,结束后,在点击终端 – 运行任务 – CMake 编译

上述过程结束后,就会正常运行与输出 1.img.cpp

输出后结果如图所示, 主要看 output 文件夹,可能和我下面不一样,因为我又在写其他的代码


发布于: 刚刚阅读数: 6
用户头像

向阳逐梦

关注

人生享受编程,编程造就人生! 2022-06-01 加入

某公司芯片测试工程师,嵌入式开发工程师,InfoQ签约作者,阿里云星级博主,华为云·云享专家。座右铭:向着太阳,追逐梦想!

评论

发布
暂无评论
C++ 结合 opencv读取图片与视频_向阳逐梦_InfoQ写作社区