opencv 三 Mat的基本操作2(图像读取保存、颜色空间、裁剪、缩放、旋转)

2023-05-16

Opencv中对彩色图的操作同样可以应用于灰度图和二值图,彩色图与灰度图直接的区别在于颜色类型空间类型的不同,这里以彩为操作示例。RGB、BGR、LAB、HSV是常见的3通道(CV_8UC3、CV_32FC3)彩色图类型,灰度图通常是一个通道的图像,二值图的数据类型与灰度图是一样的(CV_8UC1)。

一、读取|保存图像

imread函数用于读取图像,imread( const String& filename, int flags = IMREAD_COLOR ),flags的默认值为IMREAD_COLOR,也就是说默认读取为三通道BGR图像。完整的图像加载模式如下所示,0表示读取为灰度图。

IMREAD_UNCHANGED            = -1, //!< If set, return the loaded image as is (with alpha channel, otherwise it gets cropped). Ignore EXIF orientation.
       IMREAD_GRAYSCALE            = 0,  //!< If set, always convert image to the single channel grayscale image (codec internal conversion).
       IMREAD_COLOR                = 1,  //!< If set, always convert image to the 3 channel BGR color image.
       IMREAD_ANYDEPTH             = 2,  //!< If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.
       IMREAD_ANYCOLOR             = 4,  //!< If set, the image is read in any possible color format.
       IMREAD_LOAD_GDAL            = 8,  //!< If set, use the gdal driver for loading the image.
       IMREAD_REDUCED_GRAYSCALE_2  = 16, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/2.
       IMREAD_REDUCED_COLOR_2      = 17, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/2.
       IMREAD_REDUCED_GRAYSCALE_4  = 32, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/4.
       IMREAD_REDUCED_COLOR_4      = 33, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/4.
       IMREAD_REDUCED_GRAYSCALE_8  = 64, //!< If set, always convert image to the single channel grayscale image and the image size reduced 1/8.
       IMREAD_REDUCED_COLOR_8      = 65, //!< If set, always convert image to the 3 channel BGR color image and the image size reduced 1/8.
       IMREAD_IGNORE_ORIENTATION   = 128 //!< If set, do not rotate the image according to EXIF's orientation flag.
     

imwrite用于保存图像,第一个参数为文件名,第二个参数为图像对象。

    Mat img = imread("C:\\Users\\aaa\\Pictures\\timg.jpg");
	imwrite("rgb.jpg", img);

二、修改图像尺寸

opencv修改图像尺寸支持两种模型:修改为固定size和按比例缩放。

修改为固定size:将img修改为600x400(宽x高),结果存入new_img中

Mat new_img
resize(img, new_img, { 600, 400 });//缩放到固定尺寸

按比例缩放:将img的宽修改为原来的0.2倍,将img的高修改为原来的0.3倍,结果存入new_img2中。需要注意的是缩放比例是正数,且长宽缩放比例需要单独设置。

Mat new_img2;
resize(img, new_img2, {},0.2,0.3);//按比例缩放长宽

三、颜色空间修改

opencv支持多种颜色空间的相互转换,常见的颜色空间有BGR、HSV、LAB、Gray、RGB,总共约支持100多种转换模式(具体可见imgproc.hpp中ColorConversionCodes的枚举类型)。

以下代码实现了将BGR图像转化为GRAY(灰度图)、HSV、Lab、RGB模式。

	//颜色空间修改(BGR、HSV、LAB、Gray、RGB)
	Mat jray, hsv, lab,rgb;
	cvtColor(img, jray, cv::COLOR_BGR2GRAY);
	cvtColor(img, hsv, cv::COLOR_BGR2HSV);
	cvtColor(img, lab, cv::COLOR_BGR2Lab);
	cvtColor(img, rgb, cv::COLOR_BGR2RGB);

四、图像裁剪

使用img(Rect(x,y,w,h))即可在img中的x,y位置截取出一个宽为w长为h的图像。这里需要注意的是Rect的x+w不能超过原图的宽[img.cols],y+h不能超过原图的高[img.rows])

	//图像裁剪 Rect(x,y,w,h)
	//(Rect的x+w不能超过原图的宽,y+h不能超过原图的高)
	Rect m_select1 = Rect(0, 100, 300, 217);
	Mat ROI1 = img(m_select1);
	Rect m_select2 = Rect(300, 100, 320, 217);
	Mat ROI2 = img(m_select2);
	imshow("img", img);
	imshow("ROI1", ROI1);
	imshow("ROI2", ROI2);

五、图片粘贴

 opencv实现图像粘贴核心是实验copyTo函数,A.copyTo(B)既将A图粘贴到B中。在实际使用中A图与B的size可能不一样,故需要使用img(Rect(x,y,w,h))裁剪到相同的尺寸。

以下代码实现了将2.4中裁剪的两个小图粘贴到一起

    //图片粘贴(实现两个无重叠区域图像的拼接)
	//实现两个图像横着拼接
	//A.copyTo(B) A与B的大小应该一致
	Mat board =Mat::zeros(ROI1.rows, ROI1.cols+ ROI2.cols, CV_8UC3);
	Rect roi_rect1 = Rect(0, 0, ROI1.cols, ROI1.rows);
	ROI1.copyTo(board(roi_rect1));
	Rect roi_rect2 = Rect(ROI1.cols, 0, ROI2.cols, ROI2.rows);
	ROI2.copyTo(board(roi_rect2));
	imshow("board", board);

图片拼接效果如下所示 

六、图像旋转

 opencv图像旋转涉及参数较多,图像旋转需要设置旋转中心点、旋转角度、旋转后空白处填充值、旋转后size。故此定义函数实现图像旋转,以下函数默认旋转中心为图像中心,旋转角度为参数传入,空白处填充模式为边缘拉伸。

/**************************************************************************************************************
Function:       RotateImage
Description:    旋转图片
Input:          src:需要旋转的图片路径 angle:旋转角度
Return:         旋转后的图片
***************************************************************************************************************/
cv::Mat RotateImage(cv::Mat src, double angle)
{
	cv::Mat dst;
	try
	{
		//float scale = 200.0/ src.rows;//缩放因子    
		//cv::resize(src, src, cv::Size(), scale, scale, cv::INTER_LINEAR);    	    	
		//输出图像的尺寸与原图一样    
		cv::Size dst_sz(src.cols, src.rows);

		//指定旋转中心      
		cv::Point2f center(static_cast<float>(src.cols / 2.), static_cast<float>(src.rows / 2.));

		//获取旋转矩阵(2x3矩阵)      
		cv::Mat rot_mat = cv::getRotationMatrix2D(center, angle, 1.0);
		//设置选择背景边界颜色   
		/*cv::Scalar borderColor = Scalar(0, 238, 0);*/
		/*cv::warpAffine(src, dst, rot_mat, src.size(), INTER_LINEAR, BORDER_CONSTANT, borderColor);*/
		//复制边缘填充
		cv::warpAffine(src, dst, rot_mat, dst_sz, cv::INTER_LINEAR, cv::BORDER_REPLICATE);
	}
	catch (cv::Exception e)
	{
	}

	return dst;
}

 调用代码

//图像旋转
	//涉及到旋转中心点、旋转角度、旋转后的size、旋转后空白处填充
	Mat rotateImg=RotateImage(img, 60);
	imshow("rotateImg", rotateImg);

 调用效果

七、完整代码 

本章节完整代码如下所示

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

#include <iostream>  
#include <stdlib.h>
#include <stdio.h>
using namespace std;
using namespace cv;
/**************************************************************************************************************
Function:       RotateImage
Description:    旋转图片
Input:          src:需要旋转的图片路径 angle:旋转角度
Return:         旋转后的图片
***************************************************************************************************************/
cv::Mat RotateImage(cv::Mat src, double angle)
{
	cv::Mat dst;
	try
	{
		//float scale = 200.0/ src.rows;//缩放因子    
		//cv::resize(src, src, cv::Size(), scale, scale, cv::INTER_LINEAR);    	    	
		//输出图像的尺寸与原图一样    
		cv::Size dst_sz(src.cols, src.rows);

		//指定旋转中心      
		cv::Point2f center(static_cast<float>(src.cols / 2.), static_cast<float>(src.rows / 2.));

		//获取旋转矩阵(2x3矩阵)      
		cv::Mat rot_mat = cv::getRotationMatrix2D(center, angle, 1.0);
		//设置选择背景边界颜色   
		/*cv::Scalar borderColor = Scalar(0, 238, 0);*/
		/*cv::warpAffine(src, dst, rot_mat, src.size(), INTER_LINEAR, BORDER_CONSTANT, borderColor);*/
		//复制边缘填充
		cv::warpAffine(src, dst, rot_mat, dst_sz, cv::INTER_LINEAR, cv::BORDER_REPLICATE);
	}
	catch (cv::Exception e)
	{
	}

	return dst;
}
void main() {
/*彩色图操作
	图片的读取,修改,保存。修改尺寸,修改涉及颜色,裁剪,拼接,旋转*/
	Mat mat = imread("C:\\Users\\aaa\\Pictures\\timg.jpg");
//Mat的基本属性
// 宽、高;数据类型;通道数
	cout << "宽(列):" << mat.cols << ",高(行):" << mat.rows << endl;
	cout << "数据类型: " << mat.type() << endl;
	cout << "通道数: " << mat.channels() << endl;


	Mat img = imread("C:\\Users\\aaa\\Pictures\\timg.jpg");
	imwrite("rgb.jpg", img);
	//resize(img, img, { 600, 400 });//缩放到固定尺寸
	resize(img, img, {},0.2,0.2);//按比例缩放长宽

	//颜色空间修改(BGR、HSV、LAB、Gray、RGB)
	Mat jray, hsv, lab,rgb;
	cvtColor(img, jray, cv::COLOR_BGR2GRAY);
	cvtColor(img, hsv, cv::COLOR_BGR2HSV);
	cvtColor(img, lab, cv::COLOR_BGR2Lab);
	cvtColor(img, rgb, cv::COLOR_BGR2RGB);

	//图像裁剪 Rect(x,y,w,h)
	//(Rect的x+w不能超过原图的宽,y+h不能超过原图的高)
	Rect m_select1 = Rect(0, 100, 300, 217);
	Mat ROI1 = img(m_select1);
	Rect m_select2 = Rect(300, 100, 320, 217);
	Mat ROI2 = img(m_select2);
	imshow("img", img);
	imshow("ROI1", ROI1);
	imshow("ROI2", ROI2);

	//图片粘贴(实现两个无重叠区域图像的拼接)
	//实现两个图像横着拼接
	//A.copyTo(B) A与B的大小应该一致
	Mat board =Mat::zeros(ROI1.rows, ROI1.cols+ ROI2.cols, CV_8UC3);
	Rect roi_rect1 = Rect(0, 0, ROI1.cols, ROI1.rows);
	ROI1.copyTo(board(roi_rect1));
	Rect roi_rect2 = Rect(ROI1.cols, 0, ROI2.cols, ROI2.rows);
	ROI2.copyTo(board(roi_rect2));
	imshow("board", board);

	//图像旋转
	//涉及到旋转中心点、旋转角度、旋转后的size、旋转后空白处填充
	Mat rotateImg=RotateImage(img, 60);
	imshow("rotateImg", rotateImg);
	waitKey(0);
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

opencv 三 Mat的基本操作2(图像读取保存、颜色空间、裁剪、缩放、旋转) 的相关文章

  • 七、FreeRTOS学习之 软件定时器

    一 基本概念 在freertos中 xff0c 软件定时器的功能跟单片机中使用的定时器差不多 xff0c 通过设置一段时间 xff0c 等到时间到达 xff0c 定时器进入中断 xff0c 执行相应的功能函数 xff0c 被调用的函数叫做定
  • 软件iic 的编写与调试

    一 了解 1 硬件iic 其对应的芯片上有iic外设 xff0c iic的引脚是固定的 xff0c 硬件iic是直接配置内部的寄存器 xff0c 只要配置好寄存器 xff0c 外设就会产生标准的协议时序 xff0c 只需要直接调用控制函数
  • 运算符重载(),[]

    include lt iostream gt include lt cstring gt using namespace std class yunsuan private int a b c int len num char name 3
  • vector

    include lt iostream gt include lt vector gt include lt algorithm gt using namespace std 容器 xff1a vector 相当于一个数组 迭代器 xff1
  • STM32外设之TIM定时器使用及输出比较模式PWM生成,PWM频率和占空比计算,文末有固件库TIM驱动文件的函数讲解

    TIM 定时器是stm32单片机中的一个外设 xff0c STM32有8个定时器 xff0c 分别是2个高级定时器TIM1TIM8 xff0c 4个通用定时器TIM2 5 2个基本定时器TIM67 根据不同型号的单片机 xff0c 挂载的定
  • Java多线程之~~~~使用wait和notify实现生产者消费者模型

    在多线程开发中 xff0c 最经典的一个模型就是生产者消费者模型 xff0c 他们有一个缓冲区 xff0c 缓冲区有最大限制 xff0c 当缓冲区满 的时候 xff0c 生产者是不能将产品放入到缓冲区里面的 xff0c 当然 xff0c 当
  • 拷贝、移动构造

    include lt iostream gt using namespace std class temp private char a public temp char c char b a 61 new char 2 a 0 61 c
  • Dockerfile

    Dockerfile Dockerfile简介1 Dockerfile基本介绍2 Dockerfile构建过程3 Dockerfile指令用法 Dockerfile构建镜像1 Dockerfile使用CentOS构建apache镜像1 1相
  • MySQL数据库备份与恢复

    在项目的开发过程中数据库的备份是非常重要的 xff0c 为了防止数据库受到破坏 xff0c 造成不可估量的损失 xff0c 所以一定要进行数据库的备份 xff0c 并且需要掌握数据库恢复方法 xff0c 在发生数据库损坏的时候 xff0c
  • Linux设备驱动基础知识

    一 认识驱动 1 什么是驱动 不知道的情况下 xff0c 我们一般会去问度娘 xff0c 但是度娘的这个回答比较专业化 xff0c 对小白来说并不容易理解 xff0c 依旧不明白驱动到底是个啥 度娘 xff1a 驱动 xff0c 计算机软件
  • 接口及实现方法

    什么是接口 接口 xff08 英文 xff1a Interface xff09 xff0c 在JAVA编程语言中是一个抽象类型 xff0c 是抽象方法的集合 xff08 接口中的所有的方法都是抽象方法 xff09 xff0c 接口通常以in
  • JS中Document对象

    Document对象 Document对象就是一个标记性文档对象 它就是HTML文件本身 当浏览器把一个html文件加载到内存中之后 xff0c 在内存中就会形成这个document对象 document URL xff1a 返回当前页面的
  • Sphinx环境配置以及VScode编写Rst文档转html

    Sphinx环境配置 安装python3通过python3安装sphinx sphinx官方网站 xff1a Installing Sphinx Sphinx documentation python官方网站 xff1a Welcome t
  • js实现防抖和节流

    防抖 xff1a 防抖就是在连续多次触发该事件 xff0c 事件触发间隔小于设定的事件 xff0c 事件只会执行最后一次 节流 xff1a 规定的时间内 xff0c 只能触发一次该事件 接下来看代码 xff1a lt DOCTYPE htm
  • 树莓派系统镜像一键瘦身备份脚本, 生成最小化镜像img(一)

    开发 测试环境 树莓派 xff1a Raspberry Pi 3b 43 TF 存储卡 xff1a 32GB操作系统 xff1a 2020 05 27 raspios buster full armhf xff08 官方版本 xff09 程
  • 分享——网页上的虚拟机

    大家还记得之前的Windows系统吗 xff1f 相信大家一定想要重温或体验以前Windows的系统吧 xff0c 可有些朋友想体验但又嫌装虚拟机太麻烦 xff0c 怎么办呢 其实 xff0c 还有 网上的虚拟机 现在 xff0c 我就给大
  • 单片机编程中的裸机编程和多任务系统FreeRTOS系统详解,以及怎么学习FreeRTOS,看哪家的教程?(合集)

    单片机编程中的裸机系统和多任务系统 学习了那么久的stm32还停留在裸机 xff1f xff1f xff1f 单片机编程中的裸机系统和多任务系统 1 裸机系统1 1轮询系统1 2 前后台系统 2 多任务操作系统3 为什么要学习多任务操作系统
  • Selenium+Pytest自动化测试框架实战,还不会点这里一清二楚,全网最细教程!

    如果下方文字内容没有看明白的话 xff0c 我推荐大家看一套视频 xff0c 比文字内容讲的更加详细 xff01 在华为工作了10年的大佬出的Web自动化测试教程 xff0c 华为现用技术教程 xff01 哔哩哔哩 bilibili 在华为
  • Firewalld防火墙基础

    目录 前言 一 概述 2 Firewalld和iptables的关系 2 1 Firewalld和iptables的关系 3 Firewalld区域 3 1 firewalld区域的概念 3 2 firewalld防火墙定义了9个区域 3
  • Matlab/simulink控制,遗传pid,模糊pid,滑模控制,自抗扰ADRC控制

    Matlab simulink控制 xff0c 遗传pid 模糊pid xff0c 滑模控制 xff0c 自抗扰ADRC控制 xff0c 鲁棒控制 xff0c LADRC控制等 xff0c 以上控制均已封装为simulink模块 xff0c

随机推荐