圖像間的超快速色彩傳遞(P1)
安裝
假設(shè)您已經(jīng)安裝了OpenCV(帶有Python綁定)和NumPy,最簡(jiǎn)單的安裝方法是使用pip:
代碼解釋
我已經(jīng)創(chuàng)建了一個(gè)PyPI包,你可以用它在你自己的圖像之間進(jìn)行顏色轉(zhuǎn)換。該代碼也可以在GitHub上獲得。
(以下為GitHub的代碼鏈接:
https://github.com/jrosebr1/color_transfer)
不管怎樣,讓我們卷起袖子,把手弄臟,看看color_transfer包
下面發(fā)生了什么:
第3行和第4行導(dǎo)入我們需要的包。我們將使用NumPy進(jìn)行數(shù)值處理,使用CV2進(jìn)行OpenCV綁定。
從那里,我們?cè)诘?行定義了顏色傳遞函數(shù)。此函數(shù)執(zhí)行顏色從源圖像(第一個(gè)參數(shù))到目標(biāo)圖像(第二個(gè)參數(shù))的實(shí)際傳輸。
Reinhard等人詳細(xì)介紹的算法表明,應(yīng)該使用L*a*b*顏色空間,而不是標(biāo)準(zhǔn)RGB。為了處理這個(gè)問(wèn)題,我們將源圖像和目標(biāo)圖像轉(zhuǎn)換為第9行和第10行的L*a*b*顏色空間(步驟1和2)。
OpenCV將圖像表示為多維NumPy數(shù)組,但默認(rèn)為uint8數(shù)據(jù)類型。這在大多數(shù)情況下都很好,但在執(zhí)行顏色轉(zhuǎn)移時(shí),我們可能會(huì)有負(fù)值和十進(jìn)制值,因此我們需要使用浮點(diǎn)數(shù)據(jù)類型。
現(xiàn)在,讓我們開始執(zhí)行實(shí)際的顏色轉(zhuǎn)移:
第12行和第13行調(diào)用image_stats函數(shù),我將在幾段中詳細(xì)討論。 但就現(xiàn)時(shí)而言,要知道該函數(shù)只是分別計(jì)算每個(gè)L*、a*和b*通道的點(diǎn)數(shù)強(qiáng)度的平均值和標(biāo)準(zhǔn)差(步驟3和4)。
現(xiàn)在我們有了源影像和目標(biāo)影像的每個(gè)L*a*b*通道的平均值和標(biāo)準(zhǔn)差,我們現(xiàn)在可以執(zhí)行顏色轉(zhuǎn)移。
在第17-20行,我們將目標(biāo)影像分割為L(zhǎng)*、a*和b*分量,並減去它們各自的平均值(步驟5)。
從這裡開始,我們?cè)诘?3-25行上執(zhí)行第6步,按目標(biāo)標(biāo)準(zhǔn)差除以源影像標(biāo)準(zhǔn)差的比率進(jìn)行縮放。
然後,我們可以應(yīng)用第7步,將第28-30行的源通道平均值相加。
第8步是在第34-36行處理的,在這裡我們剪輯掉範(fàn)圍[0255]之外的值(在L*a*b*顏色空間的OpenCV實(shí)現(xiàn)中,這些值被縮放到範(fàn)圍[0255],儘管這不是原始L*a*b*規(guī)範(fàn)的一部分)。
最後,我們?cè)诘?1行和第42行執(zhí)行第9步和第10步,將縮放的L*a*b*通道合併在一起,最後轉(zhuǎn)換回原始RGB顏色空間。
最後,我們?cè)诘?5行返回彩色轉(zhuǎn)印影像。
讓我們快速查看image_stats函數(shù),以完成以下程式碼解釋:
這里我們定義image_stats函數(shù),它接受一個(gè)參數(shù):我們要計(jì)算統(tǒng)計(jì)數(shù)據(jù)的圖像。
在調(diào)用CV2之前,我們假設(shè)圖像已經(jīng)在L*a*b*顏色空間中。在第46行拆分,將我們的圖像拆分為各自的頻道。
從這里開始,第47-49行處理計(jì)算每個(gè)通道的平均值和標(biāo)準(zhǔn)偏差。
最后,在第52行返回每個(gè)通道的平均值和標(biāo)準(zhǔn)偏差的元組。