一、說明
在圖像處理領域,將圖像卡通化是一種新趨勢。人們使用不同的應用程序將他們的圖像轉換為卡通圖像。如今,玩弄圖像是許多人的愛好。人們通常會點擊圖片并添加濾鏡或使用不同的東西自定義圖像并將其發布到社交媒體上。但我們是程序員,我們做的不是普通人做的事。我們對將簡單的 RGB 圖像轉換為卡通圖像的過程更感興趣。在這個圖像處理部分中,我們將使用 OpenCV-Python 將圖像卡通化。
二、圖像到卡通的轉換
好吧,將圖像轉換為卡通更多的是關于圖像邊緣的檢測。如果你能很好地檢測圖像的邊緣,那么卡通效果將對該圖像更加有效。有許多算法可用于此,因此有多種方法可以做到這一點。我們將使用 OpenCV-Python 中的 BilateralFilter() 函數。
我通常在 Google Colab 中編寫和運行代碼。您可以在此處訪問 Google Colab 中的完整代碼。在這個項目中,我們將經歷以下主要步驟:
導入所需的庫
加載圖像
初始化要使用的參數
使用高斯金字塔的下采樣來減小圖像尺寸
迭代應用雙邊濾波器
使用上采樣將圖像放大到原始大小
使用中值濾波器模糊圖像
檢測并增強邊緣
將灰度邊緣圖像轉換回 RGB 彩色圖像
顯示圖像
我們必須完成這九個步驟才能獲得所需的輸出。那么,讓我們開始吧。
三、代碼實現
步驟1:庫導入
import cv2
import numpy as np
import matplotlib.pylab as plt
from google.colab.patches import cv2_imshow
from google.colab import files
第2步:圖像讀入
def read_file(filename):image = cv2.imread(filename)cv2_imshow(image)return image
uploaded = files.upload()
filename = next(iter(uploaded))
image = read_file(filename)
如果您正在使用 Google Colab,那么您可以寫下上述代碼。但如果您使用的是Jupyter 筆記本,那么只需添加要使用的圖像的路徑即可。兩者是同一件事。
步驟3:雙邊濾波
num_down = 2
num_bilateral = 7
w, h, _ = image.shape
初始化我們將要使用的參數。num_down 表示下采樣步驟的數量。num_bilateral 表示雙邊濾波步驟的數量。
步驟4:金字塔處理
img_color = np.copy(image)
for _ in range(num_down): img_color = cv2.pyrDown(img_color)
這里我們縮小了圖片的尺寸。為了縮小尺寸,我們使用了高斯金字塔的下采樣操作。我們縮小圖片的尺寸是為了使后續操作更快。
步驟5:雙邊
for _ in range(num_bilateral):
img_color = cv2.bilateralFilter(img_color, d=9, sigmaColor=0.1, sigmaSpace=0.01)
這里sigmaColor表示顏色中的濾波器 sigma,sigmaSpace表示坐標空間。我們在這里迭代地應用具有較小直徑值的雙邊濾波器。參數d表示每個像素鄰域的直徑。
步驟6:
for _ in range(num_down):img_color = cv2.pyrUp(img_color)
為了將圖像放大到原始尺寸,我們在這里使用上采樣。
步驟7:
img_gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
img_blur = cv2.medianBlur(img_gray, 7)
我們將步驟 6 中的輸出圖像轉換為灰度,并使用稱為中值過濾器對圖像進行模糊處理。
步驟8:
img_edge = cv2.adaptiveThreshold((255*img_blur).astype(np.uint8),\
255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,\
blockSize=9,C=2)
正如我們上面所討論的,對圖像進行卡通化更多的是檢測圖像的邊緣。因此,在這一步中,我們將檢測和增強所用圖像的邊緣。
步驟9:
img_edge = cv2.cvtColor(img_edge,cv2.COLOR_GRAY2RGB)
img_cartoon = cv2.bitwise_and(img_color,img_edge)
將灰度圖像轉換回 RGB 圖像,并與 RGB 圖像進行按位與運算以獲得最終輸出的卡通圖像。
步驟10:
fig = plt.figure(figsize=(20,10))
fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)
plt.subplot(121)
plt.imshow(image)
plt.axis('off')
plt.title('原始圖像??', size=20)
plt.subplot(122)
plt.imshow(img_cartoon)
plt.axis('off')
plt.title('卡通化圖像', size=20)
plt.顯示()
最后,顯示輸出。
四、卡通圖像代碼背后的邏輯
在項目中,首先,我們必須去除圖像的弱邊緣,然后將圖像轉換為平面紋理,最后增強圖像的突出邊緣。為此,我們使用了 OpenCV-Python 中的bilateralFilter()、medianBlur()、adaptiveThreshold() 和 bitwise_and() 函數。
為了保持邊緣清晰、紋理光滑,我們使用了 OpenCV-Python 中的 BilateralFilter() 函數。更改 sigmaColor 和 sigmaSpace 的值,并查看圖像輸出的變化。
此外,對圖像進行下采樣以創建圖像金字塔。接下來,我們使用雙邊濾波器去除不重要的細節,然后使用后續的上采樣將圖像調整為原始大小。最后,為了使紋理平坦化,應用了中值模糊,然后用自適應閾值獲得的二值圖像掩蓋原始圖像,成功執行上述代碼后,您將看到輸出圖像。我嘗試使用小羅伯特·唐尼的圖像,得到了這個輸出圖像。