提交 e170115a 编写于 作者: S siddharth

new interface added. decolor and cloning module added.

Both modules added
上级 5b0ee9e0
Seamless Cloning
================
.. highlight:: cpp
seamlessClone
-------------
Image editing tasks concern either global changes (color/intensity corrections, filters, deformations) or local changes concerned to a selection.
Here we are interested in achieving local changes, ones that are restricted to a region manually selected (ROI), in a seamless and effortless manner.
The extent of the changes ranges from slight distortions to complete replacement by novel content.
.. ocv:function:: void seamlessClone( InputArray src, InputArray dst, InputArray mask, Point p, OutputArray result, int flags)
:param src: Input 8-bit 3-channel image.
:param dst: Input 8-bit 3-channel image.
:param mask: Input 8-bit 1 or 3-channel image.
:param Point: Point in dst image where object is placed.
:param result: Output image with the same size and type as ``dst``.
:param flags: Cloning method that could be one of the following:
* **NORMAL_CLONE** The power of the method is fully expressed when inserting objects with complex outlines into a new background
* **MIXED_CLONE** The classic method, color-based selection and alpha
masking might be time consuming and often leaves an undesirable halo. Seamless
cloning, even averaged with the original image, is not effective. Mixed seamless
cloning based on a loose selection proves effective.
* **FEATURE_EXCHANGE** Feature exchange allows the user to replace easily certain
features of one object by alternative features.
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)
:param src: Input 8-bit 3-channel image.
:param dst: Output image with the same size and type as ``src`` .
:param red: R-channel Value
:param green: G-channel Value
:param blue: B-channel Value
RGB values between .5 to 2.5
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)
:param src: Input 8-bit 3-channel image.
:param dst: Output image with the same size and type as ``src``.
:param alpha: Value ranges between 0-2.
:param beta: Value ranges between 0-2.
This is useful to highlight under-exposed foreground objects or to reduce specular reflections.
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.
.. ocv:function:: void textureFlattening(InputArray src, OutputArray dst)
:param src: Input 8-bit 3-channel image.
:param dst: Output image with the same size and type as ``src``.
**NOTE:**
The algorithm assumes that the color of the source image is close to that of the destination. This assumption means that when the colors don't match, the source image color gets tinted toward the color of the destination image.
......@@ -66,12 +66,6 @@ enum
FEATURE_EXCHANGE = 3
};
enum
{
FOREGROUND_COLOR_CHANGE = 4,
BACKGROUND_DECOLOR = 5
};
//! restores the damaged image areas using one of the available intpainting algorithms
CV_EXPORTS_W void inpaint( InputArray src, InputArray inpaintMask,
OutputArray dst, double inpaintRadius, int flags );
......@@ -303,13 +297,13 @@ CV_EXPORTS_W Ptr<MergeRobertson> createMergeRobertson();
CV_EXPORTS_W void decolor(InputArray src, OutputArray grayscale, OutputArray color_boost);
CV_EXPORTS_W void seamlessClone(InputArray src, InputArray dst, OutputArray blend, int flags = 1);
CV_EXPORTS_W void seamlessClone(InputArray src, InputArray dst, InputArray mask, Point p, OutputArray _blend, int flags);
CV_EXPORTS_W void colorChange(InputArray src, OutputArray dst, int flags = 4, 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 = 1.0, float green = 1.0, float blue = 1.0);
CV_EXPORTS_W void illuminationChange(InputArray _src, 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, OutputArray _dst);
CV_EXPORTS_W void textureFlattening(InputArray src, OutputArray dst);
} // cv
......
/*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"
......
/*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"
......
/*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"
......@@ -11,364 +53,161 @@
using namespace std;
using namespace cv;
Mat img0, img1, img2, res, res1, final, final1, blend;
Point point;
int drag = 0;
int destx, desty;
int numpts = 100;
Point* pts = new Point[100];
Point* pts1 = new Point[100];
Point* pts2 = new Point[100];
int var = 0;
int flag = 0;
int flag1 = 0;
int minx,miny,maxx,maxy,lenx,leny;
int minxd,minyd,maxxd,maxyd,lenxd,lenyd;
int channel,num;
float alpha,beta;
float red, green, blue;
void mouseHandler(int , int , int , int, void*);
void mouseHandler1(int , int , int , int, void*);
void mouseHandler(int event, int x, int y, int, void*)
{
if (event == EVENT_LBUTTONDOWN && !drag)
{
if(flag1 == 0)
{
if(var==0)
img1 = img0.clone();
point = Point(x, y);
circle(img1,point,2,Scalar(0, 0, 255),-1, 8, 0);
pts[var] = point;
var++;
drag = 1;
if(var>1)
line(img1,pts[var-2], point, Scalar(0, 0, 255), 2, 8, 0);
imshow("Source", img1);
}
}
if (event == EVENT_LBUTTONUP && drag)
{
imshow("Source", img1);
drag = 0;
}
if (event == EVENT_RBUTTONDOWN)
{
flag1 = 1;
img1 = img0.clone();
for(int i = var; i < numpts ; i++)
pts[i] = point;
if(var!=0)
{
const Point* pts3[1] = {&pts[0]};
polylines( img1, pts3, &numpts,1, 1, Scalar(0,0,0), 2, 8, 0);
}
for(int i=0;i<var;i++)
{
minx = min(minx,pts[i].x);
maxx = max(maxx,pts[i].x);
miny = min(miny,pts[i].y);
maxy = max(maxy,pts[i].y);
}
lenx = maxx - minx;
leny = maxy - miny;
imshow("Source", img1);
}
if (event == EVENT_RBUTTONUP)
{
flag = var;
final = Mat::zeros(img0.size(),CV_8UC3);
res1 = Mat::zeros(img0.size(),CV_8UC1);
const Point* pts4[1] = {&pts[0]};
fillPoly(res1, pts4,&numpts, 1, Scalar(255, 255, 255), 8, 0);
bitwise_and(img0, img0, final,res1);
imshow("Source", img1);
if(num == 4)
{
Cloning obj;
obj.local_color_change(img0,final,res1,blend,num,red,green,blue);
namedWindow("Color Change Image");
imshow("Color Change Image", blend);
waitKey(0);
}
else if(num == 5)
{
Cloning obj;
Mat img3 = Mat(img0.size(),CV_8UC1);
Mat img4 = Mat(img0.size(),CV_8UC3);
cvtColor(img0,img3,COLOR_BGR2GRAY);
for(int i=0;i<img0.size().height;i++)
for(int j=0;j<img0.size().width;j++)
{
img4.at<uchar>(i,j*3+0) = img3.at<uchar>(i,j);
img4.at<uchar>(i,j*3+1) = img3.at<uchar>(i,j);
img4.at<uchar>(i,j*3+2) = img3.at<uchar>(i,j);
}
obj.local_color_change(img4,final,res1,blend,num);
namedWindow("Background Decolor Image");
imshow("Background Decolor Image", blend);
waitKey(0);
}
else if(num == 6)
{
Cloning obj;
obj.illum_change(img0,final,res1,blend,alpha,beta);
namedWindow("Illum Change Image");
imshow("Illum Change Image", blend);
waitKey(0);
}
}
if (event == EVENT_MBUTTONDOWN)
{
for(int i = 0; i < numpts ; i++)
{
pts[i].x=0;
pts[i].y=0;
}
var = 0;
flag1 = 0;
minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN;
imshow("Source", img0);
drag = 0;
}
}
void mouseHandler1(int event, int x, int y, int, void*)
{
Mat im1;
minxd = INT_MAX; minyd = INT_MAX; maxxd = INT_MIN; maxyd = INT_MIN;
im1 = img2.clone();
if (event == EVENT_LBUTTONDOWN)
{
if(flag1 == 1)
{
point = Point(x, y);
for(int i =0; i < numpts;i++)
pts1[i] = pts[i];
int tempx;
int tempy;
for(int i =0; i < flag; i++)
{
tempx = pts1[i+1].x - pts1[i].x;
tempy = pts1[i+1].y - pts1[i].y;
if(i==0)
{
pts2[i+1].x = point.x + tempx;
pts2[i+1].y = point.y + tempy;
}
else if(i>0)
{
pts2[i+1].x = pts2[i].x + tempx;
pts2[i+1].y = pts2[i].y + tempy;
}
}
for(int i=flag;i<numpts;i++)
pts2[i] = pts2[flag-1];
pts2[0] = point;
const Point* pts5[1] = {&pts2[0]};
polylines( im1, pts5, &numpts,1, 1, Scalar(0,0,255), 2, 8, 0);
destx = x;
desty = y;
imshow("Destination", im1);
}
}
if (event == EVENT_RBUTTONUP)
{
for(int i=0;i<flag;i++)
{
minxd = min(minxd,pts2[i].x);
maxxd = max(maxxd,pts2[i].x);
minyd = min(minyd,pts2[i].y);
maxyd = max(maxyd,pts2[i].y);
}
if(maxxd > im1.size().width || maxyd > im1.size().height || minxd < 0 || minyd < 0)
{
cout << "Index out of range" << endl;
exit(0);
}
final1 = Mat::zeros(img2.size(),CV_8UC3);
res = Mat::zeros(img2.size(),CV_8UC1);
for(int i=miny, k=minyd;i<(miny+leny);i++,k++)
for(int j=minx,l=minxd ;j<(minx+lenx);j++,l++)
{
for(int c=0;c<channel;c++)
{
final1.at<uchar>(k,l*channel+c) = final.at<uchar>(i,j*channel+c);
}
}
const Point* pts6[1] = {&pts2[0]};
fillPoly(res, pts6, &numpts, 1, Scalar(255, 255, 255), 8, 0);
if(num == 1 || num == 2 || num == 3)
{
Cloning obj;
obj.normal_clone(img2,final1,res,blend,num);
namedWindow("Cloned Image");
imshow("Cloned Image", blend);
waitKey(0);
}
for(int i = 0; i < flag ; i++)
{
pts2[i].x=0;
pts2[i].y=0;
}
minxd = INT_MAX; minyd = INT_MAX; maxxd = INT_MIN; maxyd = INT_MIN;
}
im1.release();
}
void cv::seamlessClone(InputArray _src, InputArray _dst, OutputArray _blend, int flags)
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);
blend = _blend.getMat();
num = flags;
minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN;
minxd = INT_MAX; minyd = INT_MAX; maxxd = INT_MIN; maxyd = INT_MIN;
img0 = src;
img2 = dest;
channel = img0.channels();
res = Mat::zeros(img2.size(),CV_8UC1);
res1 = Mat::zeros(img0.size(),CV_8UC1);
final = Mat::zeros(img0.size(),CV_8UC3);
final1 = Mat::zeros(img2.size(),CV_8UC3);
//////////// source image ///////////////////
namedWindow("Source", 1);
setMouseCallback("Source", mouseHandler, NULL);
imshow("Source", img0);
/////////// destination image ///////////////
namedWindow("Destination", 1);
setMouseCallback("Destination", mouseHandler1, NULL);
imshow("Destination",img2);
waitKey(0);
img0.release();
img1.release();
img2.release();
Mat blend = _blend.getMat();
int minx = INT_MAX, miny = INT_MAX, maxx = INT_MIN, maxy = INT_MIN;
int h = mask.size().height;
int w = mask.size().width;
Mat gray = Mat(mask.size(),CV_8UC1);
Mat dst_mask = Mat::zeros(dest.size(),CV_8UC1);
Mat cs_mask = Mat::zeros(src.size(),CV_8UC3);
Mat cd_mask = Mat::zeros(dest.size(),CV_8UC3);
if(mask.channels() == 3)
cvtColor(mask, gray, COLOR_BGR2GRAY );
else
gray = mask;
for(int i=0;i<h;i++)
{
for(int j=0;j<w;j++)
{
if(gray.at<uchar>(i,j) == 255)
{
minx = std::min(minx,i);
maxx = std::max(maxx,i);
miny = std::min(miny,j);
maxy = std::max(maxy,j);
}
}
}
int lenx = maxx - minx;
int leny = maxy - miny;
int minxd = p.y - lenx/2;
int maxxd = p.y + lenx/2;
int minyd = p.x - leny/2;
int maxyd = p.x + leny/2;
if(minxd < 0 || minyd < 0 || maxxd > dest.size().height || maxyd > dest.size().width)
{
cout << "Index out of range" << endl;
exit(0);
}
for(int i=minx, k=minxd;i<(minx+lenx);i++,k++)
for(int j=miny,l=minyd ;j<(miny+leny);j++,l++)
{
dst_mask.at<uchar>(k,l) = gray.at<uchar>(i,j);
}
int channel = 3;
for(int i=minx;i<(minx+lenx);i++)
for(int j=miny;j<(miny+leny);j++)
{
for(int c=0;c<3;c++)
{
if(gray.at<uchar>(i,j) == 255)
cs_mask.at<uchar>(i,j*channel+c) = src.at<uchar>(i,j*channel+c);
}
}
for(int i=minx, k=minxd;i<(minx+lenx);i++,k++)
for(int j=miny,l=minyd ;j<(miny+leny);j++,l++)
{
for(int c=0;c<channel;c++)
cd_mask.at<uchar>(k,l*channel+c) = cs_mask.at<uchar>(i,j*channel+c);
}
Cloning obj;
obj.normal_clone(dest,cd_mask,dst_mask,blend,flags);
}
void cv::colorChange(InputArray _src, OutputArray _dst, int flags, float r, float g, float b)
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());
blend = _dst.getMat();
Mat blend = _dst.getMat();
minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN;
minxd = INT_MAX; minyd = INT_MAX; maxxd = INT_MIN; maxyd = INT_MIN;
num = flags;
red = r;
green = g;
blue = b;
img0 = src;
res1 = Mat::zeros(img0.size(),CV_8UC1);
final = Mat::zeros(img0.size(),CV_8UC3);
namedWindow("Source");
setMouseCallback("Source", mouseHandler, NULL);
imshow("Source", img0);
waitKey(0);
img0.release();
float red = r;
float green = g;
float blue = b;
Mat gray = Mat::zeros(mask.size(),CV_8UC1);
cvtColor(mask, gray, COLOR_BGR2GRAY);
Mat cs_mask = Mat::zeros(src.size(),CV_8UC3);
int channel = 3;
for(int i=0;i<mask.size().height;i++)
for(int j=0;j<mask.size().width;j++)
{
if(gray.at<uchar>(i,j) == 255)
{
for(int c=0;c<channel;c++)
{
cs_mask.at<uchar>(i,j*channel+c) = src.at<uchar>(i,j*channel+c);
}
}
}
Cloning obj;
obj.local_color_change(src,cs_mask,gray,blend,red,green,blue);
}
void cv::illuminationChange(InputArray _src, OutputArray _dst, float a, float b)
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());
blend = _dst.getMat();
num = 6;
alpha = a;
beta = b;
Mat blend = _dst.getMat();
float alpha = a;
float beta = b;
Mat gray = Mat::zeros(mask.size(),CV_8UC1);
cvtColor(mask, gray, COLOR_BGR2GRAY);
Mat cs_mask = Mat::zeros(src.size(),CV_8UC3);
int channel = 3;
for(int i=0;i<mask.size().height;i++)
for(int j=0;j<mask.size().width;j++)
{
if(gray.at<uchar>(i,j) == 255)
{
for(int c=0;c<channel;c++)
{
cs_mask.at<uchar>(i,j*channel+c) = src.at<uchar>(i,j*channel+c);
}
}
}
Cloning obj;
obj.illum_change(src,cs_mask,gray,blend,alpha,beta);
img0 = src;
res1 = Mat::zeros(img0.size(),CV_8UC1);
final = Mat::zeros(img0.size(),CV_8UC3);
namedWindow("Source");
setMouseCallback("Source", mouseHandler, NULL);
imshow("Source", img0);
waitKey(0);
}
void cv::textureFlattening(InputArray _src, OutputArray _dst)
{
Mat src = _src.getMat();
_dst.create(src.size(), src.type());
blend = _dst.getMat();
img0 = src;
Mat blend = _dst.getMat();
Cloning obj;
obj.texture_flatten(img0,blend);
namedWindow("Texture Flattened Image");
imshow("Texture Flattened Image", blend);
waitKey(0);
obj.texture_flatten(src,blend);
}
/*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_SeamlessClone_normal, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "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);
ASSERT_FALSE(source.empty()) << "Could not load source image " << original_path1;
ASSERT_FALSE(destination.empty()) << "Could not load destination image " << original_path2;
ASSERT_FALSE(mask.empty()) << "Could not load mask image " << original_path3;
Mat result;
Point p;
p.x = destination.size().width/2;
p.y = destination.size().height/2;
seamlessClone(source, destination, mask, p, result, 1);
imwrite(folder + "cloned.png", result);
}
TEST(Photo_SeamlessClone_mixed, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "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);
ASSERT_FALSE(source.empty()) << "Could not load source image " << original_path1;
ASSERT_FALSE(destination.empty()) << "Could not load destination image " << original_path2;
ASSERT_FALSE(mask.empty()) << "Could not load mask image " << original_path3;
Mat result;
Point p;
p.x = destination.size().width/2;
p.y = destination.size().height/2;
seamlessClone(source, destination, mask, p, result, 2);
imwrite(folder + "cloned.png", result);
}
TEST(Photo_SeamlessClone_featureExchange, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "cloning/Feature_Exchange/";
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);
ASSERT_FALSE(source.empty()) << "Could not load source image " << original_path1;
ASSERT_FALSE(destination.empty()) << "Could not load destination image " << original_path2;
ASSERT_FALSE(mask.empty()) << "Could not load mask image " << original_path3;
Mat result;
Point p;
p.x = destination.size().width/2;
p.y = destination.size().height/2;
seamlessClone(source, destination, mask, p, result, 3);
imwrite(folder + "cloned.png", result);
}
TEST(Photo_SeamlessClone_colorChange, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "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);
ASSERT_FALSE(source.empty()) << "Could not load source image " << original_path1;
ASSERT_FALSE(mask.empty()) << "Could not load mask image " << original_path2;
Mat result;
colorChange(source, mask, result, 1.5, .5, .5);
imwrite(folder + "cloned.png", result);
}
TEST(Photo_SeamlessClone_illuminationChange, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "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);
ASSERT_FALSE(source.empty()) << "Could not load source image " << original_path1;
ASSERT_FALSE(mask.empty()) << "Could not load mask image " << original_path2;
Mat result;
illuminationChange(source, mask, result, .2, .4);
imwrite(folder + "cloned.png", result);
}
TEST(Photo_SeamlessClone_textureFlattening, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "cloning/Texture_Flattening/";
string original_path = folder + "source1.png";
Mat source = imread(original_path, IMREAD_COLOR);
ASSERT_FALSE(source.empty()) << "Could not load source image " << original_path;
Mat result;
textureFlattening(source, result);
imwrite(folder + "cloned.png", result);
}
/*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>
......@@ -5,35 +47,22 @@
using namespace cv;
using namespace std;
#ifdef DUMP_RESULTS
# define DUMP(image, path) imwrite(path, image)
#else
# define DUMP(image, path)
#endif
TEST(Photo_Decolor, regression)
{
string folder = string(cvtest::TS::ptr()->get_data_path()) + "decolor/";
string original_path = folder + "color_image_1.png";
string expected_path1 = folder + "grayscale_image_1.png";
string expected_path2 = folder + "color_boost_image_1.png";
Mat original = imread(original_path, IMREAD_COLOR);
Mat expected1 = imread(expected_path1, IMREAD_GRAYSCALE);
Mat expected2 = imread(expected_path2, IMREAD_COLOR);
ASSERT_FALSE(original.empty()) << "Could not load input image " << original_path;
ASSERT_FALSE(expected1.empty()) << "Could not load reference image " << expected_path1;
ASSERT_FALSE(expected2.empty()) << "Could not load reference image " << expected_path2;
ASSERT_FALSE(original.channels()!=3) << "Load color input image " << original_path;
Mat grayscale, color_boost;
decolor(original, grayscale, color_boost);
DUMP(grayscale, expected_path1 + ".grayscale.png");
DUMP(color_boost, expected_path2 + ".color_boost.png");
imwrite(folder + "grayscale.png",grayscale);
imwrite(folder + "color_boost.png",color_boost);
ASSERT_EQ(0, norm(grayscale != expected1));
ASSERT_EQ(0, norm(color_boost != expected2));
}
/*
* cloning.cpp
*
* Author:
* Siddharth Kherada <siddharthkherada27[at]gmail[dot]com>
*
* This tutorial demonstrates how to use OpenCV seamless cloning
* module.
* Flags:
* 1- NORMAL_CLONE
* 2- MIXED_CLONE
* 3- FEATURE_EXCHANGE
* The program takes as input a source and a destination image
* and ouputs the cloned image.
* Step 1:
* -> In the source image, select the region of interest by left click mouse button. A Polygon ROI will be created by left clicking mouse button.
* -> To set the Polygon ROI, click the right mouse button.
* -> To reset the region selected, click the middle mouse button.
* Step 2:
* -> In the destination image, select the point where you want to place the ROI in the image by left clicking mouse button.
* -> To get the cloned result, click the right mouse button.
* Result: The cloned image will be displayed.
*/
#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;
Mat img0, img1, img2, res, res1, final, final1, blend;
Point point;
int drag = 0;
int destx, desty;
int numpts = 100;
Point* pts = new Point[100];
Point* pts2 = new Point[100];
Point* pts_diff = new Point[100];
int var = 0;
int flag = 0;
int flag1 = 0;
int minx,miny,maxx,maxy,lenx,leny;
int minxd,minyd,maxxd,maxyd,lenxd,lenyd;
int channel,num;
void source(int event, int x, int y, int, void*)
{
if (event == EVENT_LBUTTONDOWN && !drag)
{
if(flag1 == 0)
{
if(var==0)
img1 = img0.clone();
point = Point(x, y);
circle(img1,point,2,Scalar(0, 0, 255),-1, 8, 0);
pts[var] = point;
var++;
drag = 1;
if(var>1)
line(img1,pts[var-2], point, Scalar(0, 0, 255), 2, 8, 0);
imshow("Source", img1);
}
}
if (event == EVENT_LBUTTONUP && drag)
{
imshow("Source", img1);
drag = 0;
}
if (event == EVENT_RBUTTONDOWN)
{
flag1 = 1;
img1 = img0.clone();
for(int i = var; i < numpts ; i++)
pts[i] = point;
if(var!=0)
{
const Point* pts3[1] = {&pts[0]};
polylines( img1, pts3, &numpts,1, 1, Scalar(0,0,0), 2, 8, 0);
}
for(int i=0;i<var;i++)
{
minx = min(minx,pts[i].x);
maxx = max(maxx,pts[i].x);
miny = min(miny,pts[i].y);
maxy = max(maxy,pts[i].y);
}
lenx = maxx - minx;
leny = maxy - miny;
int mid_pointx = minx + lenx/2;
int mid_pointy = miny + leny/2;
for(int i=0;i<var;i++)
{
pts_diff[i].x = pts[i].x - mid_pointx;
pts_diff[i].y = pts[i].y - mid_pointy;
}
imshow("Source", img1);
}
if (event == EVENT_RBUTTONUP)
{
flag = var;
final = Mat::zeros(img0.size(),CV_8UC3);
res1 = Mat::zeros(img0.size(),CV_8UC1);
const Point* pts4[1] = {&pts[0]};
fillPoly(res1, pts4,&numpts, 1, Scalar(255, 255, 255), 8, 0);
bitwise_and(img0, img0, final,res1);
imshow("Source", img1);
}
if (event == EVENT_MBUTTONDOWN)
{
for(int i = 0; i < numpts ; i++)
{
pts[i].x=0;
pts[i].y=0;
}
var = 0;
flag1 = 0;
minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN;
imshow("Source", img0);
drag = 0;
}
}
void destination(int event, int x, int y, int, void*)
{
Mat im1;
minxd = INT_MAX; minyd = INT_MAX; maxxd = INT_MIN; maxyd = INT_MIN;
im1 = img2.clone();
if (event == EVENT_LBUTTONDOWN)
{
if(flag1 == 1)
{
point = Point(x, y);
for(int i=0;i<var;i++)
{
pts2[i].x = point.x + pts_diff[i].x;
pts2[i].y = point.y + pts_diff[i].y;
}
for(int i=var;i<numpts;i++)
{
pts2[i].x = point.x + pts_diff[0].x;
pts2[i].y = point.y + pts_diff[0].y;
}
const Point* pts5[1] = {&pts2[0]};
polylines( im1, pts5, &numpts,1, 1, Scalar(0,0,255), 2, 8, 0);
destx = x;
desty = y;
imshow("Destination", im1);
}
}
if (event == EVENT_RBUTTONUP)
{
for(int i=0;i<flag;i++)
{
minxd = min(minxd,pts2[i].x);
maxxd = max(maxxd,pts2[i].x);
minyd = min(minyd,pts2[i].y);
maxyd = max(maxyd,pts2[i].y);
}
if(maxxd > im1.size().width || maxyd > im1.size().height || minxd < 0 || minyd < 0)
{
cout << "Index out of range" << endl;
exit(0);
}
final1 = Mat::zeros(img2.size(),CV_8UC3);
res = Mat::zeros(img2.size(),CV_8UC1);
for(int i=miny, k=minyd;i<(miny+leny);i++,k++)
for(int j=minx,l=minxd ;j<(minx+lenx);j++,l++)
{
for(int c=0;c<channel;c++)
{
final1.at<uchar>(k,l*channel+c) = final.at<uchar>(i,j*channel+c);
}
}
const Point* pts6[1] = {&pts2[0]};
fillPoly(res, pts6, &numpts, 1, Scalar(255, 255, 255), 8, 0);
if(num == 1 || num == 2 || num == 3)
{
seamlessClone(img0,img2,res1,point,blend,num);
imshow("Cloned Image", blend);
imwrite("cloned.png",blend);
waitKey(0);
}
for(int i = 0; i < flag ; i++)
{
pts2[i].x=0;
pts2[i].y=0;
}
minxd = INT_MAX; minyd = INT_MAX; maxxd = INT_MIN; maxyd = INT_MIN;
}
im1.release();
}
int main(int argc, char **argv)
{
if (argc != 3)
{
cout << "usage: " << argv[0] << " <source image>" << " <destination image>" << endl;
exit(1);
}
Mat src = imread(argv[1]);
Mat dest = imread(argv[2]);
cout << "Flags:" << endl;
cout << "1- NORMAL_CLONE" << endl;
cout << "2- MIXED_CLONE" << endl;
cout << "3- FEATURE_EXCHANGE" << endl << endl;
cout << "Enter Flag:";
cin >> num;
minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN;
minxd = INT_MAX; minyd = INT_MAX; maxxd = INT_MIN; maxyd = INT_MIN;
img0 = src;
img2 = dest;
channel = img0.channels();
res = Mat::zeros(img2.size(),CV_8UC1);
res1 = Mat::zeros(img0.size(),CV_8UC1);
final = Mat::zeros(img0.size(),CV_8UC3);
final1 = Mat::zeros(img2.size(),CV_8UC3);
//////////// source image ///////////////////
namedWindow("Source", 1);
setMouseCallback("Source", source, NULL);
imshow("Source", img0);
/////////// destination image ///////////////
namedWindow("Destination", 1);
setMouseCallback("Destination", destination, NULL);
imshow("Destination",img2);
waitKey(0);
img0.release();
img1.release();
img2.release();
}
/*
* create_mask.cpp
*
* Author:
* Siddharth Kherada <siddharthkherada27[at]gmail[dot]com>
*
* This tutorial demonstrates how to make mask image (black and white).
* The program takes as input a source image and ouputs its corresponding
* mask image.
*/
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"
#include <iostream>
#include <stdlib.h>
using namespace std;
using namespace cv;
Mat img0, img1, res1, final;
Point point;
int drag = 0;
int numpts = 100;
Point* pts = new Point[100];
int var = 0;
int flag = 0;
int flag1 = 0;
int minx,miny,maxx,maxy,lenx,leny;
int channel;
void mouseHandler(int event, int x, int y, int, void*)
{
if (event == EVENT_LBUTTONDOWN && !drag)
{
if(flag1 == 0)
{
if(var==0)
img1 = img0.clone();
point = Point(x, y);
circle(img1,point,2,Scalar(0, 0, 255),-1, 8, 0);
pts[var] = point;
var++;
drag = 1;
if(var>1)
line(img1,pts[var-2], point, Scalar(0, 0, 255), 2, 8, 0);
imshow("Source", img1);
}
}
if (event == EVENT_LBUTTONUP && drag)
{
imshow("Source", img1);
drag = 0;
}
if (event == EVENT_RBUTTONDOWN)
{
flag1 = 1;
img1 = img0.clone();
for(int i = var; i < numpts ; i++)
pts[i] = point;
if(var!=0)
{
const Point* pts3[1] = {&pts[0]};
polylines( img1, pts3, &numpts,1, 1, Scalar(0,0,0), 2, 8, 0);
}
for(int i=0;i<var;i++)
{
minx = min(minx,pts[i].x);
maxx = max(maxx,pts[i].x);
miny = min(miny,pts[i].y);
maxy = max(maxy,pts[i].y);
}
lenx = maxx - minx;
leny = maxy - miny;
imshow("Source", img1);
}
if (event == EVENT_RBUTTONUP)
{
flag = var;
final = Mat::zeros(img0.size(),CV_8UC3);
res1 = Mat::zeros(img0.size(),CV_8UC1);
const Point* pts4[1] = {&pts[0]};
fillPoly(res1, pts4,&numpts, 1, Scalar(255, 255, 255), 8, 0);
bitwise_and(img0, img0, final,res1);
imshow("mask",res1);
imwrite("mask.png",res1);
imshow("Source", img1);
}
if (event == EVENT_MBUTTONDOWN)
{
for(int i = 0; i < numpts ; i++)
{
pts[i].x=0;
pts[i].y=0;
}
var = 0;
flag1 = 0;
minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN;
imshow("Source", img0);
drag = 0;
}
}
int main(int argc, char **argv)
{
Mat src = imread(argv[1]);
minx = INT_MAX; miny = INT_MAX; maxx = INT_MIN; maxy = INT_MIN;
img0 = src;
channel = img0.channels();
res1 = Mat::zeros(img0.size(),CV_8UC1);
final = Mat::zeros(img0.size(),CV_8UC3);
//////////// source image ///////////////////
namedWindow("Source", 1);
setMouseCallback("Source", mouseHandler, NULL);
imshow("Source", img0);
waitKey(0);
img0.release();
img1.release();
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册