详解OpenCV图像的概念和基本操作
作者:C君莫笑 发布时间:2021-07-22 02:05:30
前言:
opencv最主要的的功能是用于图像处理,所以图像的概念贯穿了整个opencv,与其相关的核心类就是Mat。
像素:
图片尺寸以像素为单位时,每一厘米等于28像素,如1515厘米长度的图片,等于420420像素的长度。一个像素所能表达的不同颜色数取决于比特每像素(BPP)。
灰度图像:8bpp=2的8次方=256色,
高彩色:16bpp=2的16次方=65536色,
真彩色:24bpps=2的24次方=16777216色。
图像分辨率:
图像分辨率是图像总像素的多少,由于图像通常用矩阵表示,所以分辨率常用,mn表示,注意: n 表示行数(代表一列包含的像素),m表示列数代表一行包含的像素。
640X480表示图像的长和宽分别为640和480,总像素为640X480=307200(相机中所说的30万分辨率),
800X600表示图像的长和宽分别为800和600,总像素为800X600=480000(相机中所说的50万分辨率)。
图像和矩阵
图像是由像素组成的,而像素实际上就是带有坐标位置和颜色信息的点。我们把图片想象成由若干行,若干列的点组成的, 现实中有RGB颜色系统,我们可以把图中任意一点(位置在第m行,第n列)的点A表示为
A[m,n] = [blue,green,red]
参数解读
m |A点在图像中的第m行
n |A点在图像中的第n列
blue |表示蓝色,三原色(RGB)的第一个数值
green|表示绿色,三原色(RGB)的第二个数值
red |表示红色,三原色(RGB)的第一个数值
每个点对应的亮度可以理解为rgb的值,无符号8位数3维,则一个像素点为3维数组,分别对应RGB的值,在OpenCV中数据类型为:cV_8u3C。
假设Mx N,lij表示第j行j列,对应上图就是M= 300,N= 200。
假设Mx N,lij表示第j行j列,对应上图就是M= 300,N= 200。
注意:在Opencv中三维数组存储RGB值,存储颜色通道的顺序不是RGB,而是BGR,如下图:
Mat排列方式如下:
像素值的读写
很多时候,我们需要读取某个像素值,或者设置某个像素值;在更多的时候,我们需要对整个图像里的所有像素进行遍历。OpenCV提供了多种方法来实现图像的遍历。
方法一:at 函数
cv::Mat grayim(600, 800, CV_8UC1);
// 遍历所有像素,并设置像素值
for( int i = 0; i < grayim.rows; ++i)
{
for( int j = 0; j < grayim.cols; ++j )
{
grayim.at<uchar>(i,j) = (i+j)%255;
}
}
imshow("grayim",grayim);
cv::Mat colorim(600, 800, CV_8UC3);
// 遍历所有像素,并设置像素值
for( int i = 0; i < colorim.rows; ++i)
{
for( int j = 0; j < colorim.cols; ++j )
{
cv::Vec3b pixel;
// 注意:opencv通道顺序,BGR,非RGB
pixel[0] = i%255; // Blue
pixel[1] = j%255; // Green
pixel[2] = 0; // Red
colorim.at<Vec3b>(i,j) = pixel;
}
}
imshow("colorim",colorim);
waitKey();
方法一:使用数据指针
cv::Mat grayim(600, 800, CV_8UC1);
cv::Mat colorim(600, 800, CV_8UC3);
//遍历所有像素,并设置像素值
for( int i = 0; i < grayim.rows; ++i)
{
//获取第 i 行首像素指针
uchar * p = grayim.ptr<uchar>(i);
//对第 i 行的每个像素(byte)操作
for( int j = 0; j < grayim.cols; ++j )
p[j] = (i+j)%255;
}
//遍历所有像素,并设置像素值
for( int i = 0; i < colorim.rows; ++i)
{
//获取第 i 行首像素指针
cv::Vec3b * p = colorim.ptr<cv::Vec3b>(i);
for( int j = 0; j < colorim.cols; ++j )
{
p[j][0] = i%255; //Blue
p[j][1] = j%255; //Green
p[j][2] = 0; //Red
}
}
imshow("grayim",grayim);
imshow("colorim",colorim);
实验效果
图像局部操作
选择单行/单列
示例:A矩阵的第i行,将这一行的所有元素都乘以2,然后赋值给第j行
A.row(j)= A.row(i)*2;
选择多行/多列
Range是OpencV中新增的类,该类有两个关键变量star和end。Range对象可以用来表示矩阵的多个连续的行或者多个连续的列。其表示的范围为从start到end,包含start。
// 创建一个单位阵
Mat A = Mat::eye(10, 10, CV_32S);
// 提取第 1 到 3 列(不包括 3)
Mat B = A(Range::all(), Range(1, 3));
// 提取B的第 5 至 9 行(不包括 9)
// 其实等价于C = A(Range(5, 9), Range(1, 3))
Mat C = B(Range(5, 9), Range::all());
选择指定区域
图像中提取感兴趣区域(Region of interest)有两种方法:
方法—:使用构造函数
//创建宽度为 320,高度为 240 的 3 通道图像
Mat img(Size(320, 240), CV_8UC3);
//roi 是表示 img 中 Rect(10, 10, 100, 100)区域的对象
Mat roi(img, Rect(10, 10, 100, 100));
方法二:使用括号运算符
Mat roi2 = img(Rect(10, 10, 100, 100));
//当然也可以使用Range对象来定义感兴趣区域,如下:
// 用括号运算符
Mat roi3 = img(Range(10, 100), Range(10, 100));
// 用构造函数
Mat roi4(img, Range(10, 100), Range(10, 100));
取对角线元素
矩阵的对角线元素可以使用cv::Mat就的diag()函数获取:
Mat Mat::diag(int d) const
1.当d=0时,表示取主对角线; 当参数d>0是,表示取主对角线下方的次对线,
2. 当d=1时,表示取主对角线下方,且紧贴主多角线的元素;
3. 当参数d<0时,示取主对角线上方的次对角线。如同row()和col)函数,diag()函数也不进行内存复制操作,其复杂度也是0(1)。
来源:https://blog.csdn.net/qq_34623621/article/details/120653817


猜你喜欢
- 看代码吧~name = input('Name') height = input('Height(m):')
- <style type="text/css"> <!-- body,td,th {
- 这篇文章主要介绍了Pytest mark使用实例及原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要
- 一、MySQL Workbench的下载Workbench是MySql图形化的管理工具,可以在Workbench里输入MySql的语句,这可
- 最流行的数据交换格式之一是 CSV 格式。是需要通过键盘和控制台以外的方式将信息输入和输出的程序,通过文本文件交换信息是在程序之间共享信息的
- 我就废话不多说了,直接上代码吧!import cv2import osdef save_img(): video_path =
- web开发中避免不了运行环境的搭建,个人认为这是没有什么技术含量而又浪费时间的工作.所以将环境搭建的步骤记录下来,希望可以帮到有需要的朋友少
- 这是一段点击复制的代码,现在我的页面里不仅有1个链接需要用到这段代码。请哪位好心人指教一下应该怎么用ID对应的方式来改写这段js,使它实现一
- 如下所示:class EmptyDelegate(QItemDelegate): def __init__(self,paren
- Swiper是纯javascript打造的滑动特效插件,面向手机、平板电脑等移动终端。Swiper能实现触屏焦点图、触屏Tab切换、触屏多图
- 本人最近在利用faster_rcnn训练kitti数据集,其中需要将kitti数据集转为voc数据集,但是发现:kitti图片是png格式v
- 1、将css与javascript全部用下边的方法分离到外部文件中去。<link rel="stylesheet"
- 前言本文提供将图片色彩转为黑白或者褐色风格。比较类似于我们在看动漫、影视作品中,当人物在回忆过程中,体现出来的画面一般都是黑白或者褐色的。环
- 用Dreamweaver制作网页时,如果插入的图片、GIF动画、声音、视频或链接的网页是用中文命名的,在用IE浏览器浏览时可能显示不出来。以
- 1. 横排往下会影响阅读速度。如12345678的单排单列数字,肯定是竖排阅读快。但多行多列的整块信息,横排并不见得就比竖排慢,比如所有简体
- 本文是利用python 复制文件夹 刚开始写了一个普通的递归复制文件夹 然后想了想 觉得对io频繁的程序 thre
- 本文实例讲述了Python验证码识别的方法。分享给大家供大家参考。具体实现方法如下:#encoding=utf-8import Image,
- 读文件打开文件(文件需要存在)#打开文件f = open("data.txt","r")  
- matplotlib是功能十分强大的绘制二维图形的Python模块,它用Python语言实现了MATLAB画图函数的易用性,同时又有非常强大
- 本文实例讲述了JS设计模式之责任链模式。分享给大家供大家参考,具体如下:责任链设计模式:在责任链模式里,很多对象由每一个对象对其下家的引用而