此文章一共分為四篇
第一篇 入門篇(本篇)
第二篇 基礎篇
第三篇 進階篇
第四篇 項目篇
在這篇系列文章中,我將帶你從“完全小白”一路打怪升級到能動手做真實項目。
不堆術語、不講空話,只用你能跑通的代碼 + 能看懂的圖解 + 踩過的坑總結,
手把手拆解 OpenCV 的核心邏輯。點個關注不迷路!!!
目錄
第一章 Python 和OpenCV
OpenCV包含的模塊
第二章 搭建開發環境
第三章 圖像處理的基本操作
3.1讀取圖像
3.2顯示圖像
3.3保存圖像
3.4獲取圖像屬性
3.5小結
第四章 像素的操作
4.1像素
4.2使用NumPy模塊操作像素
第五章 色彩空間與通道
5.1色彩空間
5.2通道
5.3 小結
第一章 Python 和OpenCV
本篇包括Python與OpenCV、搭建開發環境、圖像處理的基本操作、像素的 操作和色彩空間與通道。這5章的作用相當於“掃盲”,即完成一個從“什麼都不 知道”到“掌握關鍵知識點”的轉變過程,為學習後面的內容奠定基礎。
OpenCV是一個開源的計算機視覺庫,並 以為計算機視覺提供通用性接口為目標。
計算機視覺 不會像人類視覺那樣能夠對圖像進行感知和識別,更不會自動控制焦距和光圈,而是把圖 像解析為按照柵格狀排列的數字。以圖1.7為例,計算機視覺將其解析為如圖1.8所示的 按照柵格狀排列的數字(圖1.8只是圖1.7的一部分)。
這些按照柵格狀排列的數字包含大量的噪聲,噪聲在圖像上常表現為引起較強視覺效 果的孤立像素點或像素塊,使得圖像模糊不清。因此,噪聲是計算機視覺面臨的一個難 題。要讓圖片變得清晰,就需要對抗噪聲。
計算機視覺使用統計的方法對抗噪聲,例如,計算機視覺雖然很難通過某個像素或者 這個像素的相鄰像素判斷這個像素是否在圖像主體的邊緣上,但是如果對圖像某一區域內 的像素做統計,那麼上述判斷就變得簡單了,即在指定區域內,圖像主體的邊緣應該表現 為一連串獨立的像素,而且這一連串像素的方向應該是一致的。這部分內容就是本書第 13章要為讀者講解的圖形檢測。
例如,使用圖形檢測的相關方法,能夠把圖1.9中的圖形邊緣繪製成紅色,進而得到 如圖1.10所示的效果
OpenCV包含的模塊
OpenCV包含的模塊的層級結構
OpenCV常用的模塊及其説明
Python OpenCV的開發工具
第二章 搭建開發環境
第三章 圖像處理的基本操作
OpenCV的作用在於讓開發人員更容易地通過編碼來處理圖像。那麼,處理圖像需 要執行哪些操作呢?圖像處理的基本操作包含4個方面的內容:讀取圖像、顯示圖像、保 存圖像和獲取圖像屬性。其中,常用的圖像屬性有3個:shape、size和dtype。本章將 依次詳解實現圖像處理的4個基本操作,並分別闡明常用的3個圖像屬性各自的含義及其 使用方法。
3.1讀取圖像
image = cv2.imread(filename, flags)
image:imread()方法的返回值,返回的是讀取到的圖像。
filename:要讀取的圖像的完整文件名。例如,要讀取當前項目目錄下的 3.1.jpg,filename的值為"3.1.jpg"(雙引號是英文格式的)。
flags:讀取圖像顏色類型的標記。當flags的默認值為1時,表示讀取的是彩色圖像,此時的flags值可以省略;當flags的值為0時,表示讀取的是灰度圖像 (如果讀取的是彩色圖像,也將轉換為與彩色圖像對應的灰度圖像)。
圖像不在工作目錄下的時候,可以用絕對路徑,如"D:/1.jpg"
灰度圖像是一種每個像素都是從黑到白,被處理為256個灰度級別的單色圖像。256 個灰度級別分別用0(純黑色)~255(純白色)的數值表示。
3.2顯示圖像
(1)imshow()方法用於顯示圖像,其語法格式如下:
cv2.imshow(winname, mat)
winname:顯示圖像的窗口名稱。
mat:要顯示的圖像。
(2)waitKey()方法用於等待用户按下鍵盤上按鍵的時間。當用户按下鍵盤上的任 意按鍵時,將執行waitKey()方法,並且獲取waitKey()方法的返回值。其語法格式如下:
retval = cv2.waitKey(delay)
retval:與被按下的按鍵對應的ASCII碼。例如,Esc鍵的ASCII碼是27,當用 户按Esc鍵時,waitKey()方法的返回值是27。如果沒有按鍵被按下,waitKey() 方法的返回值是-1。
delay:等待用户按下鍵盤上按鍵的時間,單位為毫秒(ms)。當delay的值為 負數、0或者空時,表示無限等待用户按下鍵盤上按鍵的時間。
(3)destroyAllWindows()方法用於銷燬所有正在顯示圖像的窗口,其語法格式如 下:
cv2.destroyAllWindows()
3.3保存圖像
在實際開發的過程中,對一幅圖像進行一系列的處理後,需要保存處理圖像後的結 果。為此,OpenCV提供了用於按照指定路徑保存圖像的imwrite()方法,其語法格式如下:cv2.imwrite(filename, img)
filename:保存圖像時所用的完整路徑。(這個沒必要是完整路徑,我是用vs code開發的,所以保存和尋找圖片都是當前工作空間文件夾下的,只要相對路徑就可以保存了)
img:要保存的圖像。
3.4獲取圖像屬性
在處理圖像的過程中,經常需要獲取圖像的大小、類型等圖像屬性。為此, OpenCV提供了shape、size和dtype 3個常用屬性,具體含義分別如下。
shape:如果是彩色圖像,那麼獲取的是一個包含圖像的水平像素、垂直像素 和通道數的數組,即(垂直像素,水平像素,通道數);如果是灰度圖像,那麼 獲取的是一個包含圖像的水平像素和垂直像素的數組,即(垂直像素,水平像 素)。
説明: 垂直像素指的是垂直方向上的像素,水平像素指的是水平方向上的像素。有關像 素、灰度圖像和通道的內容,將在本書的第4章和第5章進行講解
size:獲取的是圖像包含的像素個數,其值為“水平像素×垂直像素×通道 數”。灰度圖像的通道數為1。
dtype:獲取的是圖像的數據類型。
3.5小結
本章主要詳解了兩個內容:圖像處理的基本操作和常用的圖像屬性。
讀者在完成圖像 處理的基本操作的過程中,要注意3個問題:
一是通過更改參數,imread()方法讀取到的圖像既可以是一幅彩色圖像,也可以是一幅灰度圖像;
二是為了能夠正常顯示圖像,要在 cv2.imshow()方法後緊跟着cv2.waitKey()方法;
三是當聲明路徑名 時,“/”和“\\”的作用是等價的(例如,D:/3.1.jpg等價於D:\\3.1.jpg)。
第四章 像素的操作
像素是圖像的最小單位。每一幅圖像都是由M行N列的像素組成的,其中每一個像素 都存儲一個像素值。以灰度圖像為例,計算機通常把灰度圖像的像素處理為256個灰度級 別,256個灰度級別分別使用區間[0, 255]中的整數數值表示。其中,“0”表示純黑 色;“255”表示純白色。本章將圍繞着像素展開,介紹如何使用NumPy模塊操作像 素。
4.1像素
像素是構成數字圖像的基本單位。現有一幅顯示花朵的圖像(見圖4.1),在花瓣邊 緣提取一個小圓圈圈住的區域,將得到一幅如圖4.2所示的圖像。
不難發現,圖4.2所示的圖像是由許多小方塊組成的,通常把一個小方塊稱作一個像 素。因此,一個像素是具有一定面積的一個塊,而不是一個點。需要注意的是,像素的形 狀是不固定的,大多數情況下,像素被認為是方形的,但有時也可能是圓形的或者是其他 形狀的。
4.1.1 確定像素的位置
以圖4.1為例,在訪問圖4.1中的某個像素前,要確定這個像素在圖4.1中的位置。那 麼,這個位置應該如何確定呢?
在Windows 10系統的“畫圖”工具中打開圖4.1,得到如圖4.4所示的界面。在這 個界面中,就會得到圖4.1在水平方向的像素是219個,在垂直方向的像素是292個
説明 圖4.1在水平方向的像素是219個,與其對應的是x軸的取值範圍,即0~218;同 理,在垂直方向的像素是292個,與其對應的是y軸的取值範圍,即0~291。
這樣,就能夠通過座標來確定某個像素在圖4.1中的位置。在OpenCV中,正確表示 圖4.1中某個像素座標的方式是(y, x)。例如,在如圖4.5所示的座標系中,圖4.1右下角 的像素座標是(291, 218)。
4.1.2 獲取像素的BGR值
現使用print()方法打印這個 像素,將得到這個像素的BGR值,代碼如下:
得到的是一個BGR的數組 [247 149 49]
在講解這3個數值各自代表的含義之前,先了解什麼是三基色。
如圖4.6所示,人眼能夠感知紅色、綠色和藍色3種不同的顏色,因此把這3種顏色稱 作三基色。如果將這3種顏色以不同的比例進行混合,人眼就會感知到豐富多彩的顏色。
那麼,對於計算機而言,是如何對這些顏色進行編碼的呢?答案就是利用色彩空間。 也就是説,色彩空間是計算機對顏色進行編碼的模型。
以較為常用的RGB色彩空間為例,在RGB色彩空間中,存在3個通道,即R通道、G 通道和B通道。其中,R通道指的是紅色通道;G通道指的是綠色通道;B通道指的是藍色 通道;並且每個色彩通道都在區間[0, 255]內取值。
這樣,計算機將利用3個色彩通道的不同組合來表示不同的顏色。如圖4.7所示,通 過截圖工具,能夠得到座標(291, 218)上的像素值為(49, 42, 36)。
使用print()方法打印圖4.1中座標(291, 218)上的像素px,其結果是(36, 42, 49)。 而圖4.7中這個座標上的像素值為(49, 42, 36)。這時會發現這兩個結果中的數值是相同 的,但順序是相反的,這是為什麼呢?
原因是在RGB色彩空間中,彩色圖像的通道順序是R(49)→G(42) →B(36);但是,在OpenCV中,RGB色彩空間被BGR色彩空間取代,使得彩色圖像 的通道順序變為了B(36)→G(42)→R(49)。
從上文能夠知曉,在BGR色彩空間的圖像中,每3個數值表示一個像素,這3個數值 分別表示藍色、綠色和紅色3種顏色分量,把每一種顏色分量所在的區域稱作通道。那 麼,OpenCV是如何獲取指定位置上的像素的B通道、G通道和R通道的值呢?
有如下兩種方式(以座標(291, 218)上的像素為例)。
4.1.3 修改像素的BGR值
對於BGR色彩空間的圖像,當每個像素的B、G、R的3個數值相等時,就可以得到灰 度圖像。其中,B=G=R=0為純黑色,B=G=R=255為純白色。
4.2使用NumPy模塊操作像素
圖像在OpenCV中以二維或三維數組表示,數組中的每一個值就是圖像的像素值。 善於操作數組的NumPy模塊就成了OpenCV的依賴包。OpenCV中很多操作都要依賴 NumPy模塊,例如創建純色圖像、創建掩模和創建卷積核等。本節將簡單介紹NumPy 模塊的常用操作方法,並演示如何利用NumPy模塊創建圖像。
4.2.1 NumPy概述
NumPy(見圖4.9)更像是一個魔方(見圖4.10),它是Python數組計算、矩陣運 算和科學計算的核心庫,NumPy來源於Numerical和Python兩個單詞。NumPy提供了 一個高性能的數組對象,以及可以輕鬆創建一維數組、二維數組和多維數組等大量實用方 法,幫助開發者輕鬆地進行數組計算,從而廣泛地應用於數據分析、機器學習、圖像處理 和計算機圖形學、數學任務等領域中。由於NumPy是由C語言實現的,所以其運算速度 非常快。具體功能如下。
1有一個強大的N維數組對象ndarray。
2廣播功能方法。
3線性代數、傅里葉變換、隨機數生成、圖形操作等功能。
4整合C/C++/Fortran代碼的工具。
4.2.2 數組的類型
在對數組進行基本操作前,首先了解一下NumPy的數據類型。NumPy比Python增 加了更多種類的數值類型,如表4.1所示,為了區別於Python數據類型,NumPy中的 bool、int、float、complex等數據類型名稱末尾都加了短下畫線“_”。
這裏要注意,float_ 已經被叉出NumPy了,用的是float64替代
每一種數據類型都有相應的數據轉換方法。舉例如下:
4.2.3 創建數組
NumPy提供了很多創建數組的方法,下面分別介紹。
1.最常規的array()方法
NumPy創建簡單的數組主要使用array()方法,通過傳遞列表、元組來創建NumPy 數組,其中的元素可以是任何對象,語法如下:
numpy.array(object, dtype, copy, order, subok, ndmin)
object:任何具有數組接口方法的對象。
dtype:數據類型。
copy:可選參數,布爾型,默認值為True,則object對象被複制;否則,只有 當__array__返回副本,object參數為嵌套序列,或者需要副本滿足數據類型和 順序要求時,才會生成副本。
order:元素在內存中的出現順序,其值為K、A、C、F。如果object參數不是 數組,則新創建的數組將按行排列(C),如果值為F,則按列排列;如果 object參數是一個數組,則以下順序成立:C(按行)、F(按列)、A(原順 序)、K(元素在內存中的出現順序)。
説明 :當order是' A ',object是一個既不是' C '也不是' F ' order的數組,並且由於 dtype的更改而強制執行了一個副本時,那麼結果的順序不一定是' C '。這可能是一個 bug。
subok:布爾型。如果值為True,則傳遞子類,否則返回的數組將強制為基類 數組(默認值)。
ndmin:指定生成數組的最小維數。
示例:創建一維和二維數組
示例: 創建浮點類型數組
示例: 創建三維數組
2.創建指定維度和數據類型未初始化的數組
創建指定維度和數據類型未初始化的數組主要使用empty()方法,數組元素因為未被 初始化會自動取隨機值。如果要改變數組類型,可以使用dtype參數,如將數組類型設為 整型,dtype=int。
示例 : 創建2行3列的未初始化數組
3.創建用0填充的數組
創建用0填充的數組需要使用zeros()方法,該方法創建的數組元素均為0。OpenCV 經常使用該方法創建純黑圖像。
示例: 創建3行、3列、數字類型為無符號8位整數的純0數組
4.創建用1填充的數組
創建用1填充的數組需要使用ones()方法,該方法創建的數組元素均為1。OpenCV 經常使用該方法創建純掩模、卷積核等用於計算的二維數據。
示例: 創建3行、3列、數字類型為無符號8位整數的純1數組
5.創建隨機數組
randint()方法用於生成一定範圍內的隨機整數數組,左閉右開區間([low,high)), 語法如下:
numpy.random.randint(low,high,size)
low:隨機數最小取值範圍。
high:可選參數,隨機數最大取值範圍。若high為空,取值範圍為(0, low)。
若high不為空,則high必須大於low。
size:可選參數,數組維數。
示例: 創建隨機數組。
4.2.4 操作數組
不用編寫循環即可對數據執行批量運算,這就是NumPy數組運算的特點,NumPy 稱為矢量化。大小相等的數組之間的任何算術運算都可以用NumPy實現。本節主要介紹 如何複製數組和簡單的數組運算。
1 加法運算
例如,加法運算是數組中對應位置的元素相加(即每行對應相加),如圖4.12所 示。
例子 : 使用NumPy創建2個數組,並讓2個數據進行加法運算
2.減法和乘除法運算
示例 : 使用NumPy創建2個數組,並讓2個數組進行減法、乘法和除法運算
方式與上一步一樣,不再演示
3.冪運算
冪是數組中對應位置元素的冪運算,使用“**”運算符進行運算,效果如圖4.14所示。從圖中得出:數組n1的元素1和數組n2的元素3,通過冪運算得到的是1的3次冪; 數組n1的元素2和數組n2的元素4,通過冪運算得到的是2的4次冪。
4.比較運算
NumPy創建的數組可以使用邏輯運算符進行比較運算,運算的結果是布爾值數組, 數組中的布爾值為相比較的數組在相同位置元素的比較結果。
5.複製數組
NumPy提供的array()方法可以使用如下語法複製數據:
n2 = np.array(n1, copy=True)
但開發過程中更常用的是copy()方法,其語法如下:
n2 = n1.copy()
這兩種方法都可以按照原數組的結構、類型、元素值創建出一個副本,修改副本中的 元素不會影響到原數組。
4.2.5 數組的索引和切片
NumPy數組元素是通過數組的索引和切片來訪問和修改的,因此索引和切片是NumPy中最重要、最常用的操作。
1.索引
所謂數組的索引,即用於標記數組中對應元素的唯一數字,從0開始,即數組中的第 一個元素的索引是0,依次類推。NumPy數組可以使用標準Python語法x[obj]的語法對 數組進行索引,其中x是數組,obj是選擇方式。
2.切片式索引
數組的切片可以理解為對數組的分割,按照等分或者不等分,將一個數組切割為多個 片段,與Python中列表的切片操作一樣。NumPy中用冒號分隔切片參數來進行切片操作,語法如下:
[start:stop:step]
start:起始索引,若不寫任何值,則表示從0開始的全部索引。
stop:終止索引,若不寫任何值,則表示直到末尾的全部索引。
step:步長
例如,對數組n1進行一系列切片式索引操作的示意圖如圖4.15所示。
舉例:按照圖4.15所示的切片式索引操作獲取數據中某範圍的元素
切片式索引操作需要注意以下幾點。
(1)索引是左閉右開區間,如上述代碼中的n1[0:2],只能取到索引從0~1的元 素,而取不到索引為2的元素。
(2)當沒有start參數時,代表從索引0開始取數,如上述代碼中的n1[:2]。
(3)start、stop和step 3個參數都可以是負數,代表反向索引。以step參數為 例,如圖4.16所示。
3.二維數組索引
二維數組索引可以使用array[n,m]的方式,以逗號分隔,表示第n個數組的第m個元 素。
4.二維數組切片式索引
注意 這裏是[y, x ]形式
二維數組也支持切片式索引操作,如圖4.18所示就是獲取二維數組中某一塊區域的 索引。
4.2.6 創建圖像
在OpenCV中,黑白圖像實際上就是一個二維數組,彩色圖像是一個三維數組。數 組中每個元素就是圖像對應位置的像素值。因此修改圖像像素的操作實際上就是修改數組 的操作。本節將介紹幾個在OpenCV中常用的操作。
1.創建黑白圖像
在黑白圖像中,像素值為0表示純黑,像素值為255表示純白。
示例 : 創建一個100行、200列(即寬200、高100)的數組,數組元素格式為無符號8位 整數,用0填充整個數組,將該數組當作圖像顯示出來
創建純白圖像有兩種方式:第一種是先純黑圖像,然後將圖像中所有的像素值改為 255;第二種使用NumPy提供的ones()方法創建一個像素值均為1的數組,然後讓數組乘 以255。
示例: 創建一個100行、200列(即寬200、高100)的數組,數組元素格式為無符號8位 整數,用1填充整個數組,然後讓數組乘以255,最後將該數組當作圖像顯示出來
示例 : 先繪製純黑圖像作為背景,然後使用切片式索引操作將圖像中橫座標為50~100、縱 座標為25~75的矩形區域顏色改為純白色
示例:先繪製純黑圖像作為背景,然後在循環中使用切片式索引操作繪製黑白間隔圖像
2.創建彩色圖像
以上實例演示的都是用二維數組表示的黑白圖像,而當顯示生活中豐富多彩的顏色需 要引入光譜三基色的概念時,無法用二維數組表示,而要用到三維數組。OpenCV中彩色圖像默認為BGR格式,彩色圖像的第三個索引表示的就是藍、綠、紅3種顏色的分量。
示例 : 創建彩色圖像數組時要將數組創建成三維數組,元素類型仍然為無符號8位整數
3 . 創建隨機圖像
隨機圖像是指圖像中每一個像素值都是隨機生成的,因為像素之間不會組成有效的視 覺信息,所以這樣的圖像看上去就像雜亂無章的沙子。雖然隨機圖像沒有任何視覺信息, 但對於圖像處理技術仍然很重要,毫無規律的像素數組被稱為干擾圖像的噪聲,可以當作 圖像加密的密鑰。
示例:創建隨機像素的雪花點圖像。
使用NumPy提供的random.randint()方法就可以創建隨機數組,將隨機值的取值範 圍設定在0~256(即像素值範圍),元素類型設定為無符號8位整數
如果要彩色圖像就size=(height, width, 3),dtype必須是uint8,因為這樣範圍是0-255
4.2.7 拼接圖像
NumPy提供了兩種拼接數組的方法,分別是hstack()方法和vstack()方法。這兩種 拼接方法同樣可用於拼接圖像,下面分別介紹。
1.水平拼接數組
hstack()方法可以對數組進行水平拼接(或叫橫向拼接),其語法如下:
array = numpy.hstack(tup)
tup:要拼接的數組元組。
array:將參數元組中的數組水平拼接後生成的新數組。
hstack()方法可以拼接多個數組,拼接效果如圖4.28所示。被拼接的數組必須在每 一個維度都具有相同的長度,也就是數組“形狀相同”,例如2行2列的數組只能拼接2行 2列的數組,否則會出現錯誤。
示例 :創建3個一維數組,將這3個數組進行水平拼接
2.垂直拼接數組
vstack()方法可以對數組進行垂直拼接(或叫縱向拼接),其語法如下:
array = numpy.vstack(tup)
vstack()方法可以拼接多個數組,拼接效果如圖4.29所示。被拼接的數組的格式要求 與hstack()方法相同。
例子: 創建3個一維數組,將這3個數組進行垂直拼接
3.在圖像處理中的應用
在OpenCV中,圖像就是一個二維或三維的像素數組,這些數組同樣可以被NumPy 拼接,下面通過一個實例展示圖像拼接的效果。
4.3 小結
本章詳細講解了像素和使用NumPy模塊操作像素兩個方面的內容。讀者要注意掌握 以下幾個內容:一是在表示圖像某一個像素的座標的時候,正確的表示方式是(垂直像 素,水平像素);二是在OpenCV中,彩色圖像的通道順序是B→G→R;三是重點掌握 且靈活運用NumPy模塊實現圖像的創建和圖像的拼接。
第五章 色彩空間與通道
色彩是人類的眼睛對於不同頻率的光線的不同感受,不同頻率的光線既是客觀存在的 又是人類主觀感知的。為了表示這些不同頻率的光線的色彩,人類建立了多種色彩模型, 把這些色彩模型稱作色彩空間。OpenCV中的BGR色彩空間有3個通道,即表示藍色的B 通道、表示綠色的G通道和表示紅色的R通道。本章將具體講解色彩空間和通道,以及二 者之間的緊密聯繫。
5.1色彩空間
雖然Photoshop把一幅彩色圖像的色彩空間默認為RGB色彩空間,但是OpenCV把 一幅彩色圖像的色彩空間默認為BGR色彩空間,這是因為OpenCV拆分一幅彩色圖像的 通道後,默認的通道順序是B→G→R。熟悉了BGR色彩空間後,本節將結合如圖5.1所 示的圖像,介紹另外兩個比較常見的色彩空間:GRAY色彩空 間和HSV色彩空間。
5.1.1 GRAY色彩空間
GRAY色彩空間通常指的是灰度圖像,灰度圖像是一種每個像素都是從黑到白,被處 理為256個灰度級別的單色圖像。這256個灰度級別分別用區間[0, 255]中的數值表示。 其中,“0”表示純黑色,“255”表示純白色,0~255的數值表示不同亮度(即色彩的 深淺程度)的深灰色或者淺灰色。因此,一幅灰度圖像也能夠展現豐富的細節信息
2.從BGR色彩空間轉換到GRAY色彩空間
兩種圖像都是同一幅圖,只不過,圖5.1是彩色圖 像,而圖5.2是灰度圖像。OpenCV能夠將同一幅圖像從一個色彩空間轉換到另一個色彩 空間。例如,圖5.1從BGR色彩空間轉換到圖5.2所示的GRAY色彩空間。
那麼,OpenCV是如何實現從BGR色彩空間轉換到GRAY色彩空間的呢?答案就是 OpenCV中用於轉換圖像色彩空間的cvtColor()方法
dst = cv2.cvtColor(src, code)
dst:轉換後的圖像。
src:轉換前的初始圖像。
code:色彩空間轉換碼。
注意:當圖像從BGR色彩空間轉換到GRAY色彩空間時,常用的色彩空間轉換碼是 cv2.COLOR_BGR2GRAY。
例子 : 從BGR色彩空間轉換到GRAY色彩空間。
説明 : 雖然色彩空間類型轉換是雙向的,而且OpenCV也提供了cv2.COLOR_GRAY2BGR(從 GRAY色彩空間轉換到BGR色彩空間)和cv2.COLOR_ BGR2GRAY(從BGR色彩空間轉換到 GRAY色彩空間)2個色彩空間轉換碼,但是灰度圖像是無法轉換成彩色圖像的。這是因 為在彩色圖像轉換成灰度圖像的過程中,丟失了顏色比例(即紅色、綠色和藍色之間的 混合比例)。這些比例一旦丟失,就再也找不回來了。
5.1.2 HSV色彩空間
1.什麼是HSV色彩空間
BGR色彩空間是基於三基色而言的,三基色指的是紅色、綠色和藍色。而HSV色彩空間則是基於色調、飽和度和亮度而言的。
其中,色調(H)是指光的顏色,例如,彩虹中的赤、橙、黃、綠、青、藍、紫分別 表示不同的色調,如圖5.4所示。在OpenCV中,色調在區間[0, 180]內取值。例如,代 表紅色、黃色、綠色和藍色的色調值分別為0、30、60和120。
飽和度(S)是指色彩的深淺。在OpenCV中,飽和度在區間[0, 255]內取值。當飽 和度為0時,圖像將變為灰度圖像。
如圖所示,亮度(V)是指光的明暗。與飽和度相同,在OpenCV中,亮度在區 間[0, 255]內取值。亮度值越大,圖像越亮;當亮度值為0時,圖像呈純黑色。
2.從BGR色彩空間轉換到HSV色彩空間
OpenCV提供的cvtColor()方法不僅能將圖像從BGR色彩空間轉換到GRAY色彩空 間,還能將圖像從BGR色彩空間轉換到HSV色彩空間。當圖像在BGR色彩空間和HSV色 彩空間之間轉換時,常用的色彩空間轉換碼是cv2.COLOR_BGR2HSV和cv2.COLOR_HSV2BGR。
示例: 從BGR色彩空間轉換到HSV色彩空間。
5.2通道
在BGR色彩空間中,圖像的通道由B通道、G通道和R通道構成。本節將介紹如何使 用OpenCV提供的方法拆分和合並通道。
5.2.1 拆分通道
為了拆分圖像中的通道,OpenCV提供了split()方法。
1.拆分一幅BGR圖像中的通道
當使用split()方法拆分一幅BGR圖像中的通道時,split()方法的語法如下:
b, g, r = cv2.split(bgr_image)
b:B通道圖像。
g:G通道圖像。
r:R通道圖像。
bgr_image:一幅BGR圖像。
例子: 拆分一幅BGR圖像中的通道。
R通道是紅色通道,G通道是綠色通道,B通道是藍色通道。
但是圖中的B通道圖 像、G通道圖像和R通道圖像是3幅不同亮度的灰度圖像,這是為什麼呢?
原因是當程序執行到cv2.imshow("B", b)時,原圖像B、G、R這3個通道的值都會被 修改為B通道圖像的值,即(b, b, b)。同理,當程序執行到cv2.imshow("G", g)和 cv2.imshow("R", r)時,原圖像R、G、B這3個通道的值將依次被修改為G通道圖像的值(g, g, g)和R通道圖像的值(r, r, r)。對於BGR圖像,只要B、G、R這3個通道的值都相 同,就可以得到灰度圖像。
2.拆分一幅HSV圖像中的通道
當使用split()方法拆分一幅HSV圖像中的通道時,split()方法的語法如下:
h, s, v = cv2.split(hsv_image)
h:H通道圖像。
s:S通道圖像。
v:V通道圖像。
hsv_image:一幅HSV圖像。
示例: 拆分一幅HSV圖像中的通道。
5.2.2 合併通道
合併通道是拆分通道的逆過程。以圖5.1為例,雖然拆分通道後,會得到3幅不同亮 度的灰度圖像;但是將這3幅不同亮度的灰度圖像合併後,又重新得到圖5.1。下面將使用OpenCV中用於合併通道的merge()方法,驗證一下上述説法。
1.合併B通道圖像、G通道圖像和R通道圖像
當使用merge()方法按B→G→R的順序合併通道時,merge()方法的語法如下:
bgr = cv2.merge([b, g, r])
bgr:按B→G→R的順序合併通道後得到的圖像。
b:B通道圖像。
g:G通道圖像。
r:R通道圖像。
示例: 合併B通道圖像、G通道圖像和R通道圖像。
2.合併H通道圖像、S通道圖像和V通道圖像
當使用merge()方法合併H通道圖像、S通道圖像和V通道圖像時,merge()方法的語 法如下:
hsv = cv2.merge([h, s, v])
hsv:合併H通道圖像、S通道圖像和V通道圖像後得到的圖像。
h:H通道圖像。
s:S通道圖像。
v:V通道圖像。
示例: 合併H通道圖像、S通道圖像和V通道圖像。
5.2.3 綜合運用拆分通道和合並通道
在HSV色彩空間內,如果保持其中兩個通道的值不變,調整第3個通道的值,會得到 相應的藝術效果。
示例: 只把H通道的值調整為180。
同理,H通道,S通道,V通道都可以改變
5.2.4 alpha通道
BGR色彩空間包含了3個通道,即B通道、G通道和R通道。OpenCV在BGR色彩空 間的基礎上,又增加了一個用於設置圖像透明度的A通道,即alpha通道。這樣,形成一 個由B通道、G通道、R通道和A通道4個通道構成的色彩空間,即BGRA色彩空間。在BGRA色彩空間中,alpha通道在區間[0, 255]內取值;其中,0表示透明,255表示不透 明。
示例: 調整A通道的值。
雖然在代碼中已經調整了BGRA圖像中A通道的值,但是顯示圖像的效果是一樣的。 為了顯示3幅圖像的不同效果,需要使用imwrite()方法將3幅圖像保存在D盤根目錄下, 代碼如下:
説明 : PNG圖像是一種典型的4通道(即B通道、G通道、R通道和A通道)圖像,因此被保存 的3幅圖像的格式均為.png。
那麼就可以理解了,為什麼顯示的時候三張圖片是一樣的了,顯示默認是jpg顯示,沒有a通道,保存下來再去查看就可以裏
5.3小結
當使用cvtColor()方法轉換色彩空間時,雖然彩色圖像能夠轉換為灰度圖像,但是灰 度圖像不能轉換為彩色圖像。對於HSV色彩空間,如果保持其中兩個通道的值不變,調 整第3個通道的值,會得到相應的藝術效果。為了能夠顯示藝術效果,要把合併通道後的 圖像從HSV色彩空間轉換到BGR色彩空間。當使用alpha通道設置圖像的透明度時,為 了能夠直觀地看到圖像的透明效果,需先保存已經設置透明度的圖像。