一.圖像色彩空間轉換
1.1 HSV顏色空間
HSV顏色空間使用色調(Hue)、飽和度(Saturation)和亮度(Value)三個參數來表示顏色
一般對顏色空間的圖像進行有效處理都是在HSV空間進行的,然后對于基本色中對應的HSV分量需要給定一個嚴格的范圍,下面是通過實驗計算的模糊范圍(準確的范圍在網上都沒有給出)。
H: 0— 180
S: 0— 255
V: 0— 255
也就是可以通過顏色的范圍來提取圖像中的一種或多種顏色。
HSV的好處:
- 符合人類對顏色的感知方式:人類對顏色的感知是基于色調、飽和度和亮度三個維度的,而HSV顏色空間恰好就是通過這三個維度來描述顏色的。因此,使用HSV空間處理圖像可以更直觀地調整顏色和進行色彩平衡等操作,更符合人類的感知習慣。
- 顏色調整更加直觀:例如,在RGB空間中要調整紅色系的顏色,需要同時調整R、G、B三個通道的數值,而在HSV空間中只需要調整色調和飽和度即可。
- 降維處理有利于計算:在圖像處理中,降維處理可以減少計算的復雜性和計算量。HSV顏色空間相對于RGB顏色空間,減少了兩個維度(紅、綠、藍)
1.2 顏色空間轉換
cv2.cvtColor(img,code)
code:指定轉換的類型,可以使用預定義的轉換代碼。
- cv2.COLOR_RGB2GRAY 表示從RGB到灰度圖像的轉換
- cv2.COLOR_BGR2HSV?從RGB到HSV的轉換
二.灰度化
彩色圖是由R、G、B三個通道組成,而灰度圖只有一個通道。
灰度圖像與黑白圖像不同,在計算機圖像領域中黑白圖像只有黑色與白色兩種顏色但是,灰度圖像的取值可以是0~255,不過只有一個通道。這樣可以有256級灰度
# 在讀取時也可以直接將其轉化為灰度圖
import cv2 as cvimg = cv.imread('../images/flower.png', cv.IMREAD_GRAYSCALE)
cv.imshow('Gray Image', img)
cv.waitKey(0)
cv.destroyAllWindows()
2.1 最大值法
從R、G、B三個通道的值中選出最大的一個,并將其作為灰度圖像中對應位置的像素值.
2.2 平均值法
將R、G、B三個通道的像素值全部加起來,然后再除以三。
2.3 加權均值法(最常用且內置)
????????按照一定的權重去乘以每個通道的像素值,并將其相加,得到最后的值就是灰度圖像中對應位置的像素值。權重的比例為: R乘以0.299,G乘以0.587,B乘以0.114,這是經過大量實驗得到的一個權重比例,也是一個比較常用的權重比例
import cv2 as cvimg = cv.imread('../images/flower.png')
flower = cv.resize(img,(200, 200))gray = cv.cvtColor(flower, cv.COLOR_BGR2GRAY)cv.imshow('Original', flower)
cv.imshow('Gray', gray) cv.waitKey(0)
cv.destroyAllWindows()
三. 二值化處理
二值圖像的二維矩陣僅由兩個值構成,也就是灰度圖像的取值范圍變了,只有0,1
- 其操作的圖像必須是灰度圖
二值化處理函數:
_,binary = cv2.threshold(img,thresh,maxval,type)
- img:輸入圖像,要進行二值化處理的灰度圖。
- thresh:設定的閾值。
- maxval:當像素值大于(或小于,取決于閾值類型)thresh時,該像素被賦予的值。
- type:閾值處理的類型。
- 返回值:
? - 第一個值(通常用下劃線表示):計算出的閾值,若使用自適應閾值法,會根據算法自動計算出這個值。
? - 第二個值(binary):二值化后的圖像矩陣。與輸入圖像尺寸相同。
3.1 閾值法
THRESH_BINARY
????????設置一個閾值,將灰度圖中的每一個像素值與該閾值進行比較,小于等于閾值的像素就被設置為0(通常代表背景),大于閾值的像素就被設置為maxval(通常為255)
import cv2 as cvimg = cv.imread('../images/flower.png')
flower = cv.resize(img,(200, 200))# 獲得灰度圖
gray = cv.cvtColor(flower, cv.COLOR_BGR2GRAY)# 使用閾值法二值化
_,binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY)cv.imshow('flower', gray)
cv.imshow('binary', binary)
cv.waitKey(0)
cv.destroyAllWindows()
3.2 反閾值法
THRESH_BINARY_INV
與閾值法相反
import cv2 as cvimg = cv.imread('../images/flower.png')
flower = cv.resize(img,(200, 200))# 獲得灰度圖
gray = cv.cvtColor(flower, cv.COLOR_BGR2GRAY)# 使用反閾值法二值化
_,binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY_INV)cv.imshow('flower', gray)
cv.imshow('binary', binary)
cv.waitKey(0)
cv.destroyAllWindows()
3.3 截斷閾值法
THRESH_TRUNC
所有像素與閾值進行比較,像素值大于閾值的部分將會被修改為閾值,小于等于閾值的部分不變
import cv2 as cvimg = cv.imread('../images/flower.png')
flower = cv.resize(img,(200, 200))# 獲得灰度圖
gray = cv.cvtColor(flower, cv.COLOR_BGR2GRAY)# 使用截斷閾值法二值化
# 可以看到我們依然給了maxval,但是實際上這個maxval沒有起作用,但是還是要寫不然會報錯
_,binary = cv.threshold(gray, 127, 255, cv.THRESH_TRUNC)cv.imshow('flower', gray)
cv.imshow('binary', binary)
cv.waitKey(0)
cv.destroyAllWindows()
3.4 低閾值零處理
THRESH_TOZERO
像素值小于等于閾值的部分被置為0,大于閾值的部分不變。
import cv2 as cvimg = cv.imread('../images/flower.png')
flower = cv.resize(img,(200, 200))# 獲得灰度圖
gray = cv.cvtColor(flower, cv.COLOR_BGR2GRAY)# 使用低閾值零處理二值化_,binary = cv.threshold(gray, 127, 255, cv.THRESH_TOZERO)cv.imshow('flower', gray)
cv.imshow('binary', binary)
cv.waitKey(0)
cv.destroyAllWindows()
3.5 超閾值零處理
THRESH_TOZERO_INV
像素值大于閾值的部分置為0,像素值小于等于閾值的部分不變。
import cv2 as cvimg = cv.imread('../images/flower.png')
flower = cv.resize(img,(200, 200))# 獲得灰度圖
gray = cv.cvtColor(flower, cv.COLOR_BGR2GRAY)# 使用超閾值零處理二值化
_,binary = cv.threshold(gray, 127, 255, cv.THRESH_TOZERO_INV)cv.imshow('flower', gray)
cv.imshow('binary', binary)
cv.waitKey(0)
cv.destroyAllWindows()
3.6 OTSU閾值法
cv2.THRESH_OTS
?cv2.THRESH_OTS 并不是一個有效的閾值類型或標,它其實是用來計算合適閾值的方法,通常與 THRESH_BINARY?或 THRESH_BINARY_INV?結合使用
OTSU算法是通過一個值將這張圖分前景和背景
(也就是灰度圖中小于這個值的是一類,大于這個值的是一類。例如,如果你設置閾值為128,則所有大于128的像素點可以被視作前景,而小于等于128的像素點則被視為背景。)
????????通過統計學方法(最大類間方差)來驗證該值的合理性,當根據該值進行分割時,使用最大類間方差計算得到的值最大時,該值就是二值化算法中所需要的閾值。通常該值是從灰度圖中的最小值加1開始進行迭代計算,直到灰度圖中的最大像素值減1,然后把得到的最大類間方差值進行比較。
import cv2 as cvimg = cv.imread('../images/flower.png')
flower = cv.resize(img,(200, 200))# 獲得灰度圖
gray = cv.cvtColor(flower, cv.COLOR_BGR2GRAY)# 使用OTSU閾值法二值化(默認是結合閾值法即THRESH_BINARY)
_,binary = cv.threshold(gray, 127, 255, cv.THRESH_OTSU)
# 結合反閾值法
_,binary1 = cv.threshold(gray, 0, 255, cv.THRESH_OTSU+cv.THRESH_BINARY_INV)cv.imshow('flower', gray)
cv.imshow('binary', binary)
cv.imshow('binary1', binary1)
cv.waitKey(0)
cv.destroyAllWindows()
3.7 自適應二值化
????????其會對圖像中的所有像素點計算其各自的閾值,將圖像劃分為固定大小的塊,然后對每個塊進行閾值處理。
cv2.adaptiveThreshold
(image_np_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 7, 10)
參數:
maxval:最大閾值,一般為255
adaptiveMethod:小區域閾值的計算方式:
ADAPTIVE_THRESH_MEAN_C:小區域內取均值
ADAPTIVE_THRESH_GAUSSIAN_C:小區域內加權求和,權重是個高斯核
thresholdType:二值化方法,只能使用THRESH_BINARY、THRESH_BINARY_INV,也就是閾值法和反閾值法
blockSize:選取的小區域的面積,如7就是7\*7的小塊。
C:最終閾值等于小區域計算出的閾值再減去此值
?
????????自適應二值化更加適合用在明暗分布不均的圖片,因為圖片的明暗不均,導致圖片上的每一小部分都要使用不同的閾值進行二值化處理。
3.7.1 取均值
????????從圖片的左上角開始計算其鄰域內的平均值,用一個均值卷積核來實現,將卷積核中心對準要閾值處理的像素,然后計算這個卷積核內所有像素的平均值,最后減去常數C得到該點閾值。
如圖,如果像取第一個元素卷積核有空缺處,就按邊緣填充的方式填充。
3.7.2 加權求和
????????對小區域內的像素進行加權求和得到新的閾值,其權重值來自于高斯分布。與取均值的區別就是采用另一種規則的卷積核進行閾值選擇,函數中有著基本相同的參數。
3*3卷積核示例: