OpenCV利用高斯模糊實(shí)現(xiàn)簡單的磨皮美顏效果
1.高斯模糊
1.什么是高斯模糊
前面我們就知道了均值模糊和中值模糊,現(xiàn)在我們開始了解高斯模糊。
首先高斯指的是高斯函數(shù),這個我想大家應(yīng)該都知道,是一種非常常見的概率分布函數(shù)。大概就長這樣吧。
通過均值模糊類比,我們可以大膽的猜出來高斯模糊的含義:
每一次需要處理的像素矩陣中不同地方的像素的值在最后的賦值像素的占比是不一樣的。這個占比是按照高斯函數(shù)所分布的。
也就是說,越是遠(yuǎn)離中心像素的像素所占比重就更少,而中心像素值在賦值像素中的比重是最重的。
或者說,我們知道之前均值模糊所乘以的矩陣是
而高斯模糊中所乘的3*3矩陣可以是這樣的
可視化后就是這樣的
雖然我們可以從數(shù)學(xué)上得知高斯模糊和均值模糊的區(qū)別,但是在效果上我個人覺得高斯模糊可能能比起均值模糊能更好的保留邊緣信息(只是個人看法)
最后把高斯模糊的計算公式提供給數(shù)學(xué)大佬
2.opencv提供的API
GaussianBlur(Mat src, Mat dst, Size(11, 11), sigmax, sigmay);
其中Size(x, y), x, y 必須是正數(shù)而且是奇數(shù)
參數(shù)SigmaX表示高斯方程中X方向的標(biāo)準(zhǔn)方差
參數(shù)SigmaY表示高斯方程中X方向的標(biāo)準(zhǔn)方差
在高斯分布中,方差可以理解為這個高斯分布的平緩程度,也就是說中間值所占比重的大小,方差越小,中間值所占比重越大,此時模糊的效果會相對更低一點(diǎn)(在同一個size下)
可視化一下你會乘的矩陣:
當(dāng)方差較大時:
方差較小時:
這里兩幅圖不是完全合適,只是類比
2.雙邊模糊
1.什么是雙邊模糊
由于考慮到不管是均值模糊或者高斯模糊,最后的效果都是整個圖像的模糊。有時候我們無需整體的模糊,而比如只模糊邊緣,或者只模糊細(xì)節(jié)。
而雙邊模糊便是實(shí)現(xiàn)了對邊緣信息的保留而弱化了細(xì)節(jié)。(這個效果可以用來磨皮,可以想想為啥)
實(shí)現(xiàn)的原理是我們確定一個數(shù)表示兩個像素之間的差值的閾值,一旦兩個像素之間超過了這個閾值,那么就不對這兩個像素進(jìn)行高斯模糊處理,一旦沒有超過,就進(jìn)行模糊處理。因?yàn)檫吘壍貐^(qū)的像素差值是比較大的,這樣就能保留邊緣的信息。
2.opencv的API
bilateralFilter(src, dest, d=15, 150, 3);
15 –計算的半徑,半徑之內(nèi)的像數(shù)都會被納入計算,如果提供-1 則根據(jù)sigma space參數(shù)取值
150 – sigma color 決定多少差值之內(nèi)的像素會被計算
3 – sigma space 如果d的值大于0則聲明無效,否則根據(jù)它來計算d值
3.磨皮美顏效果的實(shí)現(xiàn)
1.實(shí)現(xiàn)過程
通過對雙邊模糊處理后的圖像再進(jìn)行對比度加深的操作,最后就是讓模糊的邊緣再進(jìn)行加深,幾乎回到原來的效果。而模糊效果去掉皮膚上的細(xì)節(jié),從而可以讓皮膚顯得光滑并且顏色很有光澤。
并且我利用滑軌可以動態(tài)臺哦姐雙邊模糊的閾值從而讓你們自己控制磨皮的效果。
2.主要代碼
#include <opencv2/imgcodecs.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> #include <opencv2/highgui/highgui_c.h> #include <iostream> using namespace cv; using namespace std; int main(int argc, char** argv) { string path = "xxxxxxxxxxxx.jpg"; Mat img = imread(path); Mat img2 = Mat::zeros(img.size(), img.type()); Mat img3; Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0); imshow("img1", img); int x = 1, y = 1; namedWindow("Trackbars", (10, 100));//新建了一個窗口--軌跡欄 createTrackbar("x", "Trackbars", &x, 200); while (1) { bilateralFilter(img,img2,15,x,3); imshow("img2", img2); filter2D(img2, img3, img.depth(), kernel);//src.depth()表示位圖深度,和type相關(guān) imshow("img3", img3); waitKey(10); } waitKey(0); return 0; }
3.效果
原圖:
磨皮后:
(邊緣信息沒有損失,但是色塊更加均勻了還是)?
到此這篇關(guān)于OpenCV利用高斯模糊實(shí)現(xiàn)簡單的磨皮美顏效果的文章就介紹到這了,更多相關(guān)OpenCV磨皮效果內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于MATLAB神經(jīng)網(wǎng)絡(luò)圖像識別的高識別率代碼
今天小編就為大家分享一篇關(guān)于基于MATLAB神經(jīng)網(wǎng)絡(luò)圖像識別的高識別率代碼,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03C語言中g(shù)etchar的用法以及實(shí)例解析
getchar()是stdio.h中的庫函數(shù),它的作用是從stdin流中讀入一個字符,下面這篇文章主要給大家介紹了關(guān)于C語言中g(shù)etchar的用法以及實(shí)例的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-03-03C語言實(shí)現(xiàn)無規(guī)律數(shù)據(jù)加密、解密功能
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)無規(guī)律數(shù)據(jù)加密、解密功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-03-03探討register關(guān)鍵字在c語言和c++中的差異
建議不要用register關(guān)鍵字定義全局變量,因?yàn)槿肿兞康纳芷谑菑膱?zhí)行程序開始,一直到程序結(jié)束才會終止,而register變量可能會存放在cpu的寄存器中,如果在程序的整個生命周期內(nèi)都占用著寄存器的話,這是個相當(dāng)不好的舉措2013-10-10VS2010/MFC編程(常用控件:樹形控件Tree Control控件創(chuàng)建h和實(shí)例)
本篇文章介紹了VS2010/MFC編程:常用控件:樹形控件Tree Control,包括樹形控件的創(chuàng)建、CTreeCtrl類的主要成員函數(shù)和應(yīng)用實(shí)例有興趣的可以了解一下。2016-12-12