一、卡通畫基本步驟
1.邊緣檢測,并保留邊緣檢測的圖像
2.将輸入圖像和邊緣檢測圖像轉換為32位浮點圖像
3.将轉換後的輸入圖像和邊緣檢測圖像相乘(兩圖合并),合并後重新轉換為CV_8UC3
4.輸出最終的結果
二、源代碼示範
/**
* 實作卡通畫效果
* 步驟:
* 1.邊緣檢測,并保留邊緣檢測的圖像
* 2.将輸入圖像和邊緣檢測圖像轉換為32位浮點圖像
* 3.将轉換後的輸入圖像和邊緣檢測圖像相乘(兩圖合并),合并後重新轉換為CV_8UC3
* 4.輸出最終的結果
*
* ps:為了達到較好的效果,可以調整邊緣檢測的門檻值,或者執行擴張的自定義形狀的卷積核的大小
* @param inputImagePath
*/
void showCartoonImage(char *inputImagePath) {
//加載原圖
Mat src = imread(inputImagePath);
//給圖檔應用高斯模糊(主要是為了去除自然界的噪聲)
Mat imgMedian;
//高斯模糊啊
medianBlur(src, imgMedian, 7);
//執行邊緣檢測
Mat imgCanny;
//此處門檻值可以嘗試用50~150
Canny(imgMedian, imgCanny, 120, 130);
//執行擴張,這裡的卷積核也可以自行調整試試看比如:放到到1~5
Mat kernel = getStructuringElement(MORPH_RECT, Size(1, 1));//定義一個2x2的卷積核
//使用擴張來連結斷開的邊緣
dilate(imgCanny, imgCanny, kernel);
//
imgCanny = imgCanny / 255;
imgCanny = 1 - imgCanny;
//轉換為32位浮點數
Mat imgCannyF;
imgCanny.convertTo(imgCannyF, CV_32FC3);
//中值模糊
blur(imgCannyF, imgCannyF, Size(3, 3));
//執行金字塔雙邊濾波,用于降噪、平滑、保持邊緣
Mat imgBF;
bilateralFilter(src, imgBF, 9, 150.0, 150.0);
//
Mat result = imgBF / 25;
result = result * 25;
//
Mat imgCanny3c;
Mat cannyChannels[] = {imgCannyF, imgCannyF, imgCannyF};
merge(cannyChannels, 3, imgCanny3c);
//轉為為32位浮點
Mat resultF;
result.convertTo(resultF, CV_32FC3);
//相乘
multiply(resultF, imgCanny3c, resultF);
//将32位重新轉為8位
resultF.convertTo(result, CV_8UC3);
//展示圖檔
//原圖
imshow("src", src);
//卡通畫效果
imshow("cartoon", result);
waitKey(0);
}
三、對比圖檔展示
