welsh顏色遷移演算法實現過程 python版

2021-09-19 07:32:50 字數 3446 閱讀 2716

很久很久以前,筆者曾經研究學習過welsh演算法,並用c++實現過,見鏈結 welsh顏色遷移演算法實現過程;後來心血來潮想再看看效果,卻發現opencv的版本已經更迭變化太快了,且有學友也想復現一下實驗效果,因此決定用再用python實現一次改演算法。

welsh的流程如下:

1.將目標影象和樣本影象轉換到lab空間;

2.對目標影象和樣本影象進行亮度重對映,保證後續的畫素匹配正確進行;

3.從參考中選擇一部分樣本點,將這些樣本點的畫素亮度值l和領域亮度值σ得方差儲存起來,作為權值w,w = l/2 + σ/2;

4.對目標影象進行逐畫素掃瞄,對每個畫素,計算其權值w,即為亮度值l和領域亮度值σ之和然後除以2,然後在第三步得到的樣本點鐘找到與其權值最接近的參考點,並將改點的a通道和b通道的值賦給目標影象的畫素。

5.將影象從lab空間轉化到rgb空間。

for _ in range(self.segment):

height_index = np.random.choice(self.height_array)

width_index = np.random.choice(self.width_array)

pixel = pixel(height_index, width_index)

pixel_light = self.l_image[pixel.x, pixel.y]

pixel_a = self.a_image[pixel.x, pixel.y]

pixel_b = self.b_image[pixel.x, pixel.y]

pixel_std = self.get_domain_std(pixel)

pixel_a,

pixel_b))

weight_list.sort()

return weight_list

segment是我們需要選取的參考點個數,pixel和weightpixel是我們自定義的類,看不懂沒關係,後續我會上傳整個**,大致意思就是計算參考點附近的權值w,然後儲存到乙個列表中,weightpixel是根據權值w進行排序的。為什麼要排序?因為排序後我們就能利用二分查詢快速定位到w值最接近的點了。

pixel_ratio = (consult_max_pixel - consult_min_pixel) / (max_pixel - min_pixel)

for i in range(height):

progress_bar(i / height)

for j in range(width):

pixel_light = consult_min_pixel + (gray_image_l_origin[i, j] - min_pixel) * pixel_ratio

gray_image_l[i, j] = pixel_light

prograss_bar是進度條,這裡不需要看,consult_min_pixel和consult_max_pixel是對應的參考影象亮度最小值和最大值,min_pixel和max_pixel是輸入影象亮度的最小值和最大值,這裡比較好理解,就是講輸入影象的亮度值按比例對映到參考影象的範圍內。

for row in range(height):

progress_bar(row / height)

for col in range(width):

pixel = pixel(row, col)

pixel_light = gray_image_l[pixel.x, pixel.y]

# 求視窗內畫素方差;

window_left = max(pixel.x - window_size, 0)

window_right = min(pixel.x + window_size + 1, height)

window_top = max(pixel.y - window_size, 0)

window_bottom = min(pixel.y + window_size + 1, width)

window_slice = gray_image_l[window_left: window_right, window_top: window_bottom]

pixel_std = np.std(window_slice)

weight_pixel = weightpixel(ratio * pixel_light + (1 - ratio) * pixel_std,

0, 0)

# 二分查詢,另外,為了避免列表越界,當找到列表兩邊時需要調整一下;

search_pixel = bisect.bisect(consult_image.get_weight_list(), weight_pixel)

search_pixel = 1 if search_pixel == 0 else search_pixel

search_pixel = len(consult_image.get_weight_list()) - 1 \

if search_pixel == len(consult_image.get_weight_list()) else search_pixel

left_pixel = consult_image.get_weight_list()[search_pixel - 1]

right_pixel = consult_image.get_weight_list()[search_pixel]

nearest_pixel = left_pixel if left_pixel.weight + right_pixel.weight > 2 * weight_pixel.weight else right_pixel

gray_image_a[row, col] = nearest_pixel.a

gray_image_b[row, col] = nearest_pixel.b

ok,**有點長,功能都寫在注釋裡了,應該比較容易看懂。

最後,轉換會rgb影象,儲存:

實驗效果如下:

整個**見下面鏈結,執行方式很簡單,python colorize.py即可,可以在**裡改的路徑,也可以修改一下**,新增命令列引數等;另,**需優化的地方還很多,且注釋不規範,例如函式取名不優雅、占用記憶體的height_array陣列等,都可以去掉,也可以把求權值的功能寫到乙個函式中,等等。

最後再寫一句,最新的影象著色都是以深度學習為主了,效果也會更好一些,見兩個個2023年的深度學習影象著色的效果:

; 

《Reinhard顏色遷移演算法》讀書筆記

reinhard等人根據lab顏色空間中各通道互相不關聯的特點,提出了一組適用於各顏色分量的色彩遷移公式,較好的實現了彩色影象之間的色彩遷移。基本思想就是根據著色影象的統計分析確定乙個線性變換,使得目標影象和源影象在lab空間中具有同樣的均值和方差。將參考影象和目標影象轉換到lab顏色空間下 計算參...

c 實現rsa演算法 RSA演算法實現過程

rsa演算法是實現非對稱加密的一種演算法,其用到很多有關數論的內容,在此我們不多討論。而將目光聚焦於演算法的實現過程。rsa過程 第二步 計算n a b 61 53 3233 第三步 計算 a 1 b 1 60 52 3120 第四步 選擇與3120互質的乙個數e 17,這個e也就是我們的公鑰,需要...

prim演算法的實現過程

為什麼要構建最小生成樹呢?其實原理很簡單。打個比方,現在某乙個鄉鎮有n個村,那麼這n個村肯定是聯通的。現在我們打算在各個村之間搭建網線,實現村村通的工程。那麼有什麼辦法可以實現村村互通,同時又使得最後的總距離最小呢?要達到這個目的,就必須在已有的圖中構建最小生成樹。生成最小生成樹的方法很多,prim...