OpenCV学习之图像获取和显示

news2024/12/26 11:19:51

目录

  • 图像获取
    • 从图片文件获取图像
    • 从视频文件获取图像
  • 图像显示
  • 示例代码
    • 从图片文件获取图像
    • 从视频获取图像

图像获取

OpenCV 支持从图片文件获取图像、从视频文件获取图像以及从摄像头获取图像等方式。

从图片文件获取图像

使用函数imread可以从图片文件中读取图像,具体用法如下:

Mat cv::imread	(const String& filename, int flags = IMREAD_COLOR)	

头文件包含:
#include <opencv2/imgcodecs.hpp>

描述
imread从指定文件中加载图像并且返回一个矩阵对象。如果图像加载失败(可能的原因:文件丢失、权限问题、不支持或者无效的文件格式),imread将会返回一个空矩阵(Mat::data==NULL)。

参数描述
filename图片的文件名(含路径)
flags读取模式的标志(见cv::ImreadModes

cv::ImreadModes

标志描述
IMREAD_UNCHANGED按原样返回加载的图像(包含alpha通道,否则将被裁剪)。忽略EXIF方向。
IMREAD_GRAYSCALE始终将图像转换为单通道灰度图像(编解码器内部转换)
IMREAD_COLOR始终将图像转换为3通道BGR彩色图像
IMREAD_ANYDEPTH当输入图像具有16位/32位深度时,返回16位/32位图像,否则将其转换为8
IMREAD_ANYCOLOR以任何可能的颜色格式读取图像
IMREAD_LOAD_GDAL使用gdal驱动程序加载图像
IMREAD_REDUCED_GRAYSCALE_2始终将图像转换为单通道灰度图像,并将图像大小缩小1/2
IMREAD_REDUCED_COLOR_2始终将图像转换为3通道BGR彩色图像,并将图像大小缩小1/2
IMREAD_REDUCED_GRAYSCALE_4始终将图像转换为单通道灰度图像,并将图像大小缩小1/4
IMREAD_REDUCED_COLOR_4始终将图像转换为3通道BGR彩色图像,并将图像大小缩小1/4
IMREAD_REDUCED_GRAYSCALE_8始终将图像转换为单通道灰度图像,并将图像大小缩小1/8
IMREAD_REDUCED_COLOR_8始终将图像转换为3通道BGR彩色图像,并将图像大小缩小1/8
IMREAD_IGNORE_ORIENTATION不根据EXIF的方向标志旋转图像

目前支持的文件格式如下:

  • Windows bitmaps - *.bmp, *.dib (始终支持)
  • JPEG files - *.jpeg, *.jpg, *.jpe (见注意事项)
  • JPEG 2000 files - *.jp2 (见注意事项)
  • Portable Network Graphics - *.png (见注意事项)
  • WebP - *.webp (见注意事项)
  • AVIF - *.avif (见注意事项)
  • Portable image format - *.pbm, *.pgm, *.ppm *.pxm, *.pnm (始终支持)
  • PFM files - *.pfm (见注意事项)
  • Sun rasters - *.sr, *.ras (始终支持)
  • TIFF files - *.tiff, *.tif (见注意事项)
  • OpenEXR Image files - *.exr (见注意事项)
  • Radiance HDR - *.hdr, *.pic (始终支持)
  • Raster and Vector geospatial data supported by GDAL (见注意事项)

注意事项

  • 该函数根据内容而不是文件扩展名来确定图像的类型。

  • 针对彩色图像,解码后的图像将会按照BGR的通道顺序存储。

  • 当使用IMREAD_GRAYSCALE时,如果编解码器的内部灰度转换可用,将使用编解码器的内部灰度转换。其结果可能和cvtColor()的输出不同。

  • 在 Microsoft Windows* 操作系统和 MacOSX* 上,默认使用 OpenCV 图像(libjpeg、libpng、libtiff 和 lib jasper)附带的编解码器。因此,OpenCV 始终可以读取 JPEG、PNG 和 TIFF。在 MacOSX 上,还有一个选项是使用本机 MacOSX 图像读取器。但要注意,由于 MacOSX 中嵌入了颜色管理,目前这些本机图像加载器提供的图像具有不同的像素值。

  • 在 Linux*、BSD 风格和其他类 Unix 开源操作系统上,OpenCV 查找随操作系统映像提供的编解码器。安装相关软件包(不要忘记开发文件,例如 Debian* 和 Ubuntu* 中的“libjpeg-dev”),以获得编解码器支持,或在 CMake 中打开 OPENCV_BUILD_3RDPARTY_LIBS 标志。

  • 如果将 CMake 中的 WITH_GDAL 标志设置为 true,并设置IMREAD_LOAD_GDAL标志去加载图像,则将使用 GDAL 驱动程序来解码图像,支持以下格式:光栅(Raster)、矢量(Vector)。

  • 如果图像文件中嵌入了EXIF信息,则将考虑EXIF方向,因此图像将相应地旋转,除非传递了IMREAD_IGNORE_ORIENTATIONIMREAD_UNCHANGED 标志。

  • 使用IMREAD_UNCHANGED标志保留PFM图像中的浮点值。

  • 默认情况下,像素数必须小于2^30。可以使用系统变量OPENCV_IO_MAX_IMAGE_PIXELS设置限制。

从视频文件获取图像

cv::VideoCapture是用于从视频文件、图像序列或相机捕获视频的类。要读取视频文件,需要创建cv::VideoCapture对象。

头文件包含:
#include <opencv2/videoio.hpp>

VideoCapture (const String &filename, int apiPreference=CAP_ANY)

描述:
使用apiPreference打开视频文件、捕获设备或IP视频流进行视频捕获。

参数

参数描述
filename1. 视频文件名 2.图像序列 3. 视频流URL 4.如果使用GStreamer作为后端,则采用gst-launch工具格式的GStreamer管道字符串。请注意,每个视频流或IP摄像头feed都有自己的URL方案。请参阅源码流文档以了解正确的URL。
apiPreference首选要使用的Capture API后端。如果多个可用的读取器实现,则可用于执行特定读取器

更多的构造函数,参见cv::VideoCapture Class Reference

virtual bool cv::VideoCapture::isOpened() const

描述:
如果视频捕获已经初始化则返回true。如果先前对 VideoCapture 构造函数或VideoCapture::open()的调用成功,则该方法返回 true。

virtual bool cv::VideoCapture::read	(OutputArray image)	

描述:
抓取、解码并且返回下一个视频帧。该方法/函数将VideoCapture::grab()和VideoCapture::retrieve()组合在一个调用中。这是读取视频文件或从解码中捕获数据的最方便的方法,并返回刚捕获的帧。如果没有捕获到帧(相机已断开连接,或者视频文件中没有更多帧),则该方法返回false,函数返回空图像(使用cv::Mat,用Mat::empty()测试)。

关于VideoCapture::grab()和VideoCapture::retrieve()参见https://docs.opencv.org/4.x/d8/dfe/classcv_1_1VideoCapture.html#ae38c2a053d39d6b20c9c649e08ff0146

参数:
【输出型】视频帧被放置在这个参数中。如果没有抓取到视频帧,则这个参数的图像数据为空。

返回值:
如果抓取到图像返回true,否则,返回false。

virtual double cv::VideoCapture::get(int propId	)const

描述:
返回特定的VideoCapture属性。

参数:

参数描述
propId来自 cv::VideoCaptureProperties的属性标识符或视频I/O API后端的附加标志

返回值:
所查询的属性的值。当查询不被后端支持的属性时,返回值 0。

图像显示

OpenCV显示图像可以使用High-level GUI提供的imshow函数,详情如下:

void cv::imshow	(const String & winname, InputArray mat)

头文件包含:
#include <opencv2/highgui.hpp>

描述:
在指定窗口中显示图像。
imshow函数在指定窗口中显示图像。如果窗口是使用cv::WINDOW_AUTOSIZE标志创建的,则图像将以原始大小显示,但仍受屏幕分辨率的限制。否则,图像将被缩放以适应窗口。该函数可以根据图像的深度缩放图像:

  • 如果图像是8位无符号的,则按原样显示。
  • 如果图像是16位无符号的,则像素值除以256。也就是说,值域 [0,255*256] 被映射到 [0,255]
  • 如果图像是32位或64位浮点数,则像素值乘以255。也就是说,值域 [0,1] 被映射到 [0,255]
  • 由于所需变换的模糊性,不再处理32位整数图像。使用特定于图像上下文的自定义预处理转换为8位无符号矩阵。(懵逼O0O)

如果窗口是使用 OpenGL 创建的,则 cv::imshow 也支持 ogl::Bufferogl::Texture2Dcuda::GpuMat 作为输入。
如果在此函数之前未创建窗口,则假定使用 cv::WINDOW_AUTOSIZE 创建窗口。
如果你需要显示一个比屏幕分辨率大的图像,你需要在imshow之前调用namedWindow(“”,WINDOW_NORMAL)

参数:

参数描述
winname窗口名
mat被显示的图像矩阵

注意事项:
在执行此函数后,应调用 cv::waitKeycv::pollKey 来执行 GUI 日常任务,这些任务对于实际显示给定图像并使窗口响应鼠标和键盘事件是必要的。否则,它将不会显示图像,窗口可能会锁定。例如,waitKey(0) 将无限期显示窗口,直到任何按键(它适用于图像显示)。waitKey(25) 将显示一个帧并等待大约 25 毫秒的按键(适用于逐帧显示视频)。
要删除窗口,请使用 cv::destroyWindow

[仅限 Windows 后端] 按 Ctrl+C 可将图像复制到剪贴板。按 Ctrl+S 可显示一个对话框以保存图像。

示例代码

从图片文件获取图像

  1. 文件结构
    在这里插入图片描述
  2. 源码
    ImageProcessor.h
#pragma once

#include <string>

namespace opencv_app{ namespace image {
	class ImageProcessor {
		public:
			ImageProcessor(const std::string& filepath, const std::string& filename);
			virtual ~ImageProcessor();
		public:
			bool show(const std::string& window);
		private:
			std::string filepath;
			std::string filename;
	};
}}

ImageProcessor.cpp

#include "ImageProcessor.h"
#include "opencv2/opencv.hpp"

using namespace opencv_app::image;

ImageProcessor::ImageProcessor(const std::string& filepath, const std::string& filename)
{
	this->filepath = filepath;
	this->filename = filename;
}

ImageProcessor::~ImageProcessor()
{

}

bool ImageProcessor::show(const std::string& window)
{
	std::string pathname = this->filepath + this->filename;
	cv::Mat image = cv::imread(pathname);
	if (nullptr == image.data) {
		printf("imread %s error\n", pathname.c_str());
		return false;
	}

	cv::imshow(window, image);
	cv::waitKey(0);

	return true;
}

main.cpp

#include "ImageProcessor.h"

using namespace opencv_app::image;

int main(int argc, char* argv[])
{
	if (argc < 3) {
		printf("Usage:./imageProcessor [filepath] [filename]\n");
		return -1;
	}

	ImageProcessor imageProc(argv[1], argv[2]);

	imageProc.show(argv[2]);

	return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(image_processor)

find_package(OpenCV REQUIRED)
add_executable(imageProcessor ./main.cpp ./ImageProcessor.cpp)
target_link_libraries(imageProcessor ${OpenCV_LIBS})

从视频获取图像

  1. 文件结构
    在这里插入图片描述
  2. 源码
    ImageProcessor.h
#pragma once

#include <string>

namespace opencv_app{ namespace image {
	class ImageProcessor {
		public:
			ImageProcessor(const std::string& filepath, const std::string& filename);
			virtual ~ImageProcessor();
		public:
			bool show(const std::string& window);
		private:
			std::string filepath;
			std::string filename;
	};
}}

ImageProcessor.cpp

#include "ImageProcessor.h"
#include "opencv2/opencv.hpp"
#include "opencv2/videoio.hpp"

using namespace opencv_app::image;

ImageProcessor::ImageProcessor(const std::string& filepath, const std::string& filename)
{
	this->filepath = filepath;
	this->filename = filename;
}

ImageProcessor::~ImageProcessor()
{

}

bool ImageProcessor::show(const std::string& window)
{
	std::string pathname = this->filepath + this->filename;
	
	cv::VideoCapture video(pathname);

	auto frameTot = video.get(cv::VideoCaptureProperties::CAP_PROP_FRAME_COUNT);
	auto frameRate = video.get(cv::VideoCaptureProperties::CAP_PROP_FPS);
	printf("frameTot=%f,frameRate=%f\n",frameTot, frameRate);

	while(true) {
		if (video.isOpened()) {
			break;
		}
	}
	
	while(frameTot) {
		cv::Mat image;
		if (!video.read(image)) {
			printf("grab frame from video %s error\n", pathname.c_str());
			continue;
		}
		cv::imshow(window, image);
		cv::waitKey(1000/frameRate);

		frameTot--;
	}

	return true;
}

main.cpp

#include "ImageProcessor.h"

using namespace opencv_app::image;

int main(int argc, char* argv[])
{
	if (argc < 3) {
		printf("Usage:./imageProcessor [filepath] [filename]\n");
		return -1;
	}

	ImageProcessor imageProc(argv[1], argv[2]);

	imageProc.show(argv[2]);

	return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(image_processor)

find_package(OpenCV REQUIRED)
add_executable(imageProcessor ./main.cpp ./ImageProcessor.cpp)
target_link_libraries(imageProcessor ${OpenCV_LIBS})

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

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

相关文章

Bean的生命周期,循环依赖

右边部分为生命周期。 二级缓存和三级缓存的区别就是是否被引用过&#xff0c;未被引用的放在三级缓存。如果被引用了&#xff0c;则把三级缓存的删除放到二级缓存

清华深圳2024届推免拟录取名单

名单 分析 清华深圳 数据科学与信息技术专业 共录取41人&#xff1b; 清华深圳 计算机技术专业共录取37人&#xff0c;都是专硕085404计算机技术&#xff1b; 电子信息专业大数据工程方向录取推免生13人&#xff1b; 电子信息集成电路与系统方向录取推免生18人&#xff1b; 电…

njust校园网自动认证

分析校园网登录页面 打开登录界面&#xff0c;填入你自己的账号和密码(先别点击登录)&#xff0c;然后按下 F12 点击了登录后&#xff1a; 获取登录请求的URL链接&#xff0c;可以看到南理校园网是使用POST的方式来登录的。 查看POST请求参数&#xff1a; 后面需要用到的…

SAT Encoding and CDCL Algorithm听课笔记

CDCL&#xff1a;&#xff1a;归结式 如果x不出现在公式的别的地方&#xff0c;那么两者可以等价 CDCL&#xff1a;&#xff1a;watched literals 通过监测文字来判断当前子句是否是单元子句 先选择两个未赋值的文字作为监测文字&#xff0c;若其中的监测文字被赋值后则去寻找…

基于单片机的土壤温湿度控制系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 技术交流认准下方 CSDN 官方提供的联系方式 文章目录 概要 一、温湿度控制系统的整体规划2.3系统的总体构架 二、温度湿度控制系统硬件设计3.1系统硬件概述 三、 温湿度系统软件…

Java web(七):VueElement

文章目录 一、Vue1.1 基本介绍1.2 常用指令1.3 生命周期1.4 案例VueAxios 二、Element三、综合案例【VueElementAxiosServeltMybatis】 一、Vue 1.1 基本介绍 Vue 是一套前端框架&#xff0c;免除原生JavaScript中的DOM操作&#xff0c;简化书写。 基于MVVM(Model-View-View…

六大排序算法:插入、选择、冒泡、快排、希尔、归并

1、插入排序 解析&#xff1a;第一个元素设定为已经排好序&#xff0c;依次选择后续的元素插入到已经排好序的组内进行排序。 图示&#xff1a; 代码&#xff1a; public static void insertionSort(int[] arr) {int n arr.length;for (int i 1; i < n; i) {int key a…

Databend 开源周报第 118 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 MERGE INTO 现已…

计算机毕业设计 基于SpringBoot高校毕业与学位资格审核系统的设计与实现 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

VR全景在旅游中应用有哪些?VR云游的优势是什么?

近日受到剧烈日冕物质抛射活动影响&#xff0c;漠河再现极光美景&#xff0c;极光舞动的灿烂星空下&#xff0c;正在封冻的黑龙江上&#xff0c;无数的冰排随波而去&#xff0c;天地之间光影流动好不美丽。相信很多人都想了解、观赏祖国的大好风光&#xff0c;但是碍于没时间、…

关于SSP3D复现

关于SSP3D复现的问题 准备工作 下载Xshell和XFTP&#xff1a;家校免费版下载链接连接服务器&#xff08;可能需要与服务器处在相同网络下&#xff09;GitHub上下载源码&#xff1a;SSP3D 左上角新建会话&#xff0c;输入名称和主机 点击左侧菜单“用户身份验证”&#xff0c…

Freeswitch实现软电话功能

1.话务步骤 分机注册(需要查询分机状态来判断是否可用)->登录&#xff08;接听呼入电话需要登录到指定queue&#xff09;->拨打电话->就绪->未就绪-> 登出 2. sdk调用方式 /*<--注册分机-->*/ //EslMessage eslMessage1 inboundClient.sendApiCommand(…

Linux文件系统——文件描述符

文章目录 0. 前言1. C文件接口文件打开文件写入 2. 系统文件接口open && write && closeopen的返回值 本章gitee代码仓库&#xff1a;文件描述符 0. 前言 基础原理知识&#xff1a; 文件 内容 属性 文件分为&#xff1a;打开的文件&#xff08;本章重点讲解…

python使用pysqlcipher3对sqlite数据库进行加密

python对很多项目都需要对sqlite数据库的数据进行加密&#xff0c;最流行的加密方式是使用pysqlcipher3&#xff0c;当前使用的python版本为3.7&#xff0c;本博文是直接使用pysqlcipher3在项目上的应用&#xff0c;使用的是已编译好的pysqlcipher3包&#xff0c;如果你需要pys…

6个常用的小程序UI组件库,大厂设计师都在用!

UI组件库是设计系统的一部分&#xff0c;在一般的页面设计过程中可以直接用来构建交互界面。因此&#xff0c;一个有效的小程序UI组件库可以帮助设计师快速掌握基本的交互框架&#xff0c;提高设计师的工作效率&#xff0c;让设计师有更多的时间打磨和提高小程序的整体效果。小…

Softing新版HART多路复用器现支持图尔克excom和西门子ET 200iSP等远程I/O

Softing工业自动化最近升级了用于访问配置和诊断数据的smartLink SW-HT软件&#xff0c;现在该软件可支持访问图尔克excom和西门子ET 200iSP等远程I/O。 &#xff08;smartLink SW-HT支持访问配置和诊断数据&#xff09; 越来越多的新型远程I/O选择使用以太网来替代PROFIBUS连接…

微信小程序将后端返回的图片文件流解析显示导页面

说明 由于请求接口后端返回的图片格式不是一个完整的url,也不是其他直接能显示的图片格式&#xff0c;是一张图片 后端根据模板与二维码生成图片,返回二进制数据 返回为文件流的格式,用wx.request请求的时候&#xff0c;就自动解码成为了下面这样的数据数据格式,这样的数据没…

【无代码】【VR开发】【Unity】【VRTK】4-导入VRTK Tilia Package

【导入VRTK V4】 VRTK的Tilia Package包含了一整套空间开发方案。导入后你可以在PackageManager中看到它们。 所有的Tilia包都可以在如下页面找到: https://www.vrtk.io/tilia.html Tilia包有一个安装器,可以让你仅仅安装需要的包。包的种类很多,按照适用方向分类。 点击H…

Redis中的渐进式遍历-Scan命令

之前我们学习过遍历命令keys,而keys *是一次性的把整个redis中所有的key都获取到.在不知道当前redis中有多少key的情况下,这个操作是非常危险的,可能会一下子得到太多的key而阻塞redis服务器.从而使其他redis客户端卡顿. 通过渐进式遍历,就可以做到,既可以获取到所有的key,同时…

python链队_队列的链式存储结构

队列是一种先进先出&#xff08;first in first out,FIFO&#xff09;的线性表&#xff0c;是一种常用的数据结构。 它只允许在表的前端&#xff08;front&#xff09;进行删除操作&#xff0c;而在表的后端&#xff08;rear&#xff09;进行插入操作&#xff0c;和栈一样&…