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

news2024/11/18 1:37:18

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


文章目录

  • C++ 结合 opencv读取图片与视频
  • 一、安装opencv
  • 二 、配置文件准备
    • 2.1 新建立文件夹
    • 2.2 .vscode文件下配置文件
      • (1)配置tasks.json文件
      • (1)配置launch.json
  • 三 、src文件下代码编写
    • 3.1 图片的读取和显示(代码文件:1.img.cpp)
    • 3.2 视频流的读取(代码文件:2.video.cpp)
    • 3.3 视频流的读取并保存(代码文件:3.write.cpp)
  • 四、cmake配置
  • 五、运行


一、安装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构建"
			]
		}
	]
}

(1)配置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 文件夹,可能和我下面不一样,因为我又在写其他的代码
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/707094.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

matplotlib设置坐标轴为象限模式

import numpy as np import matplotlib.pyplot as pltx np.linspace(-np.pi, np.pi, 1000) cosy np.cos(x) siny np.sin(x)plt.xlim(min(x), max(x)) plt.ylim(min(cosy), max(cosy)0.5) plt.plot(x, cosy) plt.plot(x, siny) # 设置坐标刻度 plt.xticks([-np.pi, -np.pi/2,…

ubuntu安装python

ubuntu安装python 安装包下载 切换到想要的文件夹&#xff1a;如 cd /usr/local/python3 下载安装包 wget https://www.python.org/ftp/python/3.8.10/Python-3.8.10.tgz 网速慢的话也可以现在本电脑下载tgz文件&#xff0c;然后上传到服务器 第一次上传失败&#xff01; Py…

SFP3012A-ASEMI代理海矽美快恢复二极管SFP3012A

编辑&#xff1a;ll SFP3012A-ASEMI代理海矽美快恢复二极管SFP3012A 型号&#xff1a;SFP3012A 品牌&#xff1a;MHCHXM&#xff08;海矽美&#xff09; 芯片个数&#xff1a;单芯片 封装&#xff1a;TO-247 恢复时间&#xff1a;≤75ns 工作温度&#xff1a;-40C~175C …

JS中的异步与Promise使用

同步与异步 我们知道JS是一个单线程的语言&#xff0c;即在同一时间只能做一件事情。为什么设计为当线程呢。&#xff1f;在早期JS是为了在浏览器中运行&#xff0c;我们可以利用JS来制作一些页面的效果也可以和用户做一些交互。所以设计为单线程也是为了避免复杂度。比如在网…

常见面试题之线程中并发锁(一)

1. 讲一下synchronized关键字的底层原理&#xff1f; 1.1. 基本使用 如下抢票的代码&#xff0c;如果不加锁&#xff0c;就会出现超卖或者一张票卖给多个人 Synchronized【对象锁】采用互斥的方式让同一时刻至多只有一个线程能持有【对象锁】&#xff0c;其它线程再想获取这…

常州工学院计算机组成原理(样卷)

微程序控制器&#xff1a;仿照程序设计的基本方法&#xff0c;将实现指令系统中所有指令所需要的所有控制信号按照一定的规则编码成微指令&#xff0c;若干条实现同一条指令功能的微指令构成一段微程序&#xff0c;将实现所有指令的微程序存放在一个只读存储器ROM中&#xff0c…

一套A股量化系统

shares A 股量化交易系统后台开发语言 Go/Python gmsec算法使用&#xff1a;pytorch全链路量化&#xff0c;行业板块分析&#xff0c;直接贴图。欢迎体验

【计算机视觉】最新综述:南洋理工和上海AI Lab提出基于Transformer的视觉分割综述

文章目录 一、导读二、摘要三、内容解读3.1 研究动机3.2 这篇综述的特色&#xff0c;以及与以往的Transformer综述有什么区别&#xff1f;3.3 Transformer-Based 分割和检测方法总结与对比3.4 相关研究领域的方法总结与对比3.5 不同方法的实验结果对比3.6 未来可以进行的方向 一…

vue三种方式导出报表至excel

1、序言 1.1、源码 源码在下方&#xff0c;复制运行&#xff0c;安装相应的插件即可 1.2、坑 方式一、方式二安装相同插件&#xff1a; npm install xlsx xlsx-style file-saver 导入 xlsx-style 会报如下的错误 解决办法&#xff1a; &#xff08;1&#xff09;去node_modules…

多元回归预测 | Matlab基于灰狼算法(GWO)优化混合核极限学习机HKELM回归预测, GWO-HKELM数据回归预测,多变量输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元回归预测 | Matlab基于灰狼算法(GWO)优化混合核极限学习机HKELM回归预测, GWO-HKELM数据回归预测,多变量输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 …

基于matlab使用深度学习估计身体姿势(附源码)

一、前言 此示例演示如何使用 OpenPose 算法和预训练网络估计一个或多个人的身体姿势。 身体姿势估计的目标是识别图像中人的位置及其身体部位的方向。当场景中存在多个人时&#xff0c;由于遮挡、身体接触和相似身体部位的接近&#xff0c;姿势估计可能会更加困难。 有两种…

【手撕算法|动态规划系列No.1】leetcode1137. 第 N 个泰波那契数

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

【C/C++】数组指针:array 地址 array *parray 两次解引用 **parray 值相同的原因解析

一、提出问题 #include <stdio.h>int main() { char array[16] {A, B}; char (*parray)[16] &array; printf("\n");printf(" array: \t%#lx\n", array); printf("& array: \t%#lx\n", &array); printf("…

SQL server 2012 配置数据库邮件实现邮件发送

日常开发中经常遇到邮件推送场景&#xff0c;我们可以利用SQL server也可以实现邮件发送功能。 一、配置邮件服务器 然后再弹出的页面中选择下一步 输入配置文件名&#xff0c;并添加新用户 在弹出的页面配置邮件服务器的地址、用户名、密码等相关信息 以上信息完成&#xff0…

树莓派 Raspberry Pi Zero 2W 安装默认系统时 ssh 登录并开启摄像头推流一段时间B

Raspberry Pi Zero 2W有点鸡肋&#xff0c;hdmi口用的microhdmi口&#xff0c;不是树莓派4b的minihdmi口&#xff0c;然后zero 2W也没有usb接口&#xff0c;有一个microusb安卓的otg接口&#xff0c;很烦&#xff0c;还好有wifi蓝牙模块&#xff0c;这样子还能ssh&#xff0c;不…

【冒泡排序】

前言 在计算机科学中&#xff0c;排序算法是一种常见且重要的算法。排序算法的目标是将一组无序的数据按照一定的规则进行重新排列&#xff0c;以便更方便地进行搜索、查找或其他操作。 冒泡排序&#xff08;Bubble Sort&#xff09;是最简单的排序算法之一&#xff0c;它的原…

基于Python+MySQL所写的商城管理系统

点击以下链接获取源码资源&#xff1a; https://download.csdn.net/download/qq_64505944/87971437?spm1001.2014.3001.5503 《51商城》程序使用说明 51商城项目分为网站前台和后台两个部分&#xff0c;下面将分别介绍这2个部分的使用。 1.网站前台 在虚拟环境中启动程序后&a…

Callback自定义测试-业务安全测试实操(23)

Callback自定义测试 测试原理和方法 在浏览器中存在着同源策略,所谓同源是指域名、协议、端口相同。当使用Aiax异步传输数据时,非同源域名之间会存在限制。其中有一种解决方法是JSONP (JSONwithPadding),基本原理是利用了HTML里<script></script>元素标签,远程…