https://github.com/obskyr/colorgram.py
https://github.com/darosh/colorgram-js
這兩個是同個演算法,一個是python一個是js語言。
如果大佬不方便看github,我貼一下python寫的主要的幾個函式吧。或者我下面有簡單寫了一下我自己的理解。
def sample(image):
top_two_bits = 0b11000000
sides = 1 << 2 # Left by the number of bits used. 左移
cubes = sides ** 7 #cubes = 4^7
samples = array.array(ARRAY_DATATYPE, (0 for _ in range(cubes)))
width, height = image.size
pixels = image.load()
for y in range(height):
for x in range(width):
# Pack the top two bits of all 6 values into 12 bits.
r, g, b = pixels[x, y][:3]
h, s, l = hsl(r, g, b) #hsl函式是把rgb轉化成hsl, 函式內容我就不貼了
# Standard constants for converting RGB to relative luminance.
Y = int(r * 0.2126 + g * 0.7152 + b * 0.0722)
# Everything's shifted into place from the top two
# bits' original position - that is, bits 7-8.
packed = (Y & top_two_bits)
packed |= (h & top_two_bits) >> 2
packed |= (l & top_two_bits) >> 4
samples[packed] += r
samples[packed + 1] += g
samples[packed + 2] += b
samples[packed + 3] += 1
return samples
def pick_used(samples): #提取圖中使用的顏色
used = []
for i in range(0, len(samples), 4):
count = samples[i + 3]
if count:
used.append((count, i))
return used
def get_colors(samples, used, number_of_colors): #提取影像主色調,number_of_colors個顏色
pixels = 0
colors = []
number_of_colors = min(number_of_colors, len(used))
for count, index in used[:number_of_colors]:
pixels += count
color = Color(
samples[index] // count, #rgb均值
samples[index + 1] // count,
samples[index + 2] // count,
count
)
colors.append(color)
for color in colors:
color.proportion /= pixels
return colors
這個代碼我理解的話就是,用Y(灰度)h(色相)s(飽和度)分別取二進制前兩位,組成YYhhss的八位二進制,后面再加上兩位(為了存盤rgb和count,也就是四位為一組)即YYhhssxx,這個作為索引,依次存盤累加像素點的r,g,b,count頻次,最后把累加得到的r,g,b再除以頻次得到均值。不知道我的有沒有表達清楚。
我個人肉眼感覺效果可以,只是飽和度好像整體偏普通(?)但沒大的影響。這是我簡單拿了張風景圖跑的結果,只提取了6鐘(理論好像可以提取256種?)

搜到的資料很多都是k-means啊,各種聚類啊,這個演算法也太簡潔了,我不是很理解的有兩點
1. 為什么要用Yhs去定位 (我試過hsl,rgb等等等組合效果都很差)
2. 為什么可以簡單粗暴地把rgb累加然后取均值
請問有大佬指導一下嗎!或者請問有相關的文獻?關鍵詞?嗎,我可以自己去看!我實在搜不到資料..........
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/50113.html
標籤:圖形處理/算法
上一篇:業余編程愛好者向專家求援
