Перейти к содержимому
Compvision.ru
Smorodov

Фильтр Cartoonize (вроде как из Gimp)

Recommended Posts

Перетащил еще один фильтр.

Отсюда: http://www.mathworks.com/matlabcentral/fileexchange/26188-cartoon

Результат работы:

post-1-0-37999000-1342700458_thumb.png

Код:


#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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×