OpenCv图像处理之Mat类使用

  • Opencv简介
  • 矩阵类cv::Mat
  • 遍历图像,设置像素值
    • 使用at(int x,int y)
    • 使用MatIterator_迭代器
  • 选择指定区域
    • 使用构造函数截取指定区域
    • 使用operator()运算符进行截取

Opencv简介

opencv是一个非常优秀的图像处理工具库,底层由C++编写,故本教程的编程语言选择的是C++。
在生活中到处都是唯美的图像组成的一幅幅生动美丽的画面,但是这些画面经过计算机剖析之后,其实是一系列数字组成。比如下面的这幅图

在我们眼里,是一只非常可爱的小猫咪,但是在计算机眼里,它只是一些亮度不同的点而已,这副图片的大小是746 * 745,也就是一个746 * 745的2维矩阵,矩阵中的每一个元素表示这个位置上像素的亮度,像素值越大表示该点的亮度越亮。这些点的亮度其实就是rgb的值,一般的图像文件格式使用的是unsigned 8bits,即3维无符号8位数(uchar),故一个像素点为3维数组,分别对应rgb的值。但是需要注意的是,在opencv中3维数组存储的rgb值顺序并不是rgb,而是bgr。Mat矩阵对应的参数类型是CV_8UC1,CV_8UC2,CV_8UC3(C(n),n表示的是通道数,RGB3对应的参数类型就是CV_8UC3)

矩阵类cv::Mat

下面简单介绍了一下Mat类中某些关键的成员变量,详细的可以看源码

#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>using namespace std;
using namespace cv;//Mat类副本
class MatTest {public://flags参数包含许多关于矩阵的信息,比如Mat标识,数据是否连接,深度,通道数目int flags;//矩阵维度,至少2维,1维为向量int dims;//矩阵的行列数,若为n维矩阵(n>2),那么rows=-1,cols=-1int rows, cols;//无符号字符串指针,指向数据(files,images..)uchar *data;
};
int main(){return 0;
}

下面来看一下源码中数据的类型

Matrix Type Type
CV_8U uchar
CV_8S schar
CV_16U ushort
CV_16S short
CV_32S int
CV_32F float
CV_64F double

源码中封装了各种矩阵函数,这里简单介绍几种,顺便增加熟练度

#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <d2d1.h>
#include <vector>using namespace std;
using namespace cv;int main() {//cv::Mat//默认构造函数Mat mat;//拷贝构造函数Mat mat1(const Mat &mat1);//指定行列范围的拷贝构造函数Mat mat2(const Mat &mat2, const Range &row, const Range &cols);//指定ROI的拷贝构造函数Mat mat3(const Mat &mat3, const Rect &roi);//使用多维数组中指定范围内的数据的拷贝构造函数Mat mat5(const Mat &mat5, Range *ranges);//指定类型和大小(行列)的2维数组(行在前,列在后)Mat mat6(int rows, int cols, int type);//有初始化值的置顶类型和大小的2维数组Mat mat7(int rows, int cols, int type, const Scalar &scalar);//指定大小和类型的2维数组Mat mat8(Size size, int type, const Scalar &scalar);//指定类型的多维数组Mat mat9(int ndims, const int *sizes, int type);//使用cv::Vec定义相同类型大小为n的1维向量Mat mat10(const Vec<T, n> &vec, bool copy_data = true);//使用cv::Matx定义相同类型大小为m*n的2维数组Mat mat11(const Matx<T, m, n> &vec, bool copy_data = true);//使用STL vector定义相同类型的1维数组Mat mat12(const vector<T> &vec, bool copy_data = true);//使用zeros()定义指定大小和类型的全零矩阵Mat::zeros(int rows,int cols,int type);//使用ones()定义指定大小和类型的全1矩阵Mat::ones(int rows,int cols,int type);return 0;
}

遍历图像,设置像素值

在图像处理中,设置像素值是很常见的事情,如何设置呢,通常是对图像中的全部像素进行遍历来设置

使用at(int x,int y)

#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/imgcodecs.hpp>
#include <d2d1.h>
#include <vector>using namespace std;
using namespace cv;int main() {//单通道灰度图Mat gray_image = cv::imread("D://cat.jpg", CV_8UC1);//rgbMat rgb_image = cv::imread("D://cat.jpg");//遍历gray_image所有像素,设置像素值for (int i = 0; i < gray_image.rows; ++i) {for (int j = 0; j < gray_image.cols; ++j) {gray_image.at<uchar>(i, j) = (i + j) % 255;}}cv::imshow("gray_image", gray_image);//遍历rgb_image所有像素,设置像素值for (int i = 0; i < rgb_image.rows; ++i) {for (int j = 0; j < rgb_image.cols; ++j) {//cv::Vec3bVec3b pixel;//Bluepixel[0] = i % 255;//Greenpixel[1] = j % 255;//Redpixel[2] = (i + j) % 255;rgb_image.at<Vec3b>(i, j) = pixel;}}cv::imshow("rgb_cat", rgb_image);cv::waitKey(0);return 0;
}

上述代码中Vec3b还可以写成cv::Vec<uchar,3> vec;定义一个uchar类型,长度为3的数组。opencv中封装好的类型如8U类型rgb彩色图像用的是<Vec3b>,float类型的矩阵使用<Vec3f>。对于Vec对象而言,可以使用[]符号像操作数据般读写Vec数据,如上述程序中的Vec3b pixel;对象>。
效果图


上述程序中多次用到了at<>(int x,int y);它是cv::mat的成员函数,at()可以用来存取图像中对应坐标为(x,y)的像素坐标,使用的时候要注意标明数据类型,比如单通道的灰度图可以写成img.at<uchar>(1,2) = 10;而三通道的彩色图则可以这样写img.at<Vec3b>(1,2)[0] = 10; img.at<Vec3b>(1,2)[1] = 20;img.at<Vec3b>(1,2)[2] = 30;这样是对三通道对应的像素进行了修改,opencv中对应的三原色的顺序是bgr,上面也提到过。

使用MatIterator_迭代器

#include <iostream>
#include <opencv2/highgui.hpp>
#include <vector>
#include <random>using namespace std;
using namespace cv;int main() {Mat rgb_img = imread("D:/cat.jpg");//定义迭代器对象MatIterator_<Vec3b> rgb_start, rgb_end;//随机数对象定义default_random_engine random;for (rgb_start = rgb_img.begin<Vec3b>(), rgb_end = rgb_img.end<Vec3b>();rgb_start != rgb_end; ++rgb_start) {//B-G-R(*rgb_start)[0] = random();(*rgb_start)[1] = random();(*rgb_start)[2] = random();}imshow("rgb_iter", rgb_img);waitKey(0);return 0;
}

选择指定区域

使用构造函数截取指定区域

#include <iostream>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <vector>using namespace std;
using namespace cv;int main() {Mat rgb_img = imread("D:/cat.jpg");//Rect(x,y,width,height)Mat roi(rgb_img, Rect(101, 201, 501, 500));imshow("roi_img", roi);waitKey(0);return 0;
}

效果显示

使用operator()运算符进行截取

#include <iostream>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <vector>using namespace std;
using namespace cv;int main() {Mat rgb_img = imread("D:/cat.jpg");//第一个Range()表示rowRange(代表高度,行是竖着)//第二个Range()表示colRange(代表宽度,列是横着)Mat roi = rgb_img(Range(100, 550), Range(100, 600));imshow("roi_img", roi);waitKey(0);return 0;
}

需要注意的是截取的范围是有界限的,若截取不当,则会报错

Assertion failed (0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <=roi.height && roi.y + roi.height <= m.rows) in Mat

效果显示

OpenCv图像处理之Mat类使用相关推荐

  1. 【从零学习OpenCV 4】Mat类介绍

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...

  2. 基于c++版本的opencv操作(Mat类)

    图像的基本操作(一) 前言 一.Mat类? 1.c++版本代码 添加链接描述 前言 一.Mat类? 1.c++版本代码 1.1 at()函数 1.2 使用迭代器 2.代码结果展示 2.1 at()函数 ...

  3. 如何将OpenCV中的Mat类绑定为OpenGL中的纹理

    https://blog.csdn.net/TTTTzTTTT/article/details/53456324 如果要调用外接的USB摄像头获取图像通常使用OpenCV来调用,如何调用摄像头请参考本 ...

  4. 【从零学习OpenCV 4】Mat类构造与赋值

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...

  5. OpenCV(c++) 矩阵 Mat 类的用法与注意事项

    Mat类 基本介绍 Mat类是OpenCV中使用最频繁的类之一,用于储存矩阵数据及相关操作,也是程序中图像的主要形式. Mat类主要由两部分组成:一个描述头(matrix header)及一个指向矩阵 ...

  6. Opencv中Mat类详细解读(学习笔记)

    基于windows10.vs2015.OpenCv4.1.0. 目录 1.Mat类简介 2.Mat类的构造与赋值 2.1.Mat类的构造 2.2.Mat类的赋值 3.Mat类支持的运算 3.1Mat类 ...

  7. OpenCV Mat类详解和用法(官网原文)

    参考文章:OpenCV Mat类详解和用法 我马克一下,日后更 官网原文链接:https://docs.opencv.org/3.2.0/d6/d6d/tutorial_mat_the_basic_i ...

  8. 计算机视觉之OpenCV教程 ---Mat类基础(一)

    机器视觉之OpenCV教程图像容器Mat类基础一(一) 零.OpenCV概述 基本上在机器识别的领域 ,都有OpenCV的身影 . OpenCV中基本上包含了所有的机器视觉所用到的算法 , 即使没有也 ...

  9. OpenCV Mat类详解和用法

    OpenCV Mat类详解和用法 我们有多种方法可以获得从现实世界的数字图像:数码相机.扫描仪.计算机体层摄影或磁共振成像就是其中的几种.在每种情况下我们(人类)看到了什么是图像.但是,转换图像到我们 ...

  10. python的opencv的图像对象存储的颜色通道_OpenCV大型阵列类型Mat类

    一.Mat类 Mat类是C++实现的OpenCV库的核心,表示一个N维度单通或多通道阵列,可以用来存储实数或复数值向量和数组,灰度或彩色图像,向量场,张量及直方图(当然高纬度的直方图存储在稀疏Mat类 ...

最新文章

  1. java bmp_JAVA实现对BMP图片的读取
  2. linux达人养成计划学习笔记(四)—— 压缩命令
  3. python websocket异步高并发_高并发异步uwsgi+web.py+gevent
  4. 绿色版本Tomcat
  5. PP视频怎么把输出声音设置成单声道输出
  6. python opencv3 —— findContours
  7. Network location provider at ‘https://www.googleapis.com/‘ : No response received.
  8. 5款工具帮你一键快速图片去水印(附送复杂水印去除教程)
  9. 使用Cisco Packet Tracer之图解无线网络全网互联
  10. 4pycharm与jupyter使用对比
  11. k8s资源之pvpvcsc
  12. ionic组件-Slides轮播图
  13. 谐音单词背诵,持续补充中......欢迎留言添加
  14. AnimationDrawable 帧动画 爆炸特效
  15. docker+docker-compose部署微服务项目
  16. 游戏更新-围棋练习大全-Android
  17. C/C++项目开发:教你用C++开发电脑桌面提醒程序,好厉害的黑科技!
  18. 在Asset Store上购买unity插件
  19. ai人工智能将替代人类_教AI学习人类如何有效计划
  20. 我的CSDN 2007 MVB 最有价值BLOG 奖杯碎了,心疼

热门文章

  1. Spring Mvc - 用户注册服务端生成默认头像实现
  2. 【快代理API】获取隧道代理IP
  3. 高项题目--工期计算
  4. bzoj2555 SubString (SAM+LCT维护子树大小/ETT)
  5. 熔断机制什么意思_什么是熔断机制,熔断机制是什么意思
  6. PINN解偏微分方程--程函方程
  7. 基于饥饿博弈搜索算法的函数寻优算法
  8. Unitek的USB3.0 TF卡读卡器
  9. java wait until_java调用ktr文件trans.waitUntilFinished()超时
  10. 亿级 QQ 会员活动运营系统的设计之道