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.測試

    爲使用方便,通常經常使用齊次座標與矩陣形式表示爲:ui

04表示爲矩陣形式.png

    以上知識可能比較難懂,那麼可能真正對咱們有用的知識以下所示:3d

05圖像座標示例圖.png

那麼座標系、行列、寬高的對應的關係以下所示:code

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

    經過上面的示例,你們應該瞭解到圖片是如何用矩陣進行表示存儲的。日常你們看到的彩色圖片也都採用這種方式組成,圖片越大,則矩陣規模也越大。

通道概念

  • 通道就是每一個擁有的色彩維度

一、對於灰度圖像,只有一個色彩維度,所以是單通道
二、對於RGB彩色圖像,有RGB三個色彩維度,所以是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)從而只顯示某一通道的色彩信息。

本文同步在微信訂閱號上發佈,如各位小夥伴們喜歡個人文章,也能夠關注個人微信訂閱號:woaitest,或掃描下面的二維碼添加關注:
MyQRCode.jpg

相關文章
相關標籤/搜索