在本教程中组砚,我們將學(xué)習(xí)如何完全自動地從照片中消除紅眼吻商。
如何自動刪除紅眼?
第1步:眼睛檢測
第一步是自動檢測眼睛糟红。我們使用標(biāo)準(zhǔn)的OpenCV Haar檢測器(haarcascade_eye.xml)來尋找眼睛愚铡。有時淘邻,首先運(yùn)行面部檢測器然后檢測面部區(qū)域內(nèi)的眼睛是有意義的。為了簡單起見,我們直接在圖像上運(yùn)行眼睛檢測器捧书。當(dāng)輸入圖像是人像拍攝,或者你有眼睛的特寫鏡頭時虏束,跳過面部檢測器楞黄。
第2步:遮住紅眼睛
接下來,我們需要找到受紅眼影響的瞳孔部分句旱。有許多不同的方法可以找到紅色的東西阳藻。需要注意的一點(diǎn)是,我們的顏色不僅僅是紅色谈撒,而是鮮紅色腥泥!你可以根據(jù)色度和亮度將圖像轉(zhuǎn)換為HSV色彩空間和閾值。在這篇文章中啃匿,我們使用了一種更簡單的啟發(fā)式方法蛔外。我們說他的紅色通道應(yīng)該大于閾值,也是綠色和藍(lán)色通道的總和溯乒。出于概念驗證系統(tǒng)的目的夹厌,啟發(fā)式是足夠的,但如果你想為商業(yè)軟件包構(gòu)建自動防紅眼裆悄,你需要收集成千上萬的紅眼圖像才能做出更好的東西矛纹。
在下面的代碼中,我們遍歷我們在上一步中檢測到的所有眼睛矩形光稼。然后我們使用命令split將彩色圖像分割成三個通道或南。最后孩等,我們?yōu)槊總€像素創(chuàng)建一個掩碼,其中紅色通道高于閾值(150)采够,紅色通道大于綠色和藍(lán)色通道的總和肄方。
代碼:
for (x, y, w, h) in eyes:
??# 從圖像中提取眼睛的位置
??eye = img[y:y+h, x:x+w]
??# 將眼睛圖像分離成3通道
??b = eye[:, :, 0]
??g = eye[:, :, 1]
??r = eye[:, :, 2]
??# 添加綠色和藍(lán)色通道
??bg = cv2.add(b, g)
??# 簡單的紅眼檢測器
??mask = (r > 150) &??(r > bg)
??# 將掩碼轉(zhuǎn)換為uint8格式
??mask = mask.astype(np.uint8)*255
3步:清理瞳孔掩碼
?
圖1:左:基于顏色的瞳孔掩模 中間:填充孔的瞳孔掩模 右:膨脹瞳孔掩模
在上一步中創(chuàng)建的掩模很可能會有洞。圖1中的左圖顯示了使用顏色處理獲得的原始掩模蹬癌。我們使用下面分享的代碼刪除了掩碼中的洞权她。
def fillHoles(mask):
? ? maskFloodfill = mask.copy()
? ? h, w = maskFloodfill.shape[:2]
? ? maskTemp = np.zeros((h+2, w+2), np.uint8)
? ? cv2.floodFill(maskFloodfill, maskTemp, (0, 0), 255)
? ? mask2 = cv2.bitwise_not(maskFloodfill)
? ? return mask2 | mask
此外,膨脹掩模是一個好主意逝薪,以便于它覆蓋了比需要的區(qū)域稍大隅要。這是因為在邊界處顏色逐漸消失,并且在我們的最初掩模中可能沒有捕捉到一些紅色翼闽。在圖1中拾徙,右圖是膨脹的掩模。我們使用下面分享的代碼來膨脹掩模感局。
# 通過填充孔和膨脹來清理掩模
mask = fillHoles(mask)
mask = cv2.dilate(mask, None, anchor=(-1, -1), iterations=3, borderType=1, borderValue=1)
4步:修復(fù)紅眼
現(xiàn)在我們有一個只包含每只眼睛紅色區(qū)域的掩模尼啡。我們接下來展示如何處理這個掩模內(nèi)的區(qū)域以修復(fù)紅眼。
我們知道紅眼睛會使圖像中的紅色通道飽和询微。換句話說崖瞭,紅色通道中的所有信息都被破壞。我們怎樣才能恢復(fù)這些信息呢撑毛?修復(fù)紅眼時书聚,我們不需要在紅色通道中檢索真正的底層紋理;?我們只需要找到合理的紋理。
幸運(yùn)的是藻雌,紅眼效果僅在紅色通道中破壞紋理;?藍(lán)色和綠色通道仍然很好雌续。您可以在下圖中看到圖像的紅色,綠色和藍(lán)色通道
?
圖2:左:紅色通道 中間:藍(lán)色通道 右:綠色通道
可以使用綠色和藍(lán)色通道的組合來提供合理的紅色通道胯杭。例如驯杜,我們可以創(chuàng)建一個紅色通道,它是圖像中綠色和藍(lán)色通道的平均值做个。然而鸽心,這樣做可能會給瞳孔帶來輕微的色調(diào),看起來不錯居暖,但不是很好顽频。注意中心圖像中的紫色調(diào)
?
圖3:左:紅眼?中間:通過更換紅色通道修復(fù)?右:通過更換所有通道修復(fù)
這給我們帶來了一個重要問題。瞳孔的顏色應(yīng)該是什么太闺?瞳孔是眼睛的開口糯景,眼睛的內(nèi)部是完全黑暗的。因此,瞳孔應(yīng)該是無色的(灰度)和黑暗的莺奸。我們不是僅僅替換瞳孔區(qū)域中的紅色通道丑孩,而是用綠色和藍(lán)色通道的平均值替換所有通道,這就消除了紫色調(diào)灭贷。
下面的代碼首先通過平均綠色和藍(lán)色通道來創(chuàng)建平均通道。然后用該平均通道替換所有通道的掩模區(qū)域內(nèi)的所有像素
# 通過平均綠色和藍(lán)色通道值來計算平均通道
#Recall, bg = cv2.add(b, g)
mean = bg / 2
mask = mask.astype(np.bool)[:, :, np.newaxis]
mean = mean[:, :, np.newaxis]
# 從初始圖像中復(fù)制眼睛
eyeOut = eye.copy()
# 將平均圖像復(fù)制到輸出圖像
np.copyto(eyeOut, mean, where=mask)
步驟5:更換修復(fù)的眼睛區(qū)域
在上一步中略贮,我們修復(fù)了三個通道甚疟。最后一步是合并三個通道以創(chuàng)建RGB圖像,然后將此修復(fù)的眼睛區(qū)域放回原始圖像中逃延。
代碼:
# 將修復(fù)的眼睛復(fù)制到輸出圖像
imgOut[y:y+h, x:x+w, :] = eyeOut
自動紅眼消除結(jié)果
我們首先在開始的示例圖像上顯示結(jié)果览妖。
?
圖4:紅眼消除結(jié)果
請注意,從瞳孔掩模區(qū)域移除所有顏色會使圖像看起來很漂亮揽祥,因為眼睛中心的點(diǎn)是完全白色的讽膏。還要注意,在瞳孔的邊界上紅色消失拄丰,但是由于膨脹操作府树,我們?nèi)匀豢梢圆东@到該區(qū)域。
openCV【實踐系列】7——面部標(biāo)志檢測
https://bbs.easyaiforum.cn/thread-854-1-1.html
(出處: 易學(xué)智能)