使用 Python-OpenCV 將照片變成卡通照片
來源 | 深度學習與計算機視覺
作者 | 磐懟懟
正如你可能知道的,素描或創建一個卡通並不總是需要手動完成。如今,許多應用程序可以把你的照片變成卡通照片。但是如果我告訴你,你可以用幾行代碼創造屬於自己的效果呢?
有一個名爲 OpenCV 的庫,它爲計算機視覺應用程序提供了一個公共基礎設施,並優化了機器學習算法。它可以用來識別物體,檢測和產生高分辨率的圖像。
本文,將向你展示如何利用 OpenCV 爲 Python 中的圖像提供卡通效果。使用 google colab 來編寫和運行代碼。你可以在這裏訪問 Google Colab 中的完整代碼
- https://colab.research.google.com/drive/1lV5oJ_hI8PsSV1WDVWWfL18-tMm4vnxe?usp=sharing
要創造卡通效果,我們需要注意兩件事:邊緣和調色板。這就是照片和卡通的區別所在。爲了調整這兩個主要部分,我們將經歷四個主要步驟:
-
加載圖像
-
創建邊緣蒙版
-
減少調色板
-
結合邊緣蒙版和彩色圖像
在開始主要步驟之前,不要忘記導入 notebook 中所需的庫,尤其是 cv2 和 NumPy。
import cv2
import numpy as np
# required if you use Google Colab
from google.colab.patches import cv2_imshow
from google.colab import files
1. 加載圖像
第一個主要步驟是加載圖像。定義 read_file 函數,其中包括 cv2_imshow 以在 Google Colab 中加載所選圖像。
def read_file(filename):
img = cv2.imread(filename)
cv2_imshow(img)
return img
調用創建的函數來加載圖像。
uploaded = files.upload()
filename = next(iter(uploaded))
img = read_file(filename)
我選擇了下面的圖片來轉化成卡通圖片。
2. 創建邊緣蒙版
通常,卡通效果強調圖像中邊緣的厚度。我們可以使用 cv2.adaptiveThreshold() 函數檢測圖像中的邊緣。
總之,我們可以將 egde_mask 函數定義爲:
def edge_mask(img, line_size, blur_value):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_blur = cv2.medianBlur(gray, blur_value)
edges = cv2.adaptiveThreshold(gray_blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, line_size, blur_value)
return edges
在該函數中,我們將圖像轉換爲灰度圖像。然後,利用 cv2.medianBlur 對模糊灰度圖像進行去噪處理。
模糊值越大,圖像中出現的黑色噪聲就越少。然後,應用自適應閾值函數,定義邊緣的線條尺寸。較大的線條尺寸意味着圖像中強調的較厚邊緣。
定義函數後,調用它並查看結果。
line_size = 7
blur_value = 7
edges = edge_mask(img, line_size, blur_value)
cv2_imshow(edges)
3. 減少調色板
照片和圖畫之間的主要區別——就顏色而言——是每一張照片中不同顏色的數量。
圖畫的顏色比照片的顏色少。因此,我們使用顏色量化來減少照片中的顏色數目。
色彩量化
爲了進行顏色量化,我們採用 OpenCV 庫提供的 K-Means 聚類算法。
爲了在接下來的步驟中更容易實現,我們可以如下定義 color_quantization 函數。
def color_quantization(img, k):
# Transform the image
data = np.float32(img).reshape((-1, 3))
# Determine criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 0.001)
# Implementing K-Means
ret, label, center = cv2.kmeans(data, k, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)
center = np.uint8(center)
result = center[label.flatten()]
result = result.reshape(img.shape)
return result
我們可以調整 k 值來確定要應用於圖像的顏色數。
total_color = 9
img = color_quantization(img, total_color)
在本例中,我使用 9 作爲圖像的 k 值。結果如下所示。
雙邊濾波器
在進行顏色量化之後,我們可以使用雙邊濾波器來降低圖像中的噪聲。它會給圖像帶來一點模糊和銳度降低的效果。
blurred = cv2.bilateralFilter(img, d=7,
sigmaColor=200,sigmaSpace=200)
有三個參數可根據你的首選項進行調整:
-
d:每個像素鄰域的直徑
-
sigmaColor:參數值越大,表示半等色區域越大。
-
sigmaSpace:參數的值越大,意味着更遠的像素將相互影響,只要它們的顏色足夠接近。
4. 結合邊緣蒙版和彩色圖像
最後一步是將我們之前創建的邊緣蒙版與彩色處理圖像相結合。爲此,請使用 cv2.bitwise_and 函數。
cartoon = cv2.bitwise_and(blurred, blurred, mask=edges)
我們可以在下面看到原始照片的 “卡通版”。
現在你可以開始來創建你自己的卡通效果。除了在我們上面使用的參數中調整值之外,你還可以從 OpenCV 添加另一個函數來爲你的照片提供特殊效果。代碼庫裏還有很多東西我們可以探索。很高興嘗試!
參考文獻:
-
https://www.programcreek.com/python/example/89394/cv2.kmeans
-
http://datahacker.rs/002-opencv-projects-how-to-cartoonize-an-image-with-opencv-in-python/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/fhyCX6RJgfz8mLI-fYOpjg