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

简介: 操作系统: Linux(采用远程服务器主机进行代码编写)需提前配置(安装)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构建"
      ]
    }
  ]
}

(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 文件夹,可能和我下面不一样,因为我又在写其他的代码

相关文章
|
1月前
|
计算机视觉
Opencv学习笔记(十二):图片腐蚀和膨胀操作
这篇文章介绍了图像腐蚀和膨胀的原理、作用以及使用OpenCV实现这些操作的代码示例,并深入解析了开运算和闭运算的概念及其在图像形态学处理中的应用。
113 1
Opencv学习笔记(十二):图片腐蚀和膨胀操作
|
1月前
|
计算机视觉 Python
Opencv学习笔记(二):如何将整个文件下的彩色图片全部转换为灰度图
使用OpenCV库将一个文件夹内的所有彩色图片批量转换为灰度图,并提供了相应的Python代码示例。
35 0
Opencv学习笔记(二):如何将整个文件下的彩色图片全部转换为灰度图
|
1月前
|
计算机视觉 Python
Opencv学习笔记(一):如何将得到的图片保存在指定目录以及如何将文件夹里所有图片以数组形式输出
这篇博客介绍了如何使用OpenCV库在Python中将图片保存到指定目录,以及如何将文件夹中的所有图片读取并以数组形式输出。
144 0
Opencv学习笔记(一):如何将得到的图片保存在指定目录以及如何将文件夹里所有图片以数组形式输出
|
1月前
|
计算机视觉
Opencv学习笔记(八):如何通过cv2读取视频和摄像头来进行人脸检测(jetson nano)
如何使用OpenCV库通过cv2模块读取视频和摄像头进行人脸检测,并提供了相应的代码示例。
84 1
|
1月前
|
计算机视觉
Opencv错误笔记(一):通过cv2保存图片采用中文命名出现乱码
在使用OpenCV的cv2模块保存带有中文命名的图片时,直接使用cv2.imwrite()会导致乱码问题,可以通过改用cv2.imencode()方法来解决。
132 0
Opencv错误笔记(一):通过cv2保存图片采用中文命名出现乱码
|
3月前
|
计算机视觉 Windows Python
windows下使用python + opencv读取含有中文路径的图片 和 把图片数据保存到含有中文的路径下
在Windows系统中,直接使用`cv2.imread()`和`cv2.imwrite()`处理含中文路径的图像文件时会遇到问题。读取时会返回空数据,保存时则无法正确保存至目标目录。为解决这些问题,可以使用`cv2.imdecode()`结合`np.fromfile()`来读取图像,并使用`cv2.imencode()`结合`tofile()`方法来保存图像至含中文的路径。这种方法有效避免了路径编码问题,确保图像处理流程顺畅进行。
342 1
|
4月前
|
数据安全/隐私保护 C++ 计算机视觉
Qt(C++)开发一款图片防盗用水印制作小工具
文本水印是一种常用的防盗用手段,可以将文本信息嵌入到图片、视频等文件中,用于识别和证明文件的版权归属。在数字化和网络化的时代,大量的原创作品容易被不法分子盗用或侵犯版权,因此加入文本水印成为了保护原创作品和维护知识产权的必要手段。 通常情况下,文本水印可以包含版权声明、制作者姓名、日期、网址等信息,以帮助识别文件的来源和版权归属。同时,为了增强防盗用效果,文本水印通常会采用字体、颜色、角度等多种组合方式,使得水印难以被删除或篡改,有效地降低了盗用意愿和风险。 开发人员可以使用图像处理技术和编程语言实现文本水印的功能,例如使用Qt的QPainter类进行文本绘制操作,将文本信息嵌入到图片中,
181 1
Qt(C++)开发一款图片防盗用水印制作小工具
|
5月前
|
算法 开发工具 计算机视觉
【零代码研发】OpenCV实验大师工作流引擎C++ SDK演示
【零代码研发】OpenCV实验大师工作流引擎C++ SDK演示
82 1
|
1月前
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
281 3
|
1月前
|
Serverless 计算机视觉
语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆
这篇文章介绍了如何使用OpenCV库通过mask图像绘制分割对象的外接椭圆。首先,需要加载mask图像,然后使用`cv2.findContours()`寻找轮廓,接着用`cv2.fitEllipse()`拟合外接椭圆,最后用`cv2.ellipse()`绘制椭圆。文章提供了详细的代码示例,展示了从读取图像到显示结果的完整过程。
50 0
语义分割笔记(三):通过opencv对mask图片来画分割对象的外接椭圆