AI-图像基础知识-02

图像坐标系

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

01笛卡尔坐标系.png

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

02图像坐标系.png

以上坐标在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坐标系中的坐标之间都存在如下的关系:

03坐标系转换.png

上述公式中我们假设物理坐标系统中的单位为mm,则dx的单位为mm/px,而x/dx的单位则是px.

    为使用方便,一般常用齐次坐标与矩阵形式表示为:

04表示为矩阵形式.png

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

05图像坐标示例图.png

那么坐标系、行列、宽高的对应的关系如下所示:

row=height=y
col=width=x

使用OpenCV获取图像的大小

    以上面的示例图为例,原始图片大小为:

06示例图片大小.png

    示例代码如下所示:

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个二维矩阵。如下所示:

07BGR通道信息.png

如上图所示,该图片大小为604*403,因此有3个604*403的矩阵。

在CV领域,矩阵的概念用得非常多,下面简单介绍一下相关的概念,不做深究。

矩阵

    在数学概念中,矩阵(Matrix)是一个按照阵列形式排列的实数或复数的集合。如下图所示:

08矩阵概念.png

这是一个(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()

生成的图片效果片如下所示:

09CreateImgWithMatrix.png

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

10彩色矩阵示意图.png

    通过上面的示例,大家应该了解到图片是如何用矩阵进行表示存储的。平常大家看到的彩色图片也都采用这种方式组成,图片越大,则矩阵规模也越大。

通道概念

  • 通道就是每个拥有的色彩维度

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单独通道信息的效果图如下所示:
11BGRChannelInfo.png
  • 显示原始图片、BGR合成图片、RGB合成的图片效果如下所示:
12Orginal-BGR-RGB.png

既然能分离出BGR的通道信息,再按BGR的顺序进行合并,就可以恢复原始的图片。如果不是按这个顺序进行合并的话,会出现什么的效果图呢?可以从上面最后一张图片寻找答案。

  • 注意事项

在使用cv2.split(img)分离通道信息直接使用如下代码进行显示:

b,g,r=cv2.split(img)
ShowImg(b,"Blue Channel")
ShowImg(g,"Green Channel")
ShowImg(r,"Red Channel")

如果按照以上方式进行显示,只是会得到三张不同的灰度图:

13BGR灰度图.png

上面已经分离出BGR三个通道,为什么不是三张BGR的图像?原因如下所示:

当调用imshow(b)时,是把图像的BGR三个通道值都变为b的值,所以传递的三个通道值均为(b,b,b),在前一篇讲过,如果三个通道的值一样,则为灰度图。当使用cv2.merge方法将某个通道与零矩阵进行合并,则形成(b,0,0)从而只显示某一通道的色彩信息。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容