new filters added and all the 3 modules updated

All 3 modules Updated
This commit is contained in:
siddharth 2013-09-03 21:12:05 +05:30
parent ae9b4003ae
commit 56ab1c18e6
14 changed files with 1600 additions and 570 deletions

View File

@ -39,19 +39,21 @@ colorChange
-----------
Given an original color image, two differently colored versions of this image can be mixed seamlessly.
.. ocv:function:: void colorChange( InputArray src, OutputArray dst, float red = 1.0, float green = 1.0, float blue = 1.0)
.. ocv:function:: void colorChange( InputArray src, InputArray mask, OutputArray dst, float red_mul = 1.0, float green_mul = 1.0, float blue_mul = 1.0)
:param src: Input 8-bit 3-channel image.
:param mask: Input 8-bit 1 or 3-channel image.
:param dst: Output image with the same size and type as ``src`` .
:param red: R-channel Value
:param red_mul: R-channel multiply factor.
:param green: G-channel Value
:param green_mul: G-channel multiply factor.
:param blue: B-channel Value
:param blue_mul: B-channel multiply factor.
RGB values between .5 to 2.5
Multiplication factor is between .5 to 2.5.
illuminationChange
@ -59,10 +61,12 @@ illuminationChange
Applying an appropriate non-linear transformation to the gradient field inside the selection and then integrating back with a Poisson
solver, modifies locally the apparent illumination of an image.
.. ocv:function:: void illuminationChange(InputArray src, OutputArray dst, float alpha = 0.2, float beta = 0.4)
.. ocv:function:: void illuminationChange(InputArray src, InputArray mask, OutputArray dst, float alpha = 0.2, float beta = 0.4)
:param src: Input 8-bit 3-channel image.
:param mask: Input 8-bit 1 or 3-channel image.
:param dst: Output image with the same size and type as ``src``.
:param alpha: Value ranges between 0-2.
@ -74,14 +78,21 @@ This is useful to highlight under-exposed foreground objects or to reduce specul
textureFlattening
-----------------
By retaining only the gradients at edge locations, before integrating with the Poisson solver, one washes out the texture of the selected
region, giving its contents a flat aspect.
region, giving its contents a flat aspect. Here Canny Edge Detector is used.
.. ocv:function:: void textureFlattening(InputArray src, OutputArray dst)
.. ocv:function:: void textureFlattening(InputArray src, InputArray mask, OutputArray dst, double low_threshold, double high_threshold, int kernel_size)
:param src: Input 8-bit 3-channel image.
:param mask: Input 8-bit 1 or 3-channel image.
:param dst: Output image with the same size and type as ``src``.
:param low_threshold: Range from 0 to 100.
:param high_threshold: Value > 100.
:param kernel_size: The size of the Sobel kernel to be used.
**NOTE:**

90
modules/photo/doc/npr.rst Normal file
View File

@ -0,0 +1,90 @@
Non-Photorealistic Rendering
============================
.. highlight:: cpp
edgePreservingFilter
--------------------
Filtering is the fundamental operation in image and video processing. Edge-preserving smoothing filters are used in many different applications.
.. ocv:function:: void edgePreservingFilter(InputArray src, OutputArray dst, int flags = 1, float sigma_s = 60, float sigma_r = 0.4);
:param src: Input 8-bit 3-channel image.
:param dst: Output 8-bit 3-channel image.
:param flags: Edge preserving filters:
* **RECURS_FILTER**
* **NORMCONV_FILTER**
:param sigma_s: Range between 0 to 200.
:param sigma_r: Range between 0 to 1.
detailEnhance
-------------
This filter enhances the details of a particular image.
.. ocv:function:: void detailEnhance(InputArray src, OutputArray dst, float sigma_s = 10, float sigma_r = 0.15);
:param src: Input 8-bit 3-channel image.
:param dst: Output image with the same size and type as ``src``.
:param sigma_s: Range between 0 to 200.
:param sigma_r: Range between 0 to 1.
pencilSketch
------------
Pencil-like non-photorealistic line drawing
.. ocv:function:: void pencilSketch(InputArray src, OutputArray dst1, OutputArray dst2, float sigma_s = 60, float sigma_r = 0.07, float shade_factor = 0.02);
:param src: Input 8-bit 3-channel image.
:param dst1: Output 8-bit 1-channel image.
:param dst2: Output image with the same size and type as ``src``.
:param sigma_s: Range between 0 to 200.
:param sigma_r: Range between 0 to 1.
:param shade_factor: Range between 0 to 0.1.
stylization
-----------
Stylization aims to produce digital imagery with a wide variety of effects not focused on photorealism. Edge-aware filters are ideal for stylization, as they can abstract regions of low contrast while preserving, or enhancing, high-contrast features.
.. ocv:function:: void stylization(InputArray src, OutputArray dst, float sigma_s = 60, float sigma_r = 0.45);
:param src: Input 8-bit 3-channel image.
:param dst: Output image with the same size and type as ``src``.
:param sigma_s: Range between 0 to 200.
:param sigma_r: Range between 0 to 1.
edgeEnhance
-----------
Able to suppress low-amplitude details and enhance edges.
.. ocv:function:: void edgeEnhance(InputArray src, OutputArray dst, float sigma_s = 60, float sigma_r = 0.45);
:param src: Input 8-bit 3-channel image.
:param dst: Output 8-bit 1-channel image.
:param sigma_s: Range between 0 to 200.
:param sigma_r: Range between 0 to 1.

View File

@ -68,8 +68,8 @@ enum
enum
{
RECURSIVE_FILTER = 1,
NC_FILTER = 2
RECURS_FILTER = 1,
NORMCONV_FILTER = 2
};
//! restores the damaged image areas using one of the available intpainting algorithms
@ -301,17 +301,35 @@ public:
CV_EXPORTS_W Ptr<MergeRobertson> createMergeRobertson();
CV_EXPORTS_W void decolor(InputArray src, OutputArray grayscale, OutputArray color_boost);
CV_EXPORTS_W void decolor( InputArray src, OutputArray grayscale, OutputArray color_boost);
CV_EXPORTS_W void seamlessClone(InputArray src, InputArray dst, InputArray mask, Point p, OutputArray _blend, int flags);
CV_EXPORTS_W void seamlessClone( InputArray src, InputArray dst, InputArray mask, Point p,
OutputArray _blend, int flags);
CV_EXPORTS_W void colorChange(InputArray src, InputArray mask, OutputArray dst, float red = 1.0, float green = 1.0, float blue = 1.0);
CV_EXPORTS_W void colorChange(InputArray src, InputArray mask, OutputArray dst, float red_mul = 1.0,
float green_mul = 1.0, float blue_mul = 1.0);
CV_EXPORTS_W void illuminationChange(InputArray src, InputArray mask, OutputArray dst, float alpha = 0.2, float beta = 0.4);
CV_EXPORTS_W void illuminationChange(InputArray src, InputArray mask, OutputArray dst,
float alpha = 0.2, float beta = 0.4);
CV_EXPORTS_W void textureFlattening(InputArray src, InputArray mask, OutputArray dst);
CV_EXPORTS_W void textureFlattening(InputArray src, InputArray mask, OutputArray dst,
double low_threshold, double high_threshold,
int kernel_size);
CV_EXPORTS_W void edgepreservefilter(InputArray _src, OutputArray _dst, int flags = 1, float sigma_h = 60, float sigma_r = 0.4);
CV_EXPORTS_W void edgePreservingFilter(InputArray src, OutputArray dst, int flags = 1,
float sigma_s = 60, float sigma_r = 0.4);
CV_EXPORTS_W void detailEnhance(InputArray src, OutputArray dst, float sigma_s = 10,
float sigma_r = 0.15);
CV_EXPORTS_W void pencilSketch(InputArray src, OutputArray dst, OutputArray dst1,
float sigma_s = 60, float sigma_r = 0.07, float shade_factor = 0.02);
CV_EXPORTS_W void stylization(InputArray src, OutputArray dst, float sigma_s = 60,
float sigma_r = 0.45);
CV_EXPORTS_W void edgeEnhance(InputArray src, OutputArray dst, float sigma_s = 60,
float sigma_r = 0.45);
} // cv

View File

@ -150,7 +150,6 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _boost)
for(unsigned int i = 0;i<G_pos.size();i++)
EXPsum.push_back(G_pos[i]+G_neg[i]);
vector <double> temp2;
for(unsigned int i=0;i<EXPsum.size();i++)
@ -164,7 +163,6 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _boost)
for(unsigned int i =0; i < G_pos.size();i++)
EXPterm.push_back((G_pos[i] - G_neg[i])/(EXPsum[i] + temp2[i]));
double val1 = 0.0;
vector <double> wei1;

View File

@ -39,7 +39,6 @@
//
//M*/
#include "precomp.hpp"
#include "opencv2/photo.hpp"
#include "opencv2/imgproc.hpp"
@ -87,7 +86,6 @@ float sigma = .02;
double Decolor::energyCalcu(vector <double> &Cg, vector < vector <double> > &polyGrad, vector <double> &wei)
{
vector <double> P;
vector <double> temp;
vector <double> temp1;
@ -112,8 +110,6 @@ double Decolor::energyCalcu(vector <double> &Cg, vector < vector <double> > &pol
}
void Decolor::init()
{
kernel = Mat(1,2, CV_32FC1);
@ -123,7 +119,6 @@ void Decolor::init()
kernel1.at<float>(0,0)=1.0;
kernel1.at<float>(1,0)=-1.0;
order = 2;
}
vector<double> Decolor::product(vector < vector<int> > &comb, vector <double> &initRGB)
@ -222,7 +217,6 @@ void Decolor::colorGrad(Mat img, vector <double> &Cg)
ImL.clear();
Ima.clear();
Imb.clear();
}
void Decolor::add_vector(vector < vector <int> > &comb, int r,int g,int b)
@ -364,7 +358,6 @@ void Decolor::grad_system(Mat img, vector < vector < double > > &polyGrad,
int h = img.size().height;
int w = img.size().width;
double sizefactor;
if((h + w) > 800)
{
@ -468,7 +461,6 @@ void Decolor::wei_inti(vector < vector <int> > &comb, vector <double> &wei)
void Decolor::grayImContruct(vector <double> &wei, Mat img, Mat &Gray)
{
int h=img.size().height;
int w=img.size().width;

View File

@ -1,3 +1,44 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
#include "opencv2/photo.hpp"
#include "opencv2/highgui.hpp"
@ -11,7 +52,7 @@
using namespace std;
using namespace cv;
void cv::edgepreservefilter(InputArray _src, OutputArray _dst, int flags, float sigma_s, float sigma_r)
void cv::edgePreservingFilter(InputArray _src, OutputArray _dst, int flags, float sigma_s, float sigma_r)
{
Mat I = _src.getMat();
_dst.create(I.size(), CV_8UC3);
@ -32,3 +73,196 @@ void cv::edgepreservefilter(InputArray _src, OutputArray _dst, int flags, float
convertScaleAbs(res, dst, 255,0);
}
void cv::detailEnhance(InputArray _src, OutputArray _dst, float sigma_s, float sigma_r)
{
Mat I = _src.getMat();
_dst.create(I.size(), CV_8UC3);
Mat dst = _dst.getMat();
int h = I.size().height;
int w = I.size().width;
int channel = I.channels();
float factor = 3.0;
Mat img = Mat(I.size(),CV_32FC3);
I.convertTo(img,CV_32FC3,1.0/255.0);
Mat res = Mat(h,w,CV_32FC3);
dst.convertTo(res,CV_32FC3,1.0/255.0);
Mat result = Mat(img.size(),CV_32FC3);
Mat lab = Mat(img.size(),CV_32FC3);
Mat l_channel = Mat(img.size(),CV_32FC1);
Mat a_channel = Mat(img.size(),CV_32FC1);
Mat b_channel = Mat(img.size(),CV_32FC1);
cvtColor(img,lab,COLOR_BGR2Lab);
for(int i = 0; i < h; i++)
for(int j = 0; j < w; j++)
{
l_channel.at<float>(i,j) = lab.at<float>(i,j*channel+0);
a_channel.at<float>(i,j) = lab.at<float>(i,j*channel+1);
b_channel.at<float>(i,j) = lab.at<float>(i,j*channel+2);
}
Mat L = Mat(img.size(),CV_32FC1);
l_channel.convertTo(L,CV_32FC1,1.0/255.0);
Domain_Filter obj;
obj.filter(L, res, sigma_s, sigma_r, 1);
Mat detail = Mat(h,w,CV_32FC1);
for(int i = 0; i < h; i++)
for(int j = 0; j < w; j++)
detail.at<float>(i,j) = L.at<float>(i,j) - res.at<float>(i,j);
for(int i = 0; i < h; i++)
for(int j = 0; j < w; j++)
L.at<float>(i,j) = res.at<float>(i,j) + factor*detail.at<float>(i,j);
L.convertTo(l_channel,CV_32FC1,255);
for(int i = 0; i < h; i++)
for(int j = 0; j < w; j++)
{
lab.at<float>(i,j*channel+0) = l_channel.at<float>(i,j);
lab.at<float>(i,j*channel+1) = a_channel.at<float>(i,j);
lab.at<float>(i,j*channel+2) = b_channel.at<float>(i,j);
}
cvtColor(lab,result,COLOR_Lab2BGR);
result.convertTo(dst,CV_8UC3,255);
}
void cv::pencilSketch(InputArray _src, OutputArray _dst, OutputArray _dst1, float sigma_s, float sigma_r, float shade_factor)
{
Mat I = _src.getMat();
_dst.create(I.size(), CV_8UC1);
Mat dst = _dst.getMat();
_dst1.create(I.size(), CV_8UC3);
Mat dst1 = _dst1.getMat();
Mat img = Mat(I.size(),CV_32FC3);
I.convertTo(img,CV_32FC3,1.0/255.0);
Domain_Filter obj;
Mat sketch = Mat(I.size(),CV_32FC1);
Mat color_sketch = Mat(I.size(),CV_32FC3);
obj.pencil_sketch(img, sketch, color_sketch, sigma_s, sigma_r, shade_factor);
sketch.convertTo(dst,CV_8UC1,255);
color_sketch.convertTo(dst1,CV_8UC3,255);
}
void cv::stylization(InputArray _src, OutputArray _dst, float sigma_s, float sigma_r)
{
Mat I = _src.getMat();
_dst.create(I.size(), CV_8UC3);
Mat dst = _dst.getMat();
Mat img = Mat(I.size(),CV_32FC3);
I.convertTo(img,CV_32FC3,1.0/255.0);
int h = img.size().height;
int w = img.size().width;
int channel = img.channels();
Mat res = Mat(h,w,CV_32FC3);
Domain_Filter obj;
obj.filter(img, res, sigma_s, sigma_r, NORMCONV_FILTER);
vector <Mat> planes;
split(res, planes);
Mat magXR = Mat(h, w, CV_32FC1);
Mat magYR = Mat(h, w, CV_32FC1);
Mat magXG = Mat(h, w, CV_32FC1);
Mat magYG = Mat(h, w, CV_32FC1);
Mat magXB = Mat(h, w, CV_32FC1);
Mat magYB = Mat(h, w, CV_32FC1);
Sobel(planes[0], magXR, CV_32FC1, 1, 0, 3);
Sobel(planes[0], magYR, CV_32FC1, 0, 1, 3);
Sobel(planes[1], magXG, CV_32FC1, 1, 0, 3);
Sobel(planes[1], magYG, CV_32FC1, 0, 1, 3);
Sobel(planes[2], magXB, CV_32FC1, 1, 0, 3);
Sobel(planes[2], magYB, CV_32FC1, 0, 1, 3);
Mat magx = Mat(h,w,CV_32FC1);
Mat magy = Mat(h,w,CV_32FC1);
Mat mag1 = Mat(h,w,CV_32FC1);
Mat mag2 = Mat(h,w,CV_32FC1);
Mat mag3 = Mat(h,w,CV_32FC1);
magnitude(magXR,magYR,mag1);
magnitude(magXG,magYG,mag2);
magnitude(magXB,magYB,mag3);
Mat magnitude = Mat(h,w,CV_32FC1);
for(int i =0;i < h;i++)
for(int j=0;j<w;j++)
{
magnitude.at<float>(i,j) = mag1.at<float>(i,j) + mag2.at<float>(i,j) + mag3.at<float>(i,j);
}
for(int i =0;i < h;i++)
for(int j=0;j<w;j++)
{
magnitude.at<float>(i,j) = 1.0 - magnitude.at<float>(i,j);
}
Mat stylized = Mat(h,w,CV_32FC3);
for(int i =0;i < h;i++)
for(int j=0;j<w;j++)
for(int c=0;c<channel;c++)
{
stylized.at<float>(i,j*channel + c) = res.at<float>(i,j*channel + c) * magnitude.at<float>(i,j);
}
stylized.convertTo(dst,CV_8UC3,255);
}
void cv::edgeEnhance(InputArray _src, OutputArray _dst, float sigma_s, float sigma_r)
{
Mat I = _src.getMat();
_dst.create(I.size(), CV_8UC1);
Mat dst = _dst.getMat();
Mat img = Mat(I.size(),CV_32FC3);
I.convertTo(img,CV_32FC3,1.0/255.0);
Mat orig = img.clone();
int h = img.size().height;
int w = img.size().width;
Mat res = Mat(h,w,CV_32FC3);
Mat magnitude = Mat(h,w,CV_32FC1);
Mat mag8 = Mat(h,w,CV_32FC1);
Domain_Filter obj;
obj.filter(img, res, sigma_s, sigma_r, NORMCONV_FILTER);
obj.find_magnitude(res,magnitude);
magnitude.convertTo(dst,CV_8UC1,255);
}

View File

@ -1,3 +1,44 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
#include "opencv2/photo.hpp"
#include "opencv2/imgproc.hpp"
@ -20,10 +61,13 @@ class Domain_Filter
void getGradienty( const Mat &img, Mat &gy);
void diffx(const Mat &img, Mat &temp);
void diffy(const Mat &img, Mat &temp);
void find_magnitude(Mat &img, Mat &mag);
void compute_boxfilter(Mat &output, Mat &hz, Mat &psketch, float radius);
void compute_Rfilter(Mat &O, Mat &horiz, float sigma_h);
void compute_NCfilter(Mat &O, Mat &horiz, Mat &psketch, float radius);
void filter(const Mat &img, Mat &res, float sigma_s, float sigma_r, int flags);
void pencil_sketch(const Mat &img, Mat &sketch, Mat &color_res, float sigma_s, float sigma_r, float shade_factor);
void Depth_of_field(const Mat &img, Mat &img1, float sigma_s, float sigma_r);
};
void Domain_Filter::diffx(const Mat &img, Mat &temp)
@ -70,6 +114,7 @@ void Domain_Filter::getGradientx( const Mat &img, Mat &gx)
img.at<float>(i,(j+1)*channel+c) - img.at<float>(i,j*channel+c);
}
}
void Domain_Filter::getGradienty( const Mat &img, Mat &gy)
{
int w = img.cols;
@ -86,6 +131,59 @@ void Domain_Filter::getGradienty( const Mat &img, Mat &gy)
}
}
void Domain_Filter::find_magnitude(Mat &img, Mat &mag)
{
int h = img.rows;
int w = img.cols;
vector <Mat> planes;
split(img, planes);
Mat magXR = Mat(h, w, CV_32FC1);
Mat magYR = Mat(h, w, CV_32FC1);
Mat magXG = Mat(h, w, CV_32FC1);
Mat magYG = Mat(h, w, CV_32FC1);
Mat magXB = Mat(h, w, CV_32FC1);
Mat magYB = Mat(h, w, CV_32FC1);
getGradientx(planes[0], magXR);
getGradienty(planes[0], magYR);
getGradientx(planes[1], magXG);
getGradienty(planes[1], magYG);
getGradientx(planes[2], magXR);
getGradienty(planes[2], magYR);
Mat magx = Mat(h,w,CV_32FC1);
Mat magy = Mat(h,w,CV_32FC1);
Mat mag1 = Mat(h,w,CV_32FC1);
Mat mag2 = Mat(h,w,CV_32FC1);
Mat mag3 = Mat(h,w,CV_32FC1);
magnitude(magXR,magYR,mag1);
magnitude(magXG,magYG,mag2);
magnitude(magXB,magYB,mag3);
for(int i =0;i < h;i++)
for(int j=0;j<w;j++)
{
mag.at<float>(i,j) = mag1.at<float>(i,j) + mag2.at<float>(i,j) + mag3.at<float>(i,j);
}
for(int i =0;i < h;i++)
for(int j=0;j<w;j++)
{
mag.at<float>(i,j) = 1.0 - mag.at<float>(i,j);
}
}
void Domain_Filter::compute_Rfilter(Mat &output, Mat &hz, float sigma_h)
{
@ -144,8 +242,6 @@ void Domain_Filter::compute_Rfilter(Mat &output, Mat &hz, float sigma_h)
temp.release();
V.release();
}
void Domain_Filter::compute_boxfilter(Mat &output, Mat &hz, Mat &psketch, float radius)
@ -240,7 +336,6 @@ void Domain_Filter::compute_boxfilter(Mat &output, Mat &hz, Mat &psketch, float
upper_idx.at<float>(i,j) = temp_upper_idx.at<float>(0,j) + 1;
}
lower_pos_row.release();
upper_pos_row.release();
temp_lower_idx.release();
@ -346,7 +441,6 @@ void Domain_Filter::compute_NCfilter(Mat &output, Mat &hz, Mat &psketch, float r
for(int c=0;c<channel;c++)
output.at<float>(i,j*channel+c) = final.at<float>(i,j*channel+c);
}
void Domain_Filter::init(const Mat &img, int flags, float sigma_s, float sigma_r)
{
@ -433,6 +527,7 @@ void Domain_Filter::init(const Mat &img, int flags, float sigma_s, float sigma_r
}
}
void Domain_Filter::filter(const Mat &img, Mat &res, float sigma_s = 60, float sigma_r = 0.4, int flags = 1)
{
int no_of_iter = 3;
@ -444,7 +539,6 @@ void Domain_Filter::filter(const Mat &img, Mat &res, float sigma_s = 60, float s
if(flags == 1)
{
Mat vert_t = vert.t();
for(int i=0;i<no_of_iter;i++)
@ -488,3 +582,88 @@ void Domain_Filter::filter(const Mat &img, Mat &res, float sigma_s = 60, float s
res = O.clone();
}
void Domain_Filter::pencil_sketch(const Mat &img, Mat &sketch, Mat &color_res, float sigma_s, float sigma_r, float shade_factor)
{
int no_of_iter = 3;
init(img,2,sigma_s,sigma_r);
int h = img.size().height;
int w = img.size().width;
int channel = img.channels();
/////////////////////// convert to YCBCR model for color pencil drawing //////////////////////////////////////////////////////
Mat color_sketch = Mat(h,w,CV_32FC3);
Mat Y_channel = Mat(h,w,CV_32FC1);
Mat U_channel = Mat(h,w,CV_32FC1);
Mat V_channel = Mat(h,w,CV_32FC1);
cvtColor(img,color_sketch,COLOR_BGR2YCrCb);
Mat vert_t = ct_V.t();
float sigma_h = sigma_s;
Mat penx = Mat(h,w,CV_32FC1);
Mat pen_res = Mat::zeros(h,w,CV_32FC1);
Mat peny = Mat(w,h,CV_32FC1);
Mat peny_t;
float radius;
for(int i=0;i<no_of_iter;i++)
{
sigma_h = sigma_s * sqrt(3) * pow(2.0,(no_of_iter - (i+1))) / sqrt(pow(4.0,no_of_iter) -1);
radius = sqrt(3) * sigma_h;
compute_boxfilter(O, ct_H, penx, radius);
O_t = O.t();
compute_boxfilter(O_t, vert_t, peny, radius);
O = O_t.t();
peny_t = peny.t();
for(int k=0;k<h;k++)
for(int j=0;j<w;j++)
pen_res.at<float>(k,j) = (shade_factor * (penx.at<float>(k,j) + peny_t.at<float>(k,j)));
if(i==0)
{
sketch = pen_res.clone();
for(int k = 0; k < h; k++)
for(int j = 0; j < w; j++)
{
Y_channel.at<float>(k,j) = color_sketch.at<float>(k,j*channel+0);
U_channel.at<float>(k,j) = color_sketch.at<float>(k,j*channel+1);
V_channel.at<float>(k,j) = color_sketch.at<float>(k,j*channel+2);
}
for(int k=0;k<h;k++)
for(int j=0;j<w;j++)
Y_channel.at<float>(k,j) = pen_res.at<float>(k,j);
// cvMerge(Y_channel,U_channel,V_channel,0,color_sketch);
for(int k = 0; k < h; k++)
for(int j = 0; j < w; j++)
{
color_sketch.at<float>(k,j*channel+0) = Y_channel.at<float>(k,j);
color_sketch.at<float>(k,j*channel+1) = U_channel.at<float>(k,j);
color_sketch.at<float>(k,j*channel+2) = V_channel.at<float>(k,j);
}
cvtColor(color_sketch,color_res,COLOR_YCrCb2BGR);
}
}
}

View File

@ -39,7 +39,6 @@
//
//M*/
#include "precomp.hpp"
#include "opencv2/photo.hpp"
#include "opencv2/imgproc.hpp"
@ -209,7 +208,8 @@ void cv::illuminationChange(InputArray _src, InputArray _mask, OutputArray _dst,
}
void cv::textureFlattening(InputArray _src, InputArray _mask, OutputArray _dst)
void cv::textureFlattening(InputArray _src, InputArray _mask, OutputArray _dst,
double low_threshold, double high_threshold, int kernel_size)
{
Mat src = _src.getMat();
@ -241,6 +241,6 @@ void cv::textureFlattening(InputArray _src, InputArray _mask, OutputArray _dst)
}
Cloning obj;
obj.texture_flatten(src,cs_mask,gray,blend);
obj.texture_flatten(src,cs_mask,gray,low_threshold,high_threshold,kernel_size,blend);
}

View File

@ -39,7 +39,6 @@
//
//M*/
#include "precomp.hpp"
#include "opencv2/photo.hpp"
#include "opencv2/imgproc.hpp"
@ -74,9 +73,9 @@ class Cloning
void transpose(double *mat, double *mat_t,int h,int w);
void poisson_solver(const Mat &img, Mat &gxx , Mat &gyy, Mat &result);
void normal_clone(Mat &I, Mat &mask, Mat &wmask, Mat &final, int num);
void local_color_change(Mat &I, Mat &mask, Mat &wmask, Mat &final, float red, float green, float blue);
void local_color_change(Mat &I, Mat &mask, Mat &wmask, Mat &final, float red_mul, float green_mul, float blue_mul);
void illum_change(Mat &I, Mat &mask, Mat &wmask, Mat &final, float alpha, float beta);
void texture_flatten(Mat &I, Mat &mask, Mat &wmask, Mat &final);
void texture_flatten(Mat &I, Mat &mask, Mat &wmask, double low_threshold, double high_threhold, int kernel_size, Mat &final);
};
void Cloning::getGradientx( const Mat &img, Mat &gx)
@ -94,6 +93,7 @@ void Cloning::getGradientx( const Mat &img, Mat &gx)
(float)img.at<uchar>(i,(j+1)*channel+c) - (float)img.at<uchar>(i,j*channel+c);
}
}
void Cloning::getGradienty( const Mat &img, Mat &gy)
{
int w = img.size().width;
@ -110,6 +110,7 @@ void Cloning::getGradienty( const Mat &img, Mat &gy)
}
}
void Cloning::lapx( const Mat &img, Mat &gxx)
{
int w = img.size().width;
@ -125,6 +126,7 @@ void Cloning::lapx( const Mat &img, Mat &gxx)
(float)img.at<float>(i,(j+1)*channel+c) - (float)img.at<float>(i,j*channel+c);
}
}
void Cloning::lapy( const Mat &img, Mat &gyy)
{
int w = img.size().width;
@ -242,6 +244,7 @@ void Cloning::transpose(double *mat, double *mat_t,int h,int w)
tmp.release();
}
void Cloning::poisson_solver(const Mat &img, Mat &gxx , Mat &gyy, Mat &result)
{
@ -275,7 +278,6 @@ void Cloning::poisson_solver(const Mat &img, Mat &gxx , Mat &gyy, Mat &result)
+ (int)bound.at<uchar>(i-1,j) + (int)bound.at<uchar>(i+1,j);
}
Mat diff = Mat(h,w,CV_32FC1);
for(int i =0;i<h;i++)
{
@ -391,7 +393,6 @@ void Cloning::poisson_solver(const Mat &img, Mat &gxx , Mat &gyy, Mat &result)
delete [] img_d;
delete [] gtest;
delete [] f_bp;
}
void Cloning::init(Mat &I, Mat &wmask)
@ -486,6 +487,7 @@ void Cloning::calc(Mat &I, Mat &gx, Mat &gy, Mat &sx, Mat &sy)
}
void Cloning::normal_clone(Mat &I, Mat &mask, Mat &wmask, Mat &final, int num)
{
init(I,wmask);
@ -609,7 +611,8 @@ void Cloning::normal_clone(Mat &I, Mat &mask, Mat &wmask, Mat &final, int num)
}
void Cloning::local_color_change(Mat &I, Mat &mask, Mat &wmask, Mat &final, float red=1.0, float green=1.0, float blue=1.0)
void Cloning::local_color_change(Mat &I, Mat &mask, Mat &wmask, Mat &final, float red_mul=1.0,
float green_mul=1.0, float blue_mul=1.0)
{
init(I,wmask);
@ -649,13 +652,11 @@ void Cloning::local_color_change(Mat &I, Mat &mask, Mat &wmask, Mat &final, floa
for(int i=0;i < h; i++)
for(int j=0; j < w; j++)
{
factor.at<float>(i,j*channel+0) = blue;
factor.at<float>(i,j*channel+1) = green;
factor.at<float>(i,j*channel+2) = red;
factor.at<float>(i,j*channel+0) = blue_mul;
factor.at<float>(i,j*channel+1) = green_mul;
factor.at<float>(i,j*channel+2) = red_mul;
}
for(int i=0;i < h; i++)
for(int j=0; j < w; j++)
for(int c=0;c<channel;++c)
@ -783,7 +784,8 @@ void Cloning::illum_change(Mat &I, Mat &mask, Mat &wmask, Mat &final, float alph
}
void Cloning::texture_flatten(Mat &I, Mat &mask, Mat &wmask, Mat &final)
void Cloning::texture_flatten(Mat &I, Mat &mask, Mat &wmask, double low_threshold,
double high_threshold, int kernel_size, Mat &final)
{
init(I,wmask);
@ -807,10 +809,8 @@ void Cloning::texture_flatten(Mat &I, Mat &mask, Mat &wmask, Mat &final)
I.convertTo(srx32,CV_32FC3,1.0/255.0);
I.convertTo(sry32,CV_32FC3,1.0/255.0);
Mat out = Mat(mask.size(),CV_8UC1);
Canny( mask, out, 30, 45, 3 );
Canny(mask,out,low_threshold,high_threshold,kernel_size);
int channel = mask.channels();

View File

@ -100,7 +100,7 @@ TEST(Photo_SeamlessClone_mixed, regression)
TEST(Photo_SeamlessClone_featureExchange, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "cloning/Feature_Exchange/";
string folder = string(cvtest::TS::ptr()->get_data_path()) + "cloning/Monochrome_Transfer/";
string original_path1 = folder + "source1.png";
string original_path2 = folder + "destination1.png";
string original_path3 = folder + "mask.png";
@ -174,7 +174,7 @@ TEST(Photo_SeamlessClone_textureFlattening, regression)
ASSERT_FALSE(mask.empty()) << "Could not load mask image " << original_path2;
Mat result;
textureFlattening(source, mask, result);
textureFlattening(source, mask, result, 30, 45, 3);
imwrite(folder + "cloned.png", result);

View File

@ -0,0 +1,146 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
#include "opencv2/photo.hpp"
#include <string>
using namespace cv;
using namespace std;
TEST(Photo_NPR_EdgePreserveSmoothing_RecursiveFilter, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/Smoothing/";
string original_path = folder + "test1.png";
Mat source = imread(original_path, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;
Mat result;
edgePreservingFilter(source,result,1);
imwrite(folder + "smoothened_RF.png", result);
}
TEST(Photo_NPR_EdgePreserveSmoothing_NormConvFilter, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/Smoothing/";
string original_path = folder + "test1.png";
Mat source = imread(original_path, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;
Mat result;
edgePreservingFilter(source,result,2);
imwrite(folder + "smoothened_NCF.png", result);
}
TEST(Photo_NPR_DetailEnhance, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/Detail_Enhance/";
string original_path = folder + "test1.png";
Mat source = imread(original_path, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;
Mat result;
detailEnhance(source,result);
imwrite(folder + "detail_enhanced.png", result);
}
TEST(Photo_NPR_PencilSketch, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/Pencil_Sketch/";
string original_path = folder + "test1.png";
Mat source = imread(original_path, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;
Mat result,result1;
pencilSketch(source,result,result1,10,.1,.03);
imwrite(folder + "pencil_sketch.png", result);
imwrite(folder + "color_pencil_sketch.png", result1);
}
TEST(Photo_NPR_Stylization, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/Stylization/";
string original_path = folder + "test1.png";
Mat source = imread(original_path, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;
Mat result;
stylization(source,result);
imwrite(folder + "stylized.png", result);
}
TEST(Photo_NPR_EdgeEnhance, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/Edge_Enhance/";
string original_path = folder + "test1.png";
Mat source = imread(original_path, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;
Mat result;
edgeEnhance(source,result);
imwrite(folder + "edge_enhanced.png", result);
}

View File

@ -56,18 +56,19 @@ char src[50];
char dest[50];
int var = 0;
int flag = 0;
int flag1 = 0;
int flag = 0, flag1 = 0, flag4 = 0;
int minx,miny,maxx,maxy,lenx,leny;
int minxd,minyd,maxxd,maxyd,lenxd,lenyd;
int minx, miny, maxx, maxy, lenx, leny;
int minxd, minyd, maxxd, maxyd, lenxd, lenyd;
int channel,num;
int channel, num, kernel_size;
float alpha,beta;
float red, green, blue;
double low_t, high_t;
void source(int event, int x, int y, int, void*)
{
@ -159,7 +160,7 @@ void source(int event, int x, int y, int, void*)
}
else if(num == 6)
{
textureFlattening(img0,res1,blend);
textureFlattening(img0,res1,blend,low_t,high_t,kernel_size);
imshow("Texture Flattened", blend);
waitKey(0);
}
@ -176,11 +177,12 @@ void source(int event, int x, int y, int, void*)
flag1 = 0;
minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN;
imshow("Source", img0);
if(num == 1 || num == 2 || num == 3)
imshow("Destination",img2);
drag = 0;
}
}
void destination(int event, int x, int y, int, void*)
{
@ -190,6 +192,7 @@ void destination(int event, int x, int y, int, void*)
im1 = img2.clone();
if (event == EVENT_LBUTTONDOWN)
{
flag4 = 1;
if(flag1 == 1)
{
point = Point(x, y);
@ -386,14 +389,12 @@ int main(int argc, char **argv)
res1 = Mat::zeros(img0.size(),CV_8UC1);
final = Mat::zeros(img0.size(),CV_8UC3);
//////////// source image ///////////////////
namedWindow("Source", 1);
setMouseCallback("Source", source, NULL);
imshow("Source", img0);
}
else if(num == 5)
{
@ -416,12 +417,20 @@ int main(int argc, char **argv)
setMouseCallback("Source", source, NULL);
imshow("Source", img0);
}
else if(num == 6)
{
checkfile(s);
cout << "low_threshold: ";
cin >> low_t;
cout << "high_threshold: ";
cin >> high_t;
cout << "kernel_size: ";
cin >> kernel_size;
img0 = imread(src);
res1 = Mat::zeros(img0.size(),CV_8UC1);
@ -434,13 +443,16 @@ int main(int argc, char **argv)
imshow("Source", img0);
}
int flag3 = 0;
while(true)
{
char key = waitKey(0);
if(key == 'd')
if(key == 'd' && flag3 == 0)
{
flag1 = 1;
flag3 = 1;
img1 = img0.clone();
for(int i = var; i < numpts ; i++)
pts[i] = point;
@ -490,13 +502,15 @@ int main(int argc, char **argv)
}
var = 0;
flag1 = 0;
flag3 = 0;
flag4 = 0;
minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN;
imshow("Source", img0);
if(num == 1 || num == 2 || num == 3)
imshow("Destination",img2);
drag = 0;
}
else if ((num == 1 || num == 2 || num == 3) && key == 'c' && flag1 == 1)
else if ((num == 1 || num == 2 || num == 3) && key == 'c' && flag1 == 1 && flag4 == 1)
{
seamlessClone(img0,img2,res1,point,blend,num);
imshow("Cloned Image", blend);
@ -516,14 +530,12 @@ int main(int argc, char **argv)
}
else if (num == 6 && key == 'c' && flag1 == 1)
{
textureFlattening(img0,res1,blend);
textureFlattening(img0,res1,blend,low_t,high_t,kernel_size);
imshow("Texture Flattened", blend);
imwrite("cloned.png",blend);
}
else if(key == 'q')
exit(0);
}
waitKey(0);
}

View File

@ -0,0 +1,243 @@
/*
* cloning.cpp
*
* Author:
* Siddharth Kherada <siddharthkherada27[at]gmail[dot]com>
*
* This tutorial demonstrates how to use OpenCV seamless cloning
* module without GUI.
*
* 1- Normal Cloning
* 2- Mixed Cloning
* 3- Monochrome Transfer
* 4- Color Change
* 5- Illumination change
* 6- Texture Flattening
* The program takes as input a source and a destination image (for 1-3 methods)
* and ouputs the cloned image.
*/
#include "opencv2/photo.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"
#include <iostream>
#include <stdlib.h>
using namespace std;
using namespace cv;
int main(int argc, char **argv)
{
cout << endl;
cout << "Cloning Module" << endl;
cout << "---------------" << endl;
cout << "Options: " << endl;
cout << endl;
cout << "1) Normal Cloning " << endl;
cout << "2) Mixed Cloning " << endl;
cout << "3) Monochrome Transfer " << endl;
cout << "4) Local Color Change " << endl;
cout << "5) Local Illumination Change " << endl;
cout << "6) Texture Flattening " << endl;
cout << endl;
cout << "Press number 1-6 to choose from above techniques: ";
int num;
cin >> num;
cout << endl;
if(num == 1)
{
string folder = "cloning/Normal_Cloning/";
string original_path1 = folder + "source1.png";
string original_path2 = folder + "destination1.png";
string original_path3 = folder + "mask.png";
Mat source = imread(original_path1, IMREAD_COLOR);
Mat destination = imread(original_path2, IMREAD_COLOR);
Mat mask = imread(original_path3, IMREAD_COLOR);
if(source.empty())
{
cout << "Could not load source image " << original_path1 << endl;
exit(0);
}
if(destination.empty())
{
cout << "Could not load destination image " << original_path2 << endl;
exit(0);
}
if(mask.empty())
{
cout << "Could not load mask image " << original_path3 << endl;
exit(0);
}
Mat result;
Point p;
p.x = 400;
p.y = 100;
seamlessClone(source, destination, mask, p, result, 1);
imshow("Output",result);
imwrite(folder + "cloned.png", result);
}
else if(num == 2)
{
string folder = "cloning/Mixed_Cloning/";
string original_path1 = folder + "source1.png";
string original_path2 = folder + "destination1.png";
string original_path3 = folder + "mask.png";
Mat source = imread(original_path1, IMREAD_COLOR);
Mat destination = imread(original_path2, IMREAD_COLOR);
Mat mask = imread(original_path3, IMREAD_COLOR);
if(source.empty())
{
cout << "Could not load source image " << original_path1 << endl;
exit(0);
}
if(destination.empty())
{
cout << "Could not load destination image " << original_path2 << endl;
exit(0);
}
if(mask.empty())
{
cout << "Could not load mask image " << original_path3 << endl;
exit(0);
}
Mat result;
Point p;
p.x = destination.size().width/2;
p.y = destination.size().height/2;
seamlessClone(source, destination, mask, p, result, 2);
imshow("Output",result);
imwrite(folder + "cloned.png", result);
}
else if(num == 3)
{
string folder = "cloning/Monochrome_Transfer/";
string original_path1 = folder + "source1.png";
string original_path2 = folder + "destination1.png";
string original_path3 = folder + "mask.png";
Mat source = imread(original_path1, IMREAD_COLOR);
Mat destination = imread(original_path2, IMREAD_COLOR);
Mat mask = imread(original_path3, IMREAD_COLOR);
if(source.empty())
{
cout << "Could not load source image " << original_path1 << endl;
exit(0);
}
if(destination.empty())
{
cout << "Could not load destination image " << original_path2 << endl;
exit(0);
}
if(mask.empty())
{
cout << "Could not load mask image " << original_path3 << endl;
exit(0);
}
Mat result;
Point p;
p.x = destination.size().width/2;
p.y = destination.size().height/2;
seamlessClone(source, destination, mask, p, result, 3);
imshow("Output",result);
imwrite(folder + "cloned.png", result);
}
else if(num == 4)
{
string folder = "cloning/Color_Change/";
string original_path1 = folder + "source1.png";
string original_path2 = folder + "mask.png";
Mat source = imread(original_path1, IMREAD_COLOR);
Mat mask = imread(original_path2, IMREAD_COLOR);
if(source.empty())
{
cout << "Could not load source image " << original_path1 << endl;
exit(0);
}
if(mask.empty())
{
cout << "Could not load mask image " << original_path2 << endl;
exit(0);
}
Mat result;
colorChange(source, mask, result, 1.5, .5, .5);
imshow("Output",result);
imwrite(folder + "cloned.png", result);
}
else if(num == 5)
{
string folder = "cloning/Illumination_Change/";
string original_path1 = folder + "source1.png";
string original_path2 = folder + "mask.png";
Mat source = imread(original_path1, IMREAD_COLOR);
Mat mask = imread(original_path2, IMREAD_COLOR);
if(source.empty())
{
cout << "Could not load source image " << original_path1 << endl;
exit(0);
}
if(mask.empty())
{
cout << "Could not load mask image " << original_path2 << endl;
exit(0);
}
Mat result;
illuminationChange(source, mask, result, .2, .4);
imshow("Output",result);
imwrite(folder + "cloned.png", result);
}
else if(num == 6)
{
string folder = "cloning/Texture_Flattening/";
string original_path1 = folder + "source1.png";
string original_path2 = folder + "mask.png";
Mat source = imread(original_path1, IMREAD_COLOR);
Mat mask = imread(original_path2, IMREAD_COLOR);
if(source.empty())
{
cout << "Could not load source image " << original_path1 << endl;
exit(0);
}
if(mask.empty())
{
cout << "Could not load mask image " << original_path2 << endl;
exit(0);
}
Mat result;
textureFlattening(source, mask, result, 30, 45, 3);
imshow("Output",result);
imwrite(folder + "cloned.png", result);
}
waitKey(0);
}

107
samples/cpp/npr_demo.cpp Normal file
View File

@ -0,0 +1,107 @@
/*
* npr_demo.cpp
*
* Author:
* Siddharth Kherada <siddharthkherada27[at]gmail[dot]com>
*
* This tutorial demonstrates how to use OpenCV Non-Photorealistic Rendering Module.
* 1) Edge Preserve Smoothing
* -> Using Normalized convolution Filter
* -> Using Recursive Filter
* 2) Detail Enhancement
* 3) Pencil sketch/Color Pencil Drawing
* 4) Stylization
* 5) Edge Enhancement
*
*/
#include <signal.h>
#include "opencv2/photo.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"
#include <iostream>
#include <stdlib.h>
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
int num,type;
int flag = 0;
Mat I = imread(argv[1]);
if(argc < 2)
{
cout << "usage: " << argv[0] << " <Input image> " << endl;
exit(0);
}
if(!I.data)
{
cout << "Image not found" << endl;
exit(0);
}
cout << endl;
cout << " Edge Preserve Filter" << endl;
cout << "----------------------" << endl;
cout << "Options: " << endl;
cout << endl;
cout << "1) Edge Preserve Smoothing" << endl;
cout << " -> Using Normalized convolution Filter" << endl;
cout << " -> Using Recursive Filter" << endl;
cout << "2) Detail Enhancement" << endl;
cout << "3) Pencil sketch/Color Pencil Drawing" << endl;
cout << "4) Stylization" << endl;
cout << "5) Edge Enhancement" << endl;
cout << endl;
cout << "Press number 1-5 to choose from above techniques: ";
cin >> num;
Mat img;
if(num == 1)
{
cout << endl;
cout << "Press 1 for Normalized Convolution Filter and 2 for Recursive Filter: ";
cin >> type;
edgePreservingFilter(I,img,type);
imshow("Edge Preserve Smoothing",img);
}
else if(num == 2)
{
detailEnhance(I,img);
imshow("Detail Enhanced",img);
}
else if(num == 3)
{
Mat img1;
pencilSketch(I,img1, img, 10 ,.1,.03);
imshow("Pencil Sketch",img1);
imshow("Color Pencil Sketch",img);
}
else if(num == 4)
{
stylization(I,img);
imshow("Stylization",img);
}
else if(num == 5)
{
edgeEnhance(I,img);
imshow("Edge Enhance",img);
}
waitKey(0);
}