訂閱
糾錯(cuò)
加入自媒體

一文教你使用OpenCV為照片添加卡通效果

OpenCV 是一個(gè)用于實(shí)時(shí)計(jì)算機(jī)視覺應(yīng)用的 Python 庫。OpenCV 是開源的,在圖像處理、機(jī)器學(xué)習(xí)和深度學(xué)習(xí)方面有著巨大的應(yīng)用。OpenCV 可用于對象檢測、分類、筆跡分析等。

OpenCV 可以與 Numpy 等庫集成,用于各種數(shù)學(xué)計(jì)算。

計(jì)算機(jī)視覺的主要目的是理解圖像。

OpenCV:它是關(guān)于什么的?

使用 OpenCV,我們可以執(zhí)行許多任務(wù),例如-

讀取和寫入圖像

圖像處理

捕獲和保存視頻

特征檢測

OpenCV 代表開源計(jì)算機(jī)視覺庫。它是使用 Python 用于計(jì)算機(jī)視覺的最流行的庫。OpenCV 可供所有人免費(fèi)使用,因此 OpenCV 可用于各種項(xiàng)目和應(yīng)用程序。

為我們的圖像賦予卡通效果

許多應(yīng)用程序和網(wǎng)站都提供了為圖像賦予卡通效果的工具。年輕一代喜歡這個(gè)功能,它在社交媒體上也很受歡迎。在這些應(yīng)用程序的情況下,我們只需上傳我們的圖像,然后就會(huì)返回具有所需效果的圖像。

但是,你有沒有想過,它們是如何工作的?

為此,需要進(jìn)行多次圖像轉(zhuǎn)換。在執(zhí)行此操作時(shí)需要考慮的一些重要事項(xiàng)是邊緣和顏色數(shù)量。

讓我們繼續(xù)看看代碼。

import cv2
import numpy as np
import matplotlib.image as img
from matplotlib import pyplot as plt

我們將需要 OpenCV 和 NumPy。

現(xiàn)在,讓我們閱讀圖像。

#reading the image
img = cv2.imread("person.jpeg")

我們已經(jīng)將圖像作為輸入。

讓我們看看圖像數(shù)據(jù)類型是什么。

#image type
type(img)

輸出:  numpy.ndarray

因此,圖像基本上是一個(gè)多維的 NumPy 數(shù)組。

邊緣遮罩

在卡通效果中,通常非常強(qiáng)調(diào)圖像邊緣的厚度。

我們可以使用**cv2.a(chǎn)daptiveThreshold()**函數(shù)檢測邊緣。

在我們繼續(xù)處理邊緣之前,我們需要將圖像轉(zhuǎn)換為灰度。然后,使用 cv2.medianBlur函數(shù)來降低灰度圖像的噪聲。

讓我們繼續(xù)看看代碼:

#Create Edge 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.a(chǎn)daptiveThreshold(gray_blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, line_size, blur_value)
 return edges

line_size = 7
blur_value = 7

定義了線條大小和模糊值。為了強(qiáng)調(diào)較粗的邊緣,采用較大的線條尺寸。

讓我們得到邊緣。

edges = edge_mask(img, line_size, blur_value)

現(xiàn)在,我們保存圖像。

filename = 'edges.jpg'
# Using cv2.imwrite() method
# Saving the image
cv2.imwrite(filename, edges)

輸出:

我們可以看到檢測到了邊緣。

減少顏色數(shù)量

照片和草圖/卡通之間的主要區(qū)別在于不同顏色的數(shù)量。與高清照片相比,卡通素描的顏色要少得多。

因此,使用了一種名為顏色量化的方法。這將減少照片中的顏色數(shù)量。

K均值聚類算法用于執(zhí)行該過程!発”值根據(jù)我們需要的顏色數(shù)量進(jìn)行調(diào)整。

#colour quantization
#k value determines the number of colours in the image
total_color = 8
k=total_color

在這種情況下,k 的值取為 8。

# Transform the image
data = np.float32(img).reshape((-1, 3))

接下來,圖像被轉(zhuǎn)換。

# Determine criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 0.001)

現(xiàn)在,我們實(shí)施 K 均值。

# 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)

讓我們保存圖像。

filename = 'colour.jpg'
# Using cv2.imwrite() method
# Saving the image
cv2.imwrite(filename, result)

輸出:

好的,現(xiàn)在我們看到了一些效果。

顏色量化完成后,我們現(xiàn)在可以減少圖像中的噪聲。雙邊濾波器可用于此任務(wù)。

生成的圖像會(huì)稍微模糊,圖像清晰度會(huì)降低。

blurred = cv2.bilateralFilter(result, d=10, sigmaColor=250,sigmaSpace=250)

讓我們保存圖像,看看它的外觀。

#saving the image
filename = 'blurred.jpg'
# Using cv2.imwrite() method
# Saving the image
cv2.imwrite(filename, blurred)

輸出:

完成后,現(xiàn)在我們做最后的卡通效果。

最終圖像

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

現(xiàn)在,我們保存圖像。

filename = 'cartoon.jpg'
# Using cv2.imwrite() method
# Saving the image
cv2.imwrite(filename, cartoon)

讓我們看看圖像是什么樣子的。

輸出做得很好。圖像被賦予了有趣的效果。

OpenCV 可以進(jìn)行有趣的圖像轉(zhuǎn)換。

現(xiàn)在讓我們嘗試其他東西,這一次,我們也將使用輪廓。

應(yīng)用帶有輪廓的卡通效果

讓我們首先正確定義函數(shù)。

首先是顏色量化函數(shù)。

#Colour Quantization
def ColourQuantization(image, K=9):
   Z = image.reshape((-1, 3))
   Z = np.float32(Z)
   criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001)
   compactness, label, center = cv2.kmeans(Z, K, None, criteria, 1, cv2.KMEANS_RANDOM_CENTERS)
   center = np.uint8(center)
   res = center[label.flatten()]
   res2 = res.reshape((image.shape))
   return res2

這里,對于 K-Means,K 的值取為 9。

現(xiàn)在讓我們定義輪廓的函數(shù)。

#to get countours
def Countours(image):
   contoured_image = image
   gray = cv2.cvtColor(contoured_image, cv2.COLOR_BGR2GRAY)
   edged = cv2.Canny(gray, 200, 200)
   contours, hierarchy = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2:]
   cv2.drawContours(contoured_image, contours, contourIdx=-1, color=6, thickness=1)
   return contoured_image

在這個(gè)函數(shù)中,圖像首先被轉(zhuǎn)換為灰度,然后檢測邊緣。最后,還制作了輪廓。

現(xiàn)在,讓我們使用該函數(shù)。

使用了下圖。

image = cv2.imread("person1.jpeg")
coloured = ColourQuantization(image)
contoured = Countours(coloured)
final_image = contoured

在此之后,圖像被保存。

filename = 'cartoon_final.jpg'
# Using cv2.imwrite() method
# Saving the image
cv2.imwrite(filename, final_image)

輸出:

在這種情況下,輸出也很有趣。

通過改變各種參數(shù),可以修改卡通效果。

說到用途,目前這類處理方法主要用于社交媒體和藝術(shù)目的。人們可以對他們的圖像進(jìn)行有趣的編輯,并將它們發(fā)布到社交媒體上。

聲明: 本文由入駐維科號的作者撰寫,觀點(diǎn)僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請聯(lián)系舉報(bào)。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個(gè)字

您提交的評論過于頻繁,請輸入驗(yàn)證碼繼續(xù)

  • 看不清,點(diǎn)擊換一張  刷新

暫無評論

暫無評論

    人工智能 獵頭職位 更多
    掃碼關(guān)注公眾號
    OFweek人工智能網(wǎng)
    獲取更多精彩內(nèi)容
    文章糾錯(cuò)
    x
    *文字標(biāo)題:
    *糾錯(cuò)內(nèi)容:
    聯(lián)系郵箱:
    *驗(yàn) 證 碼:

    粵公網(wǎng)安備 44030502002758號