Smorodov 579 Жалоба Опубликовано July 19, 2012 Перетащил еще один фильтр. Отсюда: http://www.mathworks.com/matlabcentral/fileexchange/26188-cartoon Результат работы: Код: #include <iostream> #include <vector> #include <stdio.h> #include <stdarg.h> #include "opencv2/core/core.hpp" #include "opencv2/core/gpumat.hpp" #include "opencv2/core/opengl_interop.hpp" #include "opencv2/gpu/gpu.hpp" #include "opencv2/ml/ml.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/contrib/contrib.hpp" #include "opencv2/video/tracking.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/nonfree/nonfree.hpp" #include "fstream" #include "iostream" using namespace std; using namespace cv; // this function has 4 pararmeter; // im // mask_radius // threshold // ramp // // // Cartoon algorithm ( Courtesy of gimp ) // ----------------- // Mask radius = radius of pixel neighborhood for intensity comparison // Threshold = relative intensity difference which will result in darkening // Ramp = amount of relative intensity difference before total black // Blur radius = mask radius / 3.0 // // Algorithm: // For each pixel, calculate pixel intensity value to be: avg (blur radius) // relative diff = pixel intensity / avg (mask radius) // If relative diff < Threshold // intensity mult = (Ramp - MIN (Ramp, (Threshold - relative diff))) / Ramp // pixel intensity *= intensity mult Mat cartoonlize(Mat& src,double mask_radius=20,double threshold=1,double ramp=3) { Mat gr; Mat g; src.convertTo(g,CV_32FC1); Mat kernel(mask_radius*2+1,mask_radius*2+1,CV_32FC1); kernel=1.0/pow(mask_radius*2+1,2); Mat g_new; filter2D(g,g_new,CV_32FC1,kernel); g_new=g/g_new; Mat mult(g_new.rows,g_new.cols,CV_32FC1); for(int i=0;i<g_new.rows;i++) { for(int j=0;j<g_new.cols;j++) { mult.at<float>(i,j)=(ramp-min(ramp,threshold-g_new.at<float>(i,j)))/ramp; } } //(ramp-min(ramp,(threshold-g_new)))/ramp; gr=g; for(int i=0;i<gr.rows;i++) { for(int j=0;j<gr.cols;j++) { if(gr.at<float>(i,j)<threshold) { gr.at<float>(i,j)=g.at<float>(i,j)/mult.at<float>(i,j); } } } Mat res; gr.convertTo(res,CV_8UC1); return res; } //----------------------------------------------------------------------------------------------------- // //----------------------------------------------------------------------------------------------------- Mat cartoon(Mat& src,double mask_radius=20,double threshold=1,double ramp=3) { Mat res; if(src.channels()>1) { vector<Mat> src_arr; cv::split(src,src_arr); Mat tmp; tmp=cartoonlize(src_arr[0],mask_radius,threshold,ramp); tmp.copyTo(src_arr[0]); tmp=cartoonlize(src_arr[1],mask_radius,threshold,ramp); tmp.copyTo(src_arr[1]); tmp=cartoonlize(src_arr[2],mask_radius,threshold,ramp); tmp.copyTo(src_arr[2]); cv::merge(src_arr,res); }else { res=cartoonlize(src,mask_radius,threshold,ramp); } return res; } //----------------------------------------------------------------------------------------------------- // //----------------------------------------------------------------------------------------------------- int main( int argc, char** argv ) { namedWindow("Src"); namedWindow("Res"); Mat Img=imread("C:\\ImagesForTest\\lena.jpg"); imshow("Src",Img); //cv::cvtColor(Img,Img,cv::COLOR_RGB2HSV); Mat res=cartoon(Img,20,100,10); //cv::cvtColor(res,res,cv::COLOR_HSV2RGB); imshow("Res",res); waitKey(0); //getchar(); return 0; } [/code] Cartoonize.cpp Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано July 20, 2012 Cartoonize похож на Posterize, если это не он и есть. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах