使用Python和OpenCV在图像之间执行超快速的颜色转换
使用Python和OpenCV在圖像之間執(zhí)行超快速的顏色轉(zhuǎn)換
- 1. 效果圖
 - 2. 原理
 - 2.1 顏色轉(zhuǎn)移算法
 - 2.2 步驟
 - 2.3 算法改進(jìn)
 
- 3. 源碼
 - 參考
 
這篇博客將介紹如何使用Python和OpenCV在圖像之間執(zhí)行超快速的顏色轉(zhuǎn)換。
 與Reinhard基于直方圖的顏色傳遞方法不同,該方法嚴(yán)格依賴Lab*顏色空間中像素強(qiáng)度的平均值和標(biāo)準(zhǔn)偏差,因此非常高效,能夠快速處理非常大的圖像。
1. 效果圖
如下圖所示,將左圖水母藍(lán)轉(zhuǎn)移到中間珊瑚紅上,得到轉(zhuǎn)換空間后的圖想藍(lán)紅珊瑚圖
 
 效果圖2如下,將原圖珊瑚紅的色彩轉(zhuǎn)移到中間水母藍(lán)圖像上,得到右側(cè)的有點(diǎn)紫白蘭的水母圖
 
2. 原理
2.1 顏色轉(zhuǎn)移算法
有倆種方法可以實(shí)現(xiàn)顏色轉(zhuǎn)換:
-  
基于直方圖的方法,該方法旨在平衡三種“類型”的垃圾箱:相等、過量和不足。
該方法效果好,但以犧牲速度為代價(jià)。使用此算法需要對(duì)源圖像中的每個(gè)像素執(zhí)行查找,這將隨著圖像大小的增長而變得非常昂貴。 -  
顏色轉(zhuǎn)移算法——它只使用L * a * b 圖像通道的平均值和標(biāo)準(zhǔn)偏差。沒有復(fù)雜的代碼,沒有計(jì)算直方圖,只是簡單的統(tǒng)計(jì)數(shù)字。這種方法可以輕松地處理巨大的圖像。
 
通過分別利用Lab顏色空間和每個(gè)L、a和b通道的平均值和標(biāo)準(zhǔn)偏差,可以在兩幅圖像之間傳遞顏色。
2.2 步驟
- 輸入源圖像和目標(biāo)圖像。源圖像包含希望目標(biāo)圖像模擬的顏色空間。左側(cè)的日落圖像是我的源,中間的圖像是我的目標(biāo),右側(cè)的圖像是應(yīng)用于目標(biāo)的源的顏色空間。
 - 將源圖像和目標(biāo)圖像轉(zhuǎn)換為Lab顏色空間。**Lab顏色空間模擬感知一致性,其中顏色值的微小變化也應(yīng)產(chǎn)生顏色重要性的相對(duì)相等變化。與標(biāo)準(zhǔn)RGB顏色空間相比,Lab*顏色空間在模擬人類如何解讀顏色方面做得更好,它在顏色傳遞方面非常有效。**
 - 拆分源和目標(biāo)的通道。
 - 計(jì)算源圖像和目標(biāo)圖像的每個(gè)Lab*通道的平均值和標(biāo)準(zhǔn)偏差。
 - 從目標(biāo)通道中減去目標(biāo)圖像的Lab*通道的平均值。
 - 通過目標(biāo)的標(biāo)準(zhǔn)偏差除以源的標(biāo)準(zhǔn)偏差,再乘以目標(biāo)通道,對(duì)目標(biāo)通道進(jìn)行縮放。
 - 為源添加Lab*通道的方式。
 - 剪裁范圍[0,255]之外的任何值(注意:此步驟不是原始文件的一部分。我添加它是因?yàn)镺penCV處理顏色空間轉(zhuǎn)換的方式。如果要在不同的語言/庫中實(shí)現(xiàn)此算法,則必須自己執(zhí)行顏色空間轉(zhuǎn)換,或者了解庫如何進(jìn)行轉(zhuǎn)換)。
 - 將頻道重新合并在一起。
 - 從Lab*空間轉(zhuǎn)換回RGB顏色空間。
 
2.3 算法改進(jìn)
雖然Reinhard等人的算法速度極快,但有一個(gè)特別的缺點(diǎn)——它依賴于全局顏色統(tǒng)計(jì),因此具有類似像素強(qiáng)度值的大區(qū)域會(huì)顯著影響平均值(從而影響整體顏色轉(zhuǎn)移)。
優(yōu)化可以考慮兩種方案:
-  
在較小的感興趣區(qū)域(ROI)中計(jì)算源圖像的平均值和標(biāo)準(zhǔn)偏差,ROI是希望模擬的顏色,而不是使用整個(gè)圖像。采用這種方法將使平均值和標(biāo)準(zhǔn)偏差更好地表示期望使用的顏色空間。
 -  
對(duì)兩幅圖像應(yīng)用k均值聚類。可以在Lab*顏色空間中對(duì)每個(gè)圖像的像素強(qiáng)度進(jìn)行聚類,然后使用歐幾里德距離確定兩個(gè)圖像之間最相似的質(zhì)心。然后,只計(jì)算這些區(qū)域內(nèi)的統(tǒng)計(jì)數(shù)據(jù)。同樣這將使平均值和標(biāo)準(zhǔn)差產(chǎn)生更“局部”的影響,并有助于緩解全局統(tǒng)計(jì)數(shù)據(jù)的過度代表性問題。 缺點(diǎn)是這種方法速度要慢得多。
 
3. 源碼
# USAGE
# python example.py --source images/sm.jpg --target images/sh.jpgimport argparseimport cv2
# 導(dǎo)入必要的類
from color_transfer import color_transferdef show_image(title, image, width=300):# 縮放照片為固定寬度像素,默認(rèn)300像素r = width / float(image.shape[1])dim = (width, int(image.shape[0] * r))resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)# 展示縮放的照片cv2.imshow(title, resized)def str2bool(v):if v.lower() in ('yes', 'true', 't', 'y', '1'):return Trueelif v.lower() in ('no', 'false', 'f', 'n', '0'):return Falseelse:raise argparse.ArgumentTypeError('Boolean value expected.')# 構(gòu)建命令行參數(shù)及解析
ap = argparse.ArgumentParser()
ap.add_argument("-s", "--source", required=True,help="Path to the source image")
ap.add_argument("-t", "--target", required=True,help="Path to the target image")
ap.add_argument("-o", "--output", help="Path to the output image (optional)")
args = vars(ap.parse_args())# 加載照片
source = cv2.imread(args["source"])
target = cv2.imread(args["target"])# 轉(zhuǎn)換原圖的顏色到目標(biāo)圖像
transfer = color_transfer(source, target)# 檢查是否保存輸出圖像
if args["output"] is not None:cv2.imwrite(args["output"], transfer)# 展示照片直至按鍵
show_image("Source", source)
show_image("Target", target)
show_image("Transfer", transfer)
cv2.waitKey(0)
 
參考
- https://www.pyimagesearch.com/2014/06/30/super-fast-color-transfer-images/
 - https://github.com/seminar2012/color_transfer
 
總結(jié)
以上是生活随笔為你收集整理的使用Python和OpenCV在图像之间执行超快速的颜色转换的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: OpenCV-Python绑定如何工作及
 - 下一篇: OpenCV中的对极几何和对极约束