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

@ -57,7 +57,7 @@ double norm(double);
double norm(double E)
{
return (sqrt(pow(E,2)));
return (sqrt(pow(E,2)));
}
void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _boost)
@ -71,170 +71,168 @@ void cv::decolor(InputArray _src, OutputArray _dst, OutputArray _boost)
if(!I.data )
{
cout << "Could not open or find the image" << endl ;
return;
}
if(I.channels() !=3)
{
cout << "Input Color Image" << endl;
return;
}
cout << "Could not open or find the image" << endl ;
return;
}
if(I.channels() !=3)
{
cout << "Input Color Image" << endl;
return;
}
int maxIter = 15;
int iterCount = 0;
int maxIter = 15;
int iterCount = 0;
float tol = .0001;
double E = 0;
double pre_E = std::numeric_limits<double>::infinity();
Decolor obj;
Decolor obj;
Mat img;
Mat img;
img = Mat(I.size(),CV_32FC3);
I.convertTo(img,CV_32FC3,1.0/255.0);
obj.init();
vector <double> Cg;
vector < vector <double> > polyGrad;
vector < vector <double> > bc;
vector < vector < int > > comb;
vector <double> Cg;
vector < vector <double> > polyGrad;
vector < vector <double> > bc;
vector < vector < int > > comb;
vector <double> alf;
vector <double> alf;
obj.grad_system(img,polyGrad,Cg,comb);
obj.weak_order(img,alf);
obj.grad_system(img,polyGrad,Cg,comb);
obj.weak_order(img,alf);
Mat Mt = Mat(polyGrad.size(),polyGrad[0].size(), CV_32FC1);
obj.wei_update_matrix(polyGrad,Cg,Mt);
Mat Mt = Mat(polyGrad.size(),polyGrad[0].size(), CV_32FC1);
obj.wei_update_matrix(polyGrad,Cg,Mt);
vector <double> wei;
obj.wei_inti(comb,wei);
vector <double> wei;
obj.wei_inti(comb,wei);
//////////////////////////////// main loop starting ////////////////////////////////////////
//////////////////////////////// main loop starting ////////////////////////////////////////
while(norm(E-pre_E) > tol)
{
iterCount +=1;
while(norm(E-pre_E) > tol)
{
iterCount +=1;
pre_E = E;
vector <double> G_pos;
vector <double> G_neg;
vector <double> G_pos;
vector <double> G_neg;
vector <double> temp;
vector <double> temp1;
vector <double> temp;
vector <double> temp1;
double val = 0.0;
for(unsigned int i=0;i< polyGrad[0].size();i++)
{
val = 0.0;
for(unsigned int j =0;j<polyGrad.size();j++)
val = val + (polyGrad[j][i] * wei[j]);
temp.push_back(val - Cg[i]);
temp1.push_back(val + Cg[i]);
}
double val = 0.0;
for(unsigned int i=0;i< polyGrad[0].size();i++)
{
val = 0.0;
for(unsigned int j =0;j<polyGrad.size();j++)
val = val + (polyGrad[j][i] * wei[j]);
temp.push_back(val - Cg[i]);
temp1.push_back(val + Cg[i]);
}
double ans = 0.0;
double ans1 = 0.0;
for(unsigned int i =0;i<alf.size();i++)
{
ans = ((1 + alf[i])/2) * exp((-1.0 * 0.5 * pow(temp[i],2))/pow(sigma,2));
ans1 =((1 - alf[i])/2) * exp((-1.0 * 0.5 * pow(temp1[i],2))/pow(sigma,2));
G_pos.push_back(ans);
G_neg.push_back(ans1);
}
double ans = 0.0;
double ans1 = 0.0;
for(unsigned int i =0;i<alf.size();i++)
{
ans = ((1 + alf[i])/2) * exp((-1.0 * 0.5 * pow(temp[i],2))/pow(sigma,2));
ans1 =((1 - alf[i])/2) * exp((-1.0 * 0.5 * pow(temp1[i],2))/pow(sigma,2));
G_pos.push_back(ans);
G_neg.push_back(ans1);
}
vector <double> EXPsum;
vector <double> EXPterm;
vector <double> EXPsum;
vector <double> EXPterm;
for(unsigned int i = 0;i<G_pos.size();i++)
EXPsum.push_back(G_pos[i]+G_neg[i]);
for(unsigned int i = 0;i<G_pos.size();i++)
EXPsum.push_back(G_pos[i]+G_neg[i]);
vector <double> temp2;
vector <double> temp2;
for(unsigned int i=0;i<EXPsum.size();i++)
{
if(EXPsum[i] == 0)
temp2.push_back(1.0);
else
temp2.push_back(0.0);
}
for(unsigned int i=0;i<EXPsum.size();i++)
{
if(EXPsum[i] == 0)
temp2.push_back(1.0);
else
temp2.push_back(0.0);
}
for(unsigned int i =0; i < G_pos.size();i++)
EXPterm.push_back((G_pos[i] - G_neg[i])/(EXPsum[i] + temp2[i]));
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;
for(unsigned int i=0;i< polyGrad.size();i++)
{
val1 = 0.0;
for(unsigned int j =0;j<polyGrad[0].size();j++)
{
val1 = val1 + (Mt.at<float>(i,j) * EXPterm[j]);
}
wei1.push_back(val1);
}
double val1 = 0.0;
vector <double> wei1;
for(unsigned int i=0;i< polyGrad.size();i++)
{
val1 = 0.0;
for(unsigned int j =0;j<polyGrad[0].size();j++)
{
val1 = val1 + (Mt.at<float>(i,j) * EXPterm[j]);
}
wei1.push_back(val1);
}
for(unsigned int i =0;i<wei.size();i++)
wei[i] = wei1[i];
for(unsigned int i =0;i<wei.size();i++)
wei[i] = wei1[i];
E = obj.energyCalcu(Cg,polyGrad,wei);
if(iterCount > maxIter)
break;
G_pos.clear();
G_neg.clear();
temp.clear();
temp1.clear();
EXPsum.clear();
EXPterm.clear();
temp2.clear();
wei1.clear();
}
G_pos.clear();
G_neg.clear();
temp.clear();
temp1.clear();
EXPsum.clear();
EXPterm.clear();
temp2.clear();
wei1.clear();
}
Mat Gray = Mat::zeros(img.size(),CV_32FC1);
obj.grayImContruct(wei, img, Gray);
Mat Gray = Mat::zeros(img.size(),CV_32FC1);
obj.grayImContruct(wei, img, Gray);
Gray.convertTo(dst,CV_8UC1,255);
Gray.convertTo(dst,CV_8UC1,255);
/////////////////////////////////// Contrast Boosting /////////////////////////////////
Mat lab = Mat(img.size(),CV_8UC3);
Mat color = Mat(img.size(),CV_8UC3);
Mat l = Mat(img.size(),CV_8UC1);
Mat a = Mat(img.size(),CV_8UC1);
Mat b = Mat(img.size(),CV_8UC1);
Mat lab = Mat(img.size(),CV_8UC3);
Mat color = Mat(img.size(),CV_8UC3);
Mat l = Mat(img.size(),CV_8UC1);
Mat a = Mat(img.size(),CV_8UC1);
Mat b = Mat(img.size(),CV_8UC1);
cvtColor(I,lab,COLOR_BGR2Lab);
cvtColor(I,lab,COLOR_BGR2Lab);
int h1 = img.size().height;
int w1 = img.size().width;
int h1 = img.size().height;
int w1 = img.size().width;
for(int i =0;i<h1;i++)
for(int j=0;j<w1;j++)
{
l.at<uchar>(i,j) = lab.at<uchar>(i,j*3+0);
a.at<uchar>(i,j) = lab.at<uchar>(i,j*3+1);
b.at<uchar>(i,j) = lab.at<uchar>(i,j*3+2);
}
for(int i =0;i<h1;i++)
for(int j=0;j<w1;j++)
{
l.at<uchar>(i,j) = lab.at<uchar>(i,j*3+0);
a.at<uchar>(i,j) = lab.at<uchar>(i,j*3+1);
b.at<uchar>(i,j) = lab.at<uchar>(i,j*3+2);
}
for(int i =0;i<h1;i++)
for(int j=0;j<w1;j++)
{
l.at<uchar>(i,j) = 255.0*Gray.at<float>(i,j);
}
for(int i =0;i<h1;i++)
for(int j=0;j<w1;j++)
{
l.at<uchar>(i,j) = 255.0*Gray.at<float>(i,j);
}
for(int i =0;i<h1;i++)
for(int j=0;j<w1;j++)
{
lab.at<uchar>(i,j*3+0) = l.at<uchar>(i,j);
lab.at<uchar>(i,j*3+1) = a.at<uchar>(i,j);
lab.at<uchar>(i,j*3+2) = b.at<uchar>(i,j);
}
for(int i =0;i<h1;i++)
for(int j=0;j<w1;j++)
{
lab.at<uchar>(i,j*3+0) = l.at<uchar>(i,j);
lab.at<uchar>(i,j*3+1) = a.at<uchar>(i,j);
lab.at<uchar>(i,j*3+2) = b.at<uchar>(i,j);
}
cvtColor(lab,color_boost,COLOR_Lab2BGR);
cvtColor(lab,color_boost,COLOR_Lab2BGR);
}

View File

@ -39,7 +39,6 @@
//
//M*/
#include "precomp.hpp"
#include "opencv2/photo.hpp"
#include "opencv2/imgproc.hpp"
@ -69,7 +68,7 @@ class Decolor
void add_to_vector_poly(vector < vector <double> > &polyGrad, vector <double> &curGrad);
void weak_order(Mat img, vector <double> &alf);
void grad_system(Mat img, vector < vector < double > > &polyGrad,
vector < double > &Cg, vector < vector <int> >& comb);
vector < double > &Cg, vector < vector <int> >& comb);
void wei_update_matrix(vector < vector <double> > &poly, vector <double> &Cg, Mat &X);
void wei_inti(vector < vector <int> > &comb, vector <double> &wei);
void grayImContruct(vector <double> &wei, Mat img, Mat &Gray);
@ -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)
@ -359,12 +353,11 @@ void Decolor::weak_order(Mat img, vector <double> &alf)
}
void Decolor::grad_system(Mat img, vector < vector < double > > &polyGrad,
vector < double > &Cg, vector < vector <int> >& comb)
vector < double > &Cg, vector < vector <int> >& comb)
{
int h = img.size().height;
int w = img.size().width;
double sizefactor;
if((h + w) > 800)
{
@ -400,7 +393,7 @@ void Decolor::grad_system(Mat img, vector < vector < double > > &polyGrad,
for(int j=0;j<w;j++)
curIm.at<float>(i,j)=
pow(red.at<float>(i,j),r)*pow(green.at<float>(i,j),g)*
pow(blue.at<float>(i,j),b);
pow(blue.at<float>(i,j),b);
vector <double> curGrad;
gradvector(curIm,curGrad);
add_to_vector_poly(polyGrad,curGrad);
@ -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;
@ -495,7 +487,7 @@ void Decolor::grayImContruct(vector <double> &wei, Mat img, Mat &Gray)
for(int j=0;j<w;j++)
Gray.at<float>(i,j)=Gray.at<float>(i,j) +
wei[kk]*pow(red.at<float>(i,j),r)*pow(green.at<float>(i,j),g)*
pow(blue.at<float>(i,j),b);
pow(blue.at<float>(i,j),b);
kk=kk+1;
}

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);
}

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,6 @@
//
//M*/
#include "precomp.hpp"
#include "opencv2/photo.hpp"
#include "opencv2/imgproc.hpp"
@ -55,11 +54,11 @@ using namespace cv;
void cv::seamlessClone(InputArray _src, InputArray _dst, InputArray _mask, Point p, OutputArray _blend, int flags)
{
Mat src = _src.getMat();
Mat dest = _dst.getMat();
Mat mask = _mask.getMat();
_blend.create(dest.size(), CV_8UC3);
Mat blend = _blend.getMat();
Mat src = _src.getMat();
Mat dest = _dst.getMat();
Mat mask = _mask.getMat();
_blend.create(dest.size(), CV_8UC3);
Mat blend = _blend.getMat();
int minx = INT_MAX, miny = INT_MAX, maxx = INT_MIN, maxy = INT_MIN;
int h = mask.size().height;
@ -134,14 +133,14 @@ void cv::seamlessClone(InputArray _src, InputArray _dst, InputArray _mask, Point
void cv::colorChange(InputArray _src, InputArray _mask, OutputArray _dst, float r, float g, float b)
{
Mat src = _src.getMat();
Mat mask = _mask.getMat();
_dst.create(src.size(), src.type());
Mat blend = _dst.getMat();
Mat src = _src.getMat();
Mat mask = _mask.getMat();
_dst.create(src.size(), src.type());
Mat blend = _dst.getMat();
float red = r;
float green = g;
float blue = b;
float red = r;
float green = g;
float blue = b;
Mat gray = Mat::zeros(mask.size(),CV_8UC1);
@ -174,12 +173,12 @@ void cv::colorChange(InputArray _src, InputArray _mask, OutputArray _dst, float
void cv::illuminationChange(InputArray _src, InputArray _mask, OutputArray _dst, float a, float b)
{
Mat src = _src.getMat();
Mat mask = _mask.getMat();
_dst.create(src.size(), src.type());
Mat blend = _dst.getMat();
float alpha = a;
float beta = b;
Mat src = _src.getMat();
Mat mask = _mask.getMat();
_dst.create(src.size(), src.type());
Mat blend = _dst.getMat();
float alpha = a;
float beta = b;
Mat gray = Mat::zeros(mask.size(),CV_8UC1);
@ -209,13 +208,14 @@ 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();
Mat mask = _mask.getMat();
_dst.create(src.size(), src.type());
Mat blend = _dst.getMat();
Mat src = _src.getMat();
Mat mask = _mask.getMat();
_dst.create(src.size(), src.type());
Mat blend = _dst.getMat();
Mat gray = Mat::zeros(mask.size(),CV_8UC1);
@ -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);
}