AI-图像基础知识-02
图像坐标系
在前面的数据标注文章中讲述如何进行标注,而标注后会保留4个坐标点,那么这些坐标点如何表示在图片中的位置?要表示一个点或图形的位置,就需要涉及到坐标系的概念。今天就来了解一下图像的坐标系。一般大家首先接触到的坐标系应该是的笛卡尔坐标系,如下所示:

如下图所示,是以图像左上角为原点建立的以像素为单位的直角坐标系u-v。其横坐标u与纵坐标v分别是在其图像数组中所在的列数和行数。

以上坐标在OpenCV中,u对应 x , v对应 y
由于(u,v)只代表像素的列数与行数,而像素在图像中的位置并没有用物理单位表示出来,所以还要建立以物理单位(如毫米)表示的图像坐标系x-y。将相机光轴与图像平面的交点(一般位于图像平面的中心处,也称为图像的主点(principal point)定义为该坐标系的原点O1,且x轴与u轴平行,y轴与v轴平行,假设(u0,v0)代表O1在u-v坐标系下的坐标,dx与dy分别表示每个像素在横轴x和纵轴y上的物理尺寸,则图像中的每个像素在u-v坐标系中的坐标和在x-y坐标系中的坐标之间都存在如下的关系:

上述公式中我们假设物理坐标系统中的单位为mm,则dx的单位为mm/px,而x/dx的单位则是px.
为使用方便,一般常用齐次坐标与矩阵形式表示为:

以上知识可能比较难懂,那么可能真正对我们有用的知识如下所示:

那么坐标系、行列、宽高的对应的关系如下所示:
row=height=y
col=width=x
使用OpenCV获取图像的大小
以上面的示例图为例,原始图片大小为:

示例代码如下所示:
import cv2
import numpy as np
import os
def GetImgFile(path,imgExtName=(".png",".bmp",".jpg",".jpeg",".gif")):
imgFileList=[ imgFile for r,s,fs in os.walk(imgPath) for imgFile in fs
if os.path.isfile(os.path.join(r,imgFile)) and
os.path.splitext(os.path.join(r,imgFile))[-1].lower() in imgExtName ]
return imgFileList
def GetImgHeightAndWidth(path,imgList):
tempDict={}
for item in imgList:
imgFullPath=path+"\\"+item
img=cv2.imdecode(np.fromfile(imgFullPath,dtype=np.uint8),cv2.IMREAD_COLOR)
imgHeight,imgWidth,_=img.shape
tempDict[item]={"Height":imgHeight,"Width":imgWidth}
return tempDict
if __name__ == "__main__":
imgPath=r"F:\编程资料\编程工程\AI学习笔记\03图像知识\测试图片"
imgShape=GetImgHeightAndWidth(imgPath,GetImgFile(imgPath))
print(imgShape)
输出结果如下所示:
{'TestImage.jpg': {'Height': 604, 'Width': 403}}
图像数字化
图像数字化简单来讲,就是如何将图像保存为计算机能够识别和还原的对象。数字化后的图像其本质上就是一个多维矩阵,例如常见的RGB图像其实可以理解为3个二维矩阵的叠加,矩阵中每个值对应颜色通道上的值(0~255),灰度图则是1个二维矩阵。如下所示:

如上图所示,该图片大小为604*403,因此有3个604*403的矩阵。
在CV领域,矩阵的概念用得非常多,下面简单介绍一下相关的概念,不做深究。
矩阵
在数学概念中,矩阵(Matrix)是一个按照阵列形式排列的实数或复数的集合。如下图所示:

这是一个(m+1)*(n+1)矩阵,行列索引从0开始
使用代码创建矩阵
在Python中常用于numpy模块创建和处理矩阵,示例代码如下所示:
import numpy as np
mat=np.array(range(10,35)).reshape(5,5)
print(mat)
输出的二维矩阵如下所示,从编程的角度来理解,就是一个二维的数组。
[[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]
[25 26 27 28 29]
[30 31 32 33 34]]
矩阵与图像
从前面已经可以大致猜到矩阵与图像的关系了。既然图像可以用多个矩阵来表示,那也就是意味着,我们可以自己通过代码来创建图像,示例如下所示:
import cv2
import numpy as np
mat=np.array([
[[255,0,0],[0,255,0],[0,0,255]],
[[123,145,239],[10,100,134],[0,235,252]],
[[23,45,12],[56,12,78],[128,150,12]]
],dtype=np.uint8)
cv2.namedWindow("Create Img",cv2.WINDOW_NORMAL)
cv2.imshow("Create Img",mat)
cv2.waitKey()
生成的图片效果片如下所示:

在上面3*3矩阵中,mat[m][n]分别代表BGR的值,如下图所示:

通过上面的示例,大家应该了解到图片是如何用矩阵进行表示存储的。平常大家看到的彩色图片也都采用这种方式组成,图片越大,则矩阵规模也越大。
通道概念
- 通道就是每个拥有的色彩维度
1、对于灰度图像,只有一个色彩维度,因此是单通道
2、对于RGB彩色图像,有RGB三个色彩维度,因此是3通道
3、对于RGBA彩色图像,有RGBA(A:alpha透明度)四个色彩维度,因此是4通道
- 大部分图像都可以用3维矩阵来表示
单纯从代码角度来讲,1维矩阵就是普通数组,3维矩阵就是3维数组,多维矩阵就是多维数组
使用OpenCV读取RGB通道图片
示例代码如下所示:
import cv2
import numpy as np
import os
def GetImgFile(path,imgExtName=(".png",".bmp",".jpg",".jpeg",".gif")):
imgFileList=[ imgFile for r,s,fs in os.walk(imgPath) for imgFile in fs
if os.path.isfile(os.path.join(r,imgFile)) and
os.path.splitext(os.path.join(r,imgFile))[-1].lower() in imgExtName ]
return imgFileList
def GetBGRInfo(path,imgList):
for item in imgList:
imgFullPath=path+"\\"+item
img=cv2.imdecode(np.fromfile(imgFullPath,dtype=np.uint8),cv2.IMREAD_COLOR)
ShowImg(img,winName="Source IMG")
# 分享BGR的通道信息
b,g,r=cv2.split(img)
# 创建与img相同大小的零矩阵
zerosArray=np.zeros(img.shape[:2],dtype="uint8")
# 显示(B,0,0)图像
ShowImg(cv2.merge([b,zerosArray,zerosArray]),"Blue Channel")
# 显示(0,G,0)图像
ShowImg(cv2.merge([zerosArray,g,zerosArray]),"Green Channel")
# 显示(0,0,R)图像
ShowImg(cv2.merge([zerosArray,zerosArray,r]),"Red Channel")
# 显示代码合成的BGR图像
ShowImg(cv2.merge([b,g,r]),"Merge Img-BGR")
# 显示代码合成的RGB图像
ShowImg(cv2.merge([r, g, b]), "Merge Img-RGB")
def ShowImg(obj,winName="ImgShow"):
cv2.imshow(winName,obj)
if cv2.waitKey(0) == ord("q") or cv2.waitKey(0) == ord("Q"):
cv2.destroyAllWindows()
if __name__ == "__main__":
imgPath=r"F:\测试图片"
imgFileList=GetImgFile(imgPath)
GetBGRInfo(imgPath,imgFileList)
- 显示BGR单独通道信息的效果图如下所示:

- 显示原始图片、BGR合成图片、RGB合成的图片效果如下所示:

既然能分离出BGR的通道信息,再按BGR的顺序进行合并,就可以恢复原始的图片。如果不是按这个顺序进行合并的话,会出现什么的效果图呢?可以从上面最后一张图片寻找答案。
- 注意事项
在使用cv2.split(img)分离通道信息直接使用如下代码进行显示:
b,g,r=cv2.split(img)
ShowImg(b,"Blue Channel")
ShowImg(g,"Green Channel")
ShowImg(r,"Red Channel")
如果按照以上方式进行显示,只是会得到三张不同的灰度图:

上面已经分离出BGR三个通道,为什么不是三张BGR的图像?原因如下所示:
当调用imshow(b)时,是把图像的BGR三个通道值都变为b的值,所以传递的三个通道值均为(b,b,b),在前一篇讲过,如果三个通道的值一样,则为灰度图。当使用cv2.merge方法将某个通道与零矩阵进行合并,则形成(b,0,0)从而只显示某一通道的色彩信息。
本文同步在微信订阅号上发布,如各位小伙伴们喜欢我的文章,也可以关注我的微信订阅号:woaitest,或扫描下面的二维码添加关注:

AI-图像基础知识-02的更多相关文章
- MongoDB基础知识 02
MongoDB基础知识 02 6 数据类型 6.1 null : 表示空值或者不存在的字段 {"x":null} 6.2 布尔型 : 布尔类型只有两个值true和false {&q ...
- day03-MySQL基础知识02
MySQL基础知识02 4.CRUD 数据库CRUD语句:增(create).删(delete).改(update).查(Retrieve) Insert 语句 (添加数据) Update 语句(更新 ...
- AI工程师基础知识100题
100道AI基础面试题 1.协方差和相关性有什么区别? 解析: 相关性是协方差的标准化格式.协方差本身很难做比较.例如:如果我们计算工资($)和年龄(岁)的协方差,因为这两个变量有不同的度量,所以我们 ...
- 极化SAR图像基础知识(1)
从今天开始学习极化SAR图像,记录于此. 极化散射矩阵S是用来表示单个像素散射特性的一种简便办法,它包含了目标的全部极化信息.
- 图像基础知识之YUV
一.YUV常用格式 YUV是编译true-color颜色空间(color space)的种类,Y'UV, YUV, YCbCr,YPbPr等专有名词都可以称为YUV,彼此有重叠.“Y”表示明亮度(L ...
- matlab图像基础知识
1.MATLAB支持的几种图像文件格式: ⑴JPEG(Joint Photogyaphic Expeyts Group):一种称为联合图像专家组的图像压缩格式. ⑵BMP(Windows Bitmap ...
- .NET基础知识(02)-拆箱与装箱
装箱和拆箱几乎是所有面试题中必考之一,看上去简单,就往往容易被忽视.其实它一点都不简单的,一个简单的问题也可以从多个层次来解读. 常见面试题目: 1.什么是拆箱和装箱? 2.什么是箱子? 3.箱子放在 ...
- 3-15 JS基础知识02
一.For循环: For (var i = 0; i <= 10; i++){ 循环体: } 注意:For循环中的表达式是可以省略的,省略以后是个死循环. odd:奇数 even : 偶 ...
- 极化SAR图像基础知识(2)
本篇主要关注物理含义 1.极化 电磁波在传播时,传播的方向和电场.磁场相互垂直,我们把电波的电场方向叫电波的极化.(i.e.依据电场E的方向来定义电磁波的极化). 如果电场矢量端点随时间变化的轨迹是一 ...
随机推荐
- 41 修改树莓派交换分区 SWAP 的大小
http://blog.lxx1.com/3289 SWAP就是LINUX下的虚拟内存分区,它的作用是在物理内存使用完之后,将磁盘空间(也就是SWAP分区)虚拟成内存来使用.它和Windows系统的交 ...
- MyEclipse10破解 运行run.bat闪退 亲自试验
找到MyEclipse安装的自带的jdk(方法是打开MyEclipse,依次window->Preferences->Java->Installed JRES找到默认路径,我的是:自 ...
- 0x01 Wechall writeup
目录 0x01 Wechall writeup Limited Access Training: Crypto - Caesar II Impossible n'est pas français Tr ...
- CSP前的板子
板子A(扩展欧几里得) 题目描述 求关于x的同余方程 ax≡1(modb) 的最小正整数解. 输入格式 一行,包含两个正整数 a,b,用一个空格隔开. 输出格式 一个正整数 x,即最小正整数解.输入 ...
- python总结九
1.sql语句: ,; 解释:由hire_date进行排序,降序desc,最大的就是最晚进来的员工,limit 如果是只有一个参数的话,那么说明是除了前面多少个数据, 如果后面有两个参数的话,那么就 ...
- 国家集训队 Crash 的文明世界(第二类斯特林数+换根dp)
题意 题目链接:https://www.luogu.org/problem/P4827 给定一棵 \(n\) 个节点的树和一个常数 \(k\) ,对于树上的每一个节点 \(i\) ,求出 \( ...
- 应用Redis分布式锁解决重复通知的问题
研究背景: 这几天被支付宝充值后通知所产生的重复处理问题搞得焦头烂额, 一周连续发生两次重复充钱的杯具, 发事故邮件发到想吐..为了挽回程序员的尊严, 我用了Redis的锁机制. 事故场景: 支付宝下 ...
- Java ReentrantLock中tryLock与lock的区别(非公平锁与公平锁)
设置同步状态,利用CAS操作. // CAS操作:如果当前状态值等于期望值,则自动将同步状态设置为给定的更新值 protected final boolean compareAndSetState(i ...
- GitHub的高级搜索功能
1. 首先,提供Github高级搜索帮助页面https://help.github.com/categories/search/ 2. 搜索语法https://help.github.com/ ...
- 前端图片canvas,file,blob,DataURL等格式转换
将file转化成base64 方法一:利用URL.createObjectURL() <!DOCTYPE html> <html> <head> <title ...