使用 Python-OpenCV 將照片變成卡通照片


來源 | 深度學習與計算機視覺

作者 | 磐懟懟

正如你可能知道的,素描或創建一個卡通並不總是需要手動完成。如今,許多應用程序可以把你的照片變成卡通照片。但是如果我告訴你,你可以用幾行代碼創造屬於自己的效果呢?

有一個名爲 OpenCV 的庫,它爲計算機視覺應用程序提供了一個公共基礎設施,並優化了機器學習算法。它可以用來識別物體,檢測和產生高分辨率的圖像。

本文,將向你展示如何利用 OpenCV 爲 Python 中的圖像提供卡通效果。使用 google colab 來編寫和運行代碼。你可以在這裏訪問 Google Colab 中的完整代碼

要創造卡通效果,我們需要注意兩件事:邊緣和調色板。這就是照片和卡通的區別所在。爲了調整這兩個主要部分,我們將經歷四個主要步驟:

  1. 加載圖像

  2. 創建邊緣蒙版

  3. 減少調色板

  4. 結合邊緣蒙版和彩色圖像

在開始主要步驟之前,不要忘記導入 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)

有三個參數可根據你的首選項進行調整:

4. 結合邊緣蒙版和彩色圖像

最後一步是將我們之前創建的邊緣蒙版與彩色處理圖像相結合。爲此,請使用 cv2.bitwise_and 函數。

cartoon = cv2.bitwise_and(blurred, blurred, mask=edges)

我們可以在下面看到原始照片的 “卡通版”。

現在你可以開始來創建你自己的卡通效果。除了在我們上面使用的參數中調整值之外,你還可以從 OpenCV 添加另一個函數來爲你的照片提供特殊效果。代碼庫裏還有很多東西我們可以探索。很高興嘗試!

參考文獻

  1. https://www.programcreek.com/python/example/89394/cv2.kmeans

  2. 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