Python打造圖片馬賽克工具:photomosaic
使用機器學習 & 相似性搜尋從你的家庭照片中建立有趣的圖片馬賽克、GIF和壁畫。
如果你想使用一個很酷的網路介面,那就上傳你的照片,我會打印出來郵寄給你,快來試試我的服務:http://photofun.strikingly.com。(之後我們會刪除所有照片。)
因為我很容易沉迷於某些東西,所以你也可以(雖然這與photomosaics無關,但卻可以讓你的相簿更酷)將面部蒙太奇特效貼到一個特定的人的臉上:
這利用了一個嵌入網路,一個有優勢的簡單的線性分類器,和一個扭曲矩陣將每個影象的眼睛對齊,並對其進行合適的比例調整。你只需要建立一個資料夾,裡面有幾個例子,這樣它就可以知道應該包括哪張臉部照片。
它是如何執行的?
我們正在做一項非常古老技術的數字版本-建立馬賽克:
除了不使用實體瓷磚圖片,你可以使用你的照片集,表情符號,或任何你想要的數字圖片集。
找一張目標照片,比如說一張全家福。你可以使用以其他影象作為圖案塊的“codebook”演算法重新建立目標影象作為馬賽克。如果你能夠智慧地搜尋並選擇圖案塊集中最好的“codebook”演算法圖片,你就可以任意地對目標圖片進行更好的重建。
本專案將目標影象分割成圖案塊(使用scale引數控制塊大小),對於每個圖案塊補丁,使用L2相似性度量法(使用Facebook的faiss庫進行超快查詢) 來找到最接近的codebook演算法圖案塊來替換它。
因為這個查詢非常快,你甚至可以對視訊中的每一幀都這樣做並建立視訊馬賽克(見video.py)。如果你感興趣的話,你還可以使用performance.py執行一系列有趣的效能指標。
安裝
確保你已經安裝了:
- Docker
- XQuartz (版本: 2.7.5或更高) 如果你想執行interactive.py OpenCV GUI瀏覽器的話就安裝,否則就不需要安裝它。 .
對於 XQuartz庫,開啟遠端設定,然後退出並重啟XQuartz (!).
我只在Mac OS X上測試過,但是由於它是Docker化的,所以應該可以在Docker執行的任何地方執行!
接下來,構建Docker映象並執行一個容器:
如果你想通過SSH連線到Docker容器上,執行上述命令後執行以下命令:
sh enter.sh
最後,也是最重要的,收集一些你想要用來建立影象(作為馬賽克圖案塊)或建立馬賽克(把你的照片/視訊變成馬賽克)的照片和視訊。我把過去幾年的iPhone照片/視訊都放在一個資料夾裡,你可以在下面看到一些很酷的效果。
Photomosaic指令碼
請注意,所有這些指令碼的預設設定都是使用快取的,這意味著一旦你以一定的比例(即:圖案塊大小)索引了一個特定資料夾中的照片之後,就不需要再做一次。
如果你從資料夾中新增或刪除一個檔案,photomosaic會智慧地進行重新索引。快取索引的pickle檔案預設儲存在快取資料夾中。
1)使用影象建立馬賽克
使用一組其他影象重新構建一個影象,縮小影象尺寸並將其作為圖案塊。
引數:
- --savepath: 儲存位置. %s是預設檔名 ,%d 是比例。
- --target: 使用其他圖片進行重構的目標圖片
- --codebook-dir: 用來使用codebook演算法建立圖案塊的圖片
- --scale: 將要建立的圖案塊多大/小. 方向比例最大值
- --height-aspect: 高度方向
- --width-aspect:寬度方向
- --vectorization-factor: 如果查詢之前縮小特徵向量 (一般不需要調整此項)
2)建立馬賽克視訊
對視訊的每一幀進行同樣的操作。
例子(Tipper 音樂會):
儲存路徑輸出僅使用*.mp4,目前只支援mp4。
引數:
- --target:用其他圖案塊影象重新構建的目標視訊
- --codebook-dir: 用來使用codebook演算法建立圖案塊的圖片
- --scale: 建立的圖案塊多大/小. 方向比例最大值.
- --height-aspect: 高度方向
- --width-aspect: 寬度方向
- --savepath: 視訊檔案輸出目錄 (僅以.MP4副檔名測試過)
ffmpeg用於音訊拼接,因為OpenCV並不能真正處理這些。
你也可以在這裡調整高寬比,但這些和其他的都是可選引數。
3) 互動式探究馬賽克比例
不確定哪個比例看起來最好?想嘗試一些不同的設定嗎?執行以下命令。
然後只要按下s鍵,你就可以將選擇的比例儲存到磁碟上!
或者,按ESC退出視窗而不儲存。
引數:
- --target: 使用其他圖案塊影象建立的目標影象
- --codebook-dir: 用於建立圖案塊的影象(codebook)
- --min-scale:按照此比例開始(整數)
- --max-scale:允許使用者增加比例到此值(整數)
- --savepath:儲存位置。%s 是初始檔名,%d 是比例
你也可以在這裡調整高寬比,但這些和其他的都是可選引數。
4)從帶有各種不同圖案塊比例的一連串馬賽克建立GIF
這將建立一系列各種比例的馬賽克,然後將它們組合在一起,形成每秒具有指定幀的GIF。你可以用—ascending引數來調整順序。
如果你選擇了一個很大的數值範圍,預計要等待一個半小時左右,這取決於你的機器。
注意,第一次在容器上執行它時,你可能會看到一個“a Imageio: "ffmpeg-linux64-v3.3.1" was not found on your computer; downloading it now.”的訊息,這很正常。
優化GIF檔案大小
如果你簡單地執行上述操作,你可能會得到一個200 MB的GIF檔案,這很荒謬。最簡單的補救方法是使用像gifsicle這樣的工具。
以下是我的建議:
$ brew install gifsicle$ gifsicle -O3 --resize-height 400 --colors 256 < your/gigantic.gif > totally/reasonable/sized.gif
例如,我使用該命令將一個130 MB的GIF壓縮為2MB。EZgif是一個非常好的線上工具,可以以不同的權重壓縮gif檔案,但它們只能支援100MB以內的gif檔案。
其它設定
下面是一些其他設定,允許你調整視覺化輸出。
1) 隨機性(--randomness)
如果你想給你的圖片馬賽克帶來一點混亂,使用隨機性引數。
它是[0,1)範圍內的一個浮點數,這是給定的圖案塊被填充的概率,不是使用codebook中最接近的塊,而是完全隨機的。
例(以0.05的隨機性):
2) 視訊馬賽克穩定性(--stabilization-threshold)
視訊馬賽克只是圖片馬賽克功能的重複應用。因此,幀與幀之間的微小變化可能會導致視訊中相同的物件使用不同的圖案塊顯示。這並不可怕,但它影響視覺穩定性,因為它總是在變化。
--stabilization-threshold 是一個浮點數,表示該塊的前一段距離的一部分。我們只有在以下情況下才會更換那個位置的圖案塊:
`current closest tile"s distance` < `--stabilization-threshold` * `last frame"s distance`
否則,我們只需要保持圖案塊與該幀一樣。這是一個粗略的穩定性探索法,在未來我會進行改進。
3) 不透明度(--opacity)
一些圖片馬賽克有點欺騙性,它只是在原始影象上按指定比例疊加帶有馬賽克圖案塊。這是一個很流行的技術,我決定引入它。只需使用--opacity 標誌即可:
4) 最佳-K (--best-k)
你可能會注意到你的許多圖片賽克將有大塊區域的顏色相似,所以一個單一的影象將被平鋪在你的大部分影象。如果你想加入一點(合理的)隨機性,而不是使用(--randomness)功能,你可以使用--best-k引數。
在每個圖案塊上,使用--best-k引數,,k個優先匹配項將被隨機選擇,按距離大致進行反向加權(因此“更接近”的影象最有可能)。
這是與上面相同的影象,但使用了 --best-k 5引數:
面部蒙太奇效果
我真的很想做面部蒙太奇,儘管它們和圖片馬馬賽克沒有任何關係,本部分就是!
簡單來說,就是使用一個人的不同照片來建立GIF,並將全部照片對齊到此人的臉部。
工作原理:.
1.將只包含你想加入蒙太奇效果的臉部影象的照片(例如你自己)放在一個資料夾(--target-face-dir)。自拍照片是最好的選擇。
2.將包含其他臉部影象的照片放在一個資料夾(--other-face-dir),越多越好。不要加入你的臉部照片。如果你真的很缺少其他人 的照片/有很多合影,那就把自己P掉。
3.將你想要用來繪製蒙太奇效果的照片目錄放在一起(--photos-dir)。
作為一個開始,我已經在media/faces/other_faces (不太可能是你的臉部照片)中加入了450張臉部圖片的學術資料集(Caltech Faces Dataset)。如果你出於學術原因使用的話,請務必引用它們和dlib庫。
如果你想要更好的準確度,我會試著在--target-face-dir 和 --other-face-dir 目錄新增至少100張照片。我添加了這一點,使用face_montage.py執行的 結果是大約每300張照片有1個錯誤正片(在執行create_gif_from_photos_folder.py步驟之前很容易將其刪除)。
你可以從這個地方找到更多隨機的臉部照片。
總之,以下是更詳細的描述來幫助你執行人臉嵌入,訓練線性分類器,對人臉進行對齊:
然後,要將它們實際編譯成GIF,要在上面的描述中使用--savedir引數,然後執行:
將這兩個步驟分開很好,因為你可能想要從第一步建立的資料夾中刪除錯誤正片和不好看的圖片,不然會搞亂生成的GIF中你想要的每秒多少幀。我在嵌入過程中實現了快取,但是執行一組完整的照片(僅我有耐心執行的照片庫部分就有4000多張照片)仍然需要一些時間。
使用 ffprobe / ffmpeg
本專案中的一些例程使用了來自視訊/音訊檔案的引數。我經常通過轉到一個單獨的程序來直接呼叫命令列程式,雖然有點麻煩,但是也可以完成任務。
FFProbe是一個很好的工具,命令列介面非常強大。推薦你閱讀此指南來掌握它。
類似地,ffmpeg使音訊/視訊流的拼接和重組變得容易。以下是一些具體的ffmpeg資源:
- ffmpeg編碼課程
- ffmpeg教程
- 數字視訊簡介
圖片魔法
轉換工具用來製作GIF也很不錯:
$ cd your/cool/folder/with/jpg/images$ convert -delay 5 -layers optimize *.jpg output.gif
然後,你可能想使用gifsicle技巧來壓縮/調整GIF的大小,使其變成合適大小。
單元測試
有一個小型的(但令人尷尬的是不完整的)測試套件,你可以使用它進行測試: