如何破解《楚門的世界》馬賽克海報(bào)?附完整教程! | 您所在的位置:網(wǎng)站首頁 › 屬虎人2022年遇到貴人 › 如何破解《楚門的世界》馬賽克海報(bào)?附完整教程! |
點(diǎn)擊上方“藍(lán)字”關(guān)注我們 看了電影《楚門的世界》的海報(bào),是不是覺得特別炫酷?將各個(gè)圖片拼在一起,最后呈現(xiàn)為主角,在那個(gè)年代,這種海報(bào)制作堪稱一絕! 別羨慕,你也可以完成! 在開始之前,你有沒有想過上面的圖片是怎么實(shí)現(xiàn)的?難道這是用 ps 一張張拼起來的?光靠人工把近千張圖片按照色域一一排列,這個(gè)可能性幾乎為0。 所以,馬賽克圖片生成器就產(chǎn)生了。那么今天,我們就用 Python 做一個(gè)馬賽克圖片生成器。只需要 200 行 Python?代碼,就可以將任意圖片轉(zhuǎn)換成馬賽克效果。既可以用來記錄校園生活、游戲生涯,又可以用作禮物。 01 項(xiàng)目思路 項(xiàng)目大概分為 3 個(gè)步驟: 計(jì)算素材庫中每張圖片的平均色 把目標(biāo)圖片切分成平均的色塊,與素材庫圖片進(jìn)行替換 全部替換完成后,再與原始圖像進(jìn)行融合 02 計(jì)算圖像平均值 一張圖像,是通過許多的像素組成的。為了生成馬賽克圖片,我們的想法是,將原有圖像的每一個(gè)小部分,使用顏色與這一小部分相似的圖像進(jìn)行替換,從而生成馬賽克風(fēng)格的圖像。 如何計(jì)算圖片的顏色相似度?這里要引用 RGB 和 HSV 的概念。 RGB 色彩空間是,由三個(gè)通道表示一幅圖像。三個(gè)通道分別為紅色 (R),綠色 (G) 和藍(lán)色(B),通過這三種顏色的不同組合,可以形成幾乎所有的其他顏色。 但是,在自然環(huán)境下,圖像容易受自然光照、遮擋等情況的影響,也就是人眼觀察圖片會(huì)對(duì)圖片的亮度比較敏感。而 RGB 色彩空間的三個(gè)分量都與亮度密切相關(guān),只要亮度改變,RGB 顏色的三個(gè)分量都會(huì)改變。 同時(shí),由于人眼對(duì)于這 RGB 這三種顏色的敏感程度是不一樣的。在單色中,人眼對(duì)紅色最不敏感,藍(lán)色最敏感,所以 RGB 色彩空間是一種均勻性較差的色彩空間。 由于 RGB 色彩空間不能方便的比較顏色之間的相似度,于是我們要使用 HSV 色彩空間。HSV 色彩空間也是由三個(gè)分量組成的,分別是: Hue(色調(diào)) Saturation (飽和度) Value (明度) 我們會(huì)常用下圖的圓柱體來表示 HSV 色彩空間,其中: H 用極坐標(biāo)的極角表示; S 用極坐標(biāo)的軸的長(zhǎng)度表示; V 用圓柱的高度表示。 計(jì)算圖片?HSV?值的代碼如下: class mosaic(object): ? ?"""定義計(jì)算圖片的平均hsv值 ? ?""" ? ?def __init__(self, IN_DIR: str, OUT_DIR: str, SLICE_SIZE: int, REPATE: int, ? ? ? ? ? ? ? ? OUT_SIZE: int) -> None: ? ? ? ?self.IN_DIR = IN_DIR ?# 原始的圖像素材所在文件夾 ? ? ? ?self.OUT_DIR = OUT_DIR ?# 輸出素材的文件夾, 這些都是計(jì)算過hsv和經(jīng)過resize之后的圖像 ? ? ? ?self.SLICE_SIZE = SLICE_SIZE ?# 圖像放縮后的大小 ? ? ? ?self.REPATE = REPATE ?# 同一張圖片可以重復(fù)使用的次數(shù) ? ? ? ?self.OUT_SIZE = OUT_SIZE ?# 最終圖片輸出的大小 ? ?def resize_pic(self, in_name: str, size: int) -> Image: ? ? ? ?"""轉(zhuǎn)換圖像大小 ? ? ? ?""" ? ? ? ?img = Image.open(in_name) ? ? ? ?img = ImageOps.fit(img, (size, size), Image.ANTIALIAS) ? ? ? ?return img ? ?def get_avg_color(self, img: Image) -> Tuple[float, float, float]: ? ? ? ?"""計(jì)算圖像的平均hsv ? ? ? ?""" ? ? ? ?width, height = img.size ? ? ? ?pixels = img.load() ? ? ? ?if type(pixels) is not int: ? ? ? ? ? ?data = [] ?# 存儲(chǔ)圖像像素的值 ? ? ? ? ? ?for x in range(width): ? ? ? ? ? ? ? ?for y in range(height): ? ? ? ? ? ? ? ? ? ?cpixel = pixels[x, y] ?# 獲得每一個(gè)像素的值 ? ? ? ? ? ? ? ? ? ?data.append(cpixel) ? ? ? ? ? ?h = 0 ? ? ? ? ? ?s = 0 ? ? ? ? ? ?v = 0 ? ? ? ? ? ?count = 0 ? ? ? ? ? ?for x in range(len(data)): ? ? ? ? ? ? ? ?r = data[x][0] ? ? ? ? ? ? ? ?g = data[x][1] ? ? ? ? ? ? ? ?b = data[x][2] ?# 得到一個(gè)點(diǎn)的GRB三色 ? ? ? ? ? ? ? ?count += 1 ? ? ? ? ? ? ? ?hsv = rgb_to_hsv(r / 255.0, g / 255.0, b / 255.0) ? ? ? ? ? ? ? ?h += hsv[0] ? ? ? ? ? ? ? ?s += hsv[1] ? ? ? ? ? ? ? ?v += hsv[2] ? ? ? ? ? ?hAvg = round(h / count, 3) ? ? ? ? ? ?sAvg = round(s / count, 3) ? ? ? ? ? ?vAvg = round(v / count, 3) ? ? ? ? ? ?if count > 0: ?# 像素點(diǎn)的個(gè)數(shù)大于0 ? ? ? ? ? ? ? ?return (hAvg, sAvg, vAvg) ? ? ? ? ? ?else: ? ? ? ? ? ? ? ?raise IOError("讀取圖片數(shù)據(jù)失敗") ? ? ? ?else: ? ? ? ? ? ?raise IOError("PIL 讀取圖片數(shù)據(jù)失敗")以上內(nèi)容出自藍(lán)橋云課免費(fèi)課程—— Python 制作馬賽克拼合圖像,但由于篇幅有限,無法一一呈現(xiàn)。如果你有任何代碼問題,歡迎大家隨時(shí)通過文末方式和我交流。 戳戳“閱讀原文”直達(dá)課程頁面! |
CopyRight 2018-2019 實(shí)驗(yàn)室設(shè)備網(wǎng) 版權(quán)所有 |