OpenCV学习之图像获取和显示

图像获取

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})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,OpenCV是一个开源计算机视觉和机器学习软件库,用于开发图像和视频处理应用程序。通过使用OpenCV,您可以读取摄像头并显示实时图像,打开视频文件或摄像头文件,并获取视频的相关信息,例如帧宽度、帧高度、帧率和总帧数。 对于学习OpenCV,你可以按照以下步骤进行: 1. 安装OpenCV库:在开始学习OpenCV之前,您需要从OpenCV官方网站下载和安装OpenCV库。根据您的操作系统和编程语言选择合适的版本。 2. 学习基本概念:熟悉OpenCV的基本概念和术语,例如图像和视频的加载、显示、保存以及常用的图像处理操作,如滤波、边缘检测和特征提取等。 3. 掌握OpenCV函数和类:深入了解OpenCV提供的函数和类,例如cv::Mat用于图像和矩阵操作,cv::VideoCapture用于读取和处理视频,以及cv::imshow和cv::waitKey等用于显示图像的函数。 4. 实践项目:通过完成一些实践项目来应用您所学到的知识。例如,利用OpenCV实现人脸检测、目标追踪、图像识别等。 5. 学习资料和资源:查找和阅读OpenCV的官方文档、教程和示例代码,参与开源社区讨论和交流,加入相关的论坛和邮件列表等。 总结起来,学习OpenCV包括安装OpenCV库、学习基本概念、掌握OpenCV函数和类、实践项目以及查找和阅读相关资料和资源。通过不断实践和学习,您将能够更好地理解和应用OpenCV库来开发图像和视频处理应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值