Opencv實戰【4】——圖片動漫化處理

博主聯系方式:
QQ:1540984562
微信:wxid_nz49532kbh9u22 QQ交流群:750313950

目錄

    • 動漫化風格的特點
    • 處理手段
    • 代碼
    • 實現效果
    • 總結

動漫化風格的特點

(1)動漫中的細節相對少;
(2)動漫中的邊緣輪廓更突出;
(3)動漫的色彩更鮮艷;

處理手段

(1)突出邊緣線條
利用canny算子找出邊緣,然后利用copyTo函數將邊緣加到原圖上。
這里用到copyTo函數的第二種用法:

copyTo(roi , mask)

作用是把mask和image重疊以后把mask中像素值為非0(black)的點對應的image中的點變為透明,而保留為0的點。
然而我們發現,canny算子得到的結果是二值化圖,其中邊緣像素值為255,是白色,非邊緣像素是0,是黑色。
若是直接將canny算子得到的結果進行累加,則會是這樣的結果。
結果

所以我們要進行處理:

change_g_cannyImage = 255 - g_cannyImage;

非邊緣轉化為255,邊緣轉化為0;非邊緣會在之后的處理會變為透明,而邊緣則會保持原有的數據0,為黑色,這樣就會有強化邊緣的效果。
主要代碼:

//【1】運行canny算子Canny(g_grayImage, g_cannyImage, g_nThresholdValue, g_nThresholdValue/3, 3);cv::Mat g_canny3Image(g_srcImage.rows, g_srcImage.cols, CV_8UC3, cv::Scalar(0,0,0));//【2】貼圖//(將邊緣變為黑色)Mat change_g_cannyImage;change_g_cannyImage = 255 - g_cannyImage;//將單通道轉化為三通道cvtColor(change_g_cannyImage, g_canny3Image, COLOR_GRAY2BGR);//image.copyTo(imageROI,mask), 作用是把mask和image重疊以后把mask中像素值為0(black)的點對應的image中的點變為透明,而保留其他點。Mat bianyuan_dst;g_srcImage.copyTo(bianyuan_dst, g_canny3Image);

效果:
效果
(2)弱化與去除細節
這里的細節是除了邊緣外的,只在區域的內部進行弱化。這時就需要使用雙邊濾波。

所謂“細節”,從圖像處理的角度看來就是圖像中的高頻成分。要想去除高頻成分,自然而然就要用到濾波(filtering)的方法。常用的濾波器有均值濾波器、高斯濾波器、中值濾波器等。但是,這些常用濾波器都有一個共同的問題——會弱化所有的高頻信息。而很不幸的是,圖像中的邊緣也屬于高頻信息(因為邊緣意味著圖像在這里產生了突變,突變就意味著高頻)。因此常用濾波器會將我們本應突出的邊緣一起弱化模糊。
這種情況下就要讓雙邊濾波器(Bilateral filter)出場了。這種濾波器的特點是可以“保邊濾波”(或者叫“區域平滑”,Region smoothing)。顧名思義,就是可以只模糊區域內部而保留清晰的邊緣。為了搞明白雙邊濾波器為什么有這樣的效果,首先來說一下高斯濾波器。高斯濾波器,或者說高斯濾波模板,其中的各個點的值僅與該點到模板中心點的空間距離有關,而并沒有考慮各個點與中心點的相似度(即像素值的接近程度),這樣就導致無論是變化不大的區域內部點,還是突變的邊緣點,只要和中心的距離相同,那就同等對待。
而雙邊濾波器就是在高斯濾波器基礎上加上了相似度權重,在高斯濾波模板的每個點上再乘以一個與中心點的相似度系數(即“相似度權重”),從而將邊緣與內部區分處理。相似度權重計算方法和高斯濾波模板中各點值(可以稱為“高斯權重”)的計算方法相同,只不過高斯權重是將該點到中心的距離代入高斯函數計算,而相似度權重是將該點與中心的像素相似度(比如該點像素值與中心像素值的歐氏距離,或者直接求二者的差值)代入高斯函數計算得到。

//【3】雙邊濾波Mat lvbo_dst;bilateralFilter(bianyuan_dst, lvbo_dst, g_nkernelValue, g_nkernelValue * 2, g_nkernelValue / 2);

(3)讓圖像色彩更鮮艷
提高色彩飽和度。
方法:
1、RGB轉HSV,且提取原圖像的S通道
2、乘上一個大于1的數,并且對值進行限幅
3、將修改后的S通道替換掉原本的S通道,并將3個通道合并
4、HSV轉為RGB

//【4】修改圖像的顏色的飽和度Mat hsv_image,hsv_dst;cvtColor(lvbo_dst, hsv_image, COLOR_BGR2HSV);vector<Mat> channels;split(hsv_image, channels);Mat S_Mat;float k = g_nS*1.0f / 100;channels.at(1).copyTo(S_Mat);cv::Mat S_dst(S_Mat.rows, S_Mat.cols, CV_8UC1, cv::Scalar(0));//S_dst = S_Mat * k;H_mul_k(&S_Mat, &S_dst,k);//將修改后的S與原來的H,V進行mergechannels[1] = S_dst.clone();	//深復制merge(channels, hsv_dst);//將修改后的HSV轉為RGB圖Mat RGB_dst;cvtColor(hsv_dst, RGB_dst, COLOR_HSV2BGR);

代碼

#include <opencv2/opencv.hpp>
#include "opencv2/features2d.hpp"
#include <iostream>
#include "windows.h"
#include <stdio.h>
#include <time.h>
#include <math.h>  
#define WINDOW_NAME "【程序窗口】"			
using namespace cv;
using namespace std;
//RNG g_rng(12345);//對照片進行動漫化一般需要四個步驟
//1、邊緣檢測
//2、將邊緣檢測得到的邊緣 以黑色的形式貼在原來的畫上。
//3、對貼了邊緣的圖進行雙邊濾波,雙邊濾波可以較好的濾波的同時保留邊緣。
//4、修改圖像的顏色的飽和度,本文采用的是將RGB轉化為HSV空間,然后調整S分量。//*--------------------------【全局變量聲明】-------------------------------------*/
int g_nThresholdValue = 100;	//canny參數值
int g_nkernelValue = 3;	//雙邊濾波核大小
int g_nS = 100;	//雙邊濾波核大小
Mat g_srcImage, g_grayImage,g_cannyImage,g_dstImage;//*--------------------------【全局函數聲明】-------------------------------------*/
void on_CannyThreshold(int, void*);	//回調函數/****照片動漫化示例**********/
int main()
{//載入原圖g_srcImage = imread("D:\\opencv_picture_test\\HOG行人檢測\\timg.jpg");//加載原圖if (g_srcImage.empty()){printf("Could not find the image!\n");return -1;}g_grayImage.create(g_srcImage.size(), g_srcImage.type());		//創建一個同大小類型的矩陣cvtColor(g_srcImage, g_grayImage,COLOR_BGR2GRAY);//imshow("【原圖的灰度圖】", g_grayImage);//進行均值濾波操作blur(g_grayImage, g_grayImage, Size(3, 3));namedWindow(WINDOW_NAME, WINDOW_NORMAL);//WINDOW_NORMAL允許用戶自由伸縮窗口//【3】創建窗口 并 顯示原圖//imshow("原始圖", g_srcImage);//【4】創建滑動條來控制閾值createTrackbar("canny參數值", WINDOW_NAME, &g_nThresholdValue, 255, on_CannyThreshold);createTrackbar("雙邊濾波核", WINDOW_NAME, &g_nkernelValue, 25, on_CannyThreshold);createTrackbar("S擴大", WINDOW_NAME, &g_nS, 300, on_CannyThreshold);//【5】初始化自定義的閾值回調函數on_CannyThreshold(0, 0);while (1){if (waitKey(10) == 27) break;		//按下Esc 退出}return 0;}void H_mul_k(Mat* srcImage, Mat* dstImage, float k)
{int height = (*srcImage).rows;int width = (*srcImage).cols;for (int j = 0; j < height; j++){for (int i = 0; i < width; i++){int zhi = (*srcImage).at<uchar>(j, i) * k;if (zhi >= 255) zhi = 255;else if (zhi <= 0) zhi = 0;else zhi = zhi;(*dstImage).at<uchar>(j, i) = zhi;}}
}
//*--------------------------【on_Threshold 函數】-------------------------------------*/
void on_CannyThreshold(int, void*)
{//【1】運行canny算子Canny(g_grayImage, g_cannyImage, g_nThresholdValue, g_nThresholdValue/3, 3);cv::Mat g_canny3Image(g_srcImage.rows, g_srcImage.cols, CV_8UC3, cv::Scalar(0,0,0));//【2】貼圖//將canny圖反轉(將邊緣變為黑色)Mat change_g_cannyImage;//change_g_cannyImage = g_cannyImage < 100;		//非邊緣轉化為255,邊緣轉化為0;非邊緣會在之后的處理會變為透明,而邊緣則會保持原有的數據0change_g_cannyImage = 255 - g_cannyImage;//將單通道轉化為三通道cvtColor(change_g_cannyImage, g_canny3Image, COLOR_GRAY2BGR);//image.copyTo(imageROI,mask), 作用是把mask和image重疊以后把mask中像素值為0(black)的點對應的image中的點變為透明,而保留其他點。Mat bianyuan_dst;g_srcImage.copyTo(bianyuan_dst, g_canny3Image);//【3】雙邊濾波Mat lvbo_dst;bilateralFilter(bianyuan_dst, lvbo_dst, g_nkernelValue, g_nkernelValue * 2, g_nkernelValue / 2);//【4】修改圖像的顏色的飽和度Mat hsv_image,hsv_dst;cvtColor(lvbo_dst, hsv_image, COLOR_BGR2HSV);vector<Mat> channels;split(hsv_image, channels);Mat S_Mat;float k = g_nS*1.0f / 100;channels.at(1).copyTo(S_Mat);cv::Mat S_dst(S_Mat.rows, S_Mat.cols, CV_8UC1, cv::Scalar(0));//S_dst = S_Mat * k;H_mul_k(&S_Mat, &S_dst,k);//將修改后的S與原來的H,V進行mergechannels[1] = S_dst.clone();	//深復制merge(channels, hsv_dst);//將修改后的HSV轉為RGB圖Mat RGB_dst;cvtColor(hsv_dst, RGB_dst, COLOR_HSV2BGR);imshow(WINDOW_NAME, RGB_dst);
}

實現效果

原圖

漫畫圖

總結

這種方法其實只能對部分景象圖有比較好的漫畫效果,對人的臉部面容效果其實并不是很好。
似乎是有根據深度學習訓練出來的算法,能夠對人臉面容實現很好的動漫化:
如何用深度學習模型為自己做個漫畫畫像
零門檻人像轉卡通、GIF表情包
這兩個鏈接并沒有相關代碼,原理還是很復雜的,以后再進行研究。

Reference:

圖片動漫化處理原理
opencv 照片動漫風格
RGB、HSV、HSI顏色空間
OpenCV cvtColor()函數
opencv中的merge函數
openCv——copyTo()的形式詳解

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/378524.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/378524.shtml
英文地址,請注明出處:http://en.pswp.cn/news/378524.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

nextshort_Java掃描儀的nextShort()方法與示例

nextshort掃描器類的nextShort()方法 (Scanner Class nextShort() method) Syntax: 句法&#xff1a; public short nextShort();public short nextShort(int rad);nextShort() method is available in java.util package. nextShort()方法在java.util包中可用。 nextShort() …

php 生成css文件怎么打開,php生成html文件的多種步驟介紹

//定義日期函數functiongetdatetime(){$datetimegetdate();$strReturn$datetime["year"]."-";$strReturn$strReturn.$datetime["mon"]."-";$strReturn$strReturn.$datetime["mday"];return$strReturn;}//定義時間函數(文件名…

08-KNN手寫數字識別

標簽下載地址 文件內容備注train-images-idx3-ubyte.gz訓練集圖片&#xff1a;55000張訓練圖片&#xff0c;5000張驗證圖片train-labels-idx1-ubyte.gz訓練集圖片對應的數字標簽t10k-images-idx3-ubyte.gz測試集圖片&#xff1a;10000張圖片t表示test&#xff0c;測試圖片&…

MFC odbc訪問遠程數據庫

首先&#xff0c;MFC通過ODBC訪問數據庫&#xff0c;主要使用兩個類&#xff0c;一個是CDataBase&#xff0c;一個是CRecordset。第一個是用于建立數據庫連接的&#xff0c;第二個是數據集&#xff0c;用來查詢的。步驟如下&#xff1a;1.實例化一個CDataBase對象&#xff0c;并…

微機原理——擴展存儲器設計

目錄【1】存儲器的層次結構【2】存儲器的分類【3】SRAM1、基本原理&#xff1a;2、結構&#xff1a;3、芯片參數與引腳解讀&#xff1a;4、CPU與SRAM的連接方式【4】DRAM1、基本原理&#xff1a;2、結構3、芯片引腳解讀&#xff1a;【5】存儲器系統設計【6】存儲器擴展設計&…

floatvalue 重寫_Java Number floatValue()方法與示例

floatvalue 重寫Number類floatValue()方法 (Number Class floatValue() method) floatValue() method is available in java.lang package. floatValue()方法在java.lang包中可用。 floatValue() method is used to return the value denoted by this Number object converted …

array_column php什么版本可以用,array_column兼容php5.5以下版本

gistfile1.txt// ----------------------------------------------------------------------// |獲取二維數組中指定的一列&#xff0c;PHP5.5以后有專用函數array_column()// ----------------------------------------------------------------------// |param array $arr// …

。net學習之控件的使用注意點

jQuery使用 1、自定義屬性的使用<script>$(#xwjj_i_main br[brinfoPd_KangQiao_Subject_Xwjj_br_1]).hide();</script> 2、ready代碼塊$(document).ready(function(){ //你的代碼}); 3、簡單的特效hide&#xff08;&#xff09;$("a").click(function()…

09-CNN手寫數字識別

CNN卷積神經網絡的本質就是卷積運算 維度的調整&#xff1a; tf.reshape(imageInput,[-1,28,28,1]) imageInput為[None,784]&#xff0c;N行* 784維 調整為 M28行28列*1通道 即&#xff1a;二維轉化為四維數據 參數一&#xff1a;等價于運算結果M 參數二&#xff1a;28 28 表示…

【轉】左值與右值

出處&#xff1a;http://www.embedded.com/electronics-blogs/programming-pointers/4023341/Lvalues-and-Rvalues C and C enforce subtle differences on the expressions to the left and right of the assignment operator If youve been programming in either C or C for…

Opencv將處理后的視頻保存出現的問題

問題描述&#xff1a; 代碼運行過程中&#xff0c;imshow出來的每幀的效果圖是正確的&#xff0c;但是按照網上的方法保存下來卻是0kb&#xff0c;打開不了。 參考的網上的一些方法&#xff0c;均是失敗的&#xff0c;具體原因我也不清楚&#xff1a; 1、例如我這樣設置&#x…

Java Number shortValue()方法與示例

Number類shortValue()方法 (Number Class shortValue() method) shortValue() method is available in java.lang package. shortValue()方法在java.lang包中可用。 shortValue() method is used to return the value denoted by this Number object converted to type short (…

MATLAB可以打開gms文件嗎,gms文件擴展名,gms文件怎么打開?

.gms文件類型&#xff1a;Gesture and Motion Signal File擴展名為.gms的文件是一個數據文件。文件說明&#xff1a;Low-level, binary, minimal but generic format used to organize and store Gesture and Motion Signals in a flexible and optimized way; gesture-related…

黑白圖片顏色反轉并保存

將圖像的黑白顏色反轉并保存 import cv2 # opencv讀取圖像 img cv2.imread(rE:\Python-workspace\OpenCV\OpenCV/YY.png, 1) cv2.imshow(img, img) img_shape img.shape # 圖像大小(565, 650, 3) print(img_shape) h img_shape[0] w img_shape[1] # 彩色圖像轉換為灰度圖…

家貓WEB系統

現在只放源碼在些.為它寫應用很簡單有空整理文檔演示地址:jiamaocode.com/os/ 源碼&#xff1a;http://jiamaocode.com/ProCts/2011/04/14/1918/1918.html轉載于:https://www.cnblogs.com/jiamao/archive/2011/04/16/2018339.html

C# DataRow數組轉換為DataTable

public DataTable ToDataTable(DataRow[] rows) { if (rows null || rows.Length 0) return null; DataTable tmp rows[0].Table.Clone(); // 復制DataRow的表結構 foreach (DataRow row in rows) tmp.Rows.Add(row); // 將DataRow添加…

plesk 運行不了php,如何在Plesk中使用composer(使用其他版本的PHP運行Composer)

對于基于Plesk的服務器, composer的默認安裝將使用系統安裝的PHP版本, 而不使用Plesk所安裝的任何版本。盡管Composer至少需要PHP 5.3.2, 但是當你嘗試在需要特定版本PHP的項目中安裝依賴項時, 就會出現問題。例如, 如果你有一個至少需要PHP 7.2的項目, 并且系統的默認PHP安裝是…

Java Calendar hashCode()方法與示例

日歷類hashCode()方法 (Calendar Class hashCode() method) hashCode() method is available in java.util package. hashCode()方法在java.util包中可用。 hashCode() method is used to retrieve the hash code value of this Calendar. hashCode()方法用于檢索此Calendar的哈…

Error: Flash Download failed - Target DLL has been cancelled

博主聯系方式: QQ:1540984562 QQ交流群:892023501 群里會有往屆的smarters和電賽選手,群里也會不時分享一些有用的資料,有問題可以在群里多問問。 由于換了新電腦,keil重裝了下,然而之前的MCU的支持包沒有安裝,以及一些其他的問題,導致可以編譯但是不能將程序燒錄到單片…

設計一個較為合理的實驗方案來研究芳綸纖維的染色熱力學性能

請你設計一個較為合理的實驗方案來研究芳綸纖維的染色熱力學性能?包括吸附等溫線、親和力、染色熱和染色熵的測定,并指出實驗中應注意哪些事項來減少實驗誤差? 標準答案: 染色熱力學理論研究染色平衡問題。研究染色熱力學性能:首先研究選擇適宜的染料 吸附等溫線類型測定…