This commit is contained in:
cristy
2013-03-25 11:30:44 +00:00
parent 09dbb823cd
commit 3afd4014cd
11 changed files with 155 additions and 40 deletions
+2 -2
View File
@@ -440,8 +440,8 @@ int main( int /*argc*/, char ** argv)
cout << " unsharp mask ..." << endl;
example = model;
example.label( "Unsharp Mask" );
// radius_, sigma_, gain_
example.unsharpmask( 0.0, 1.0, 1.0);
// radius_, sigma_, amount_, threshold_
example.unsharpmask( 0.0, 1.0, 1.0, 0.05);
images.push_back( example );
cout << " wave ..." << endl;
+8 -4
View File
@@ -2282,7 +2282,8 @@ void Magick::Image::trim ( void )
// the threshold in pixels needed to apply the diffence amount.
void Magick::Image::unsharpmask ( const double radius_,
const double sigma_,
const double gain_ )
const double amount_,
const double threshold_ )
{
ExceptionInfo exceptionInfo;
GetExceptionInfo( &exceptionInfo );
@@ -2290,7 +2291,8 @@ void Magick::Image::unsharpmask ( const double radius_,
UnsharpMaskImage( image(),
radius_,
sigma_,
gain_,
amount_,
threshold_,
&exceptionInfo );
replaceImage( newImage );
throwException( exceptionInfo );
@@ -2300,7 +2302,8 @@ void Magick::Image::unsharpmask ( const double radius_,
void Magick::Image::unsharpmaskChannel ( const ChannelType channel_,
const double radius_,
const double sigma_,
const double gain_ )
const double amount_,
const double threshold_ )
{
ExceptionInfo exceptionInfo;
GetExceptionInfo( &exceptionInfo );
@@ -2309,7 +2312,8 @@ void Magick::Image::unsharpmaskChannel ( const ChannelType channel_,
UnsharpMaskImage( image(),
radius_,
sigma_,
gain_,
amount_,
threshold_,
&exceptionInfo );
(void) SetPixelChannelMask( image(), channel_mask );
replaceImage( newImage );
+7 -5
View File
@@ -259,7 +259,7 @@ namespace Magick
void crop ( const Geometry &geometry_ );
// Cycle image colormap
void cycleColormap ( const ::ssize_t gain_ );
void cycleColormap ( const ::ssize_t amount_ );
// Despeckle image (reduce speckle noise)
void despeckle ( void );
@@ -640,7 +640,7 @@ namespace Magick
void splice ( const Geometry &geometry_ );
// Spread pixels randomly within image by specified ammount
void spread ( const size_t gain_ = 3 );
void spread ( const size_t amount_ = 3 );
// Sparse color image, given a set of coordinates, interpolates the colors
// found at those coordinates, across the whole image, using various
@@ -700,18 +700,20 @@ namespace Magick
// center pixel.
// sigma_
// the standard deviation of the Gaussian, in pixels.
// gain_
// amount_
// the percentage of the difference between the original and
// the blur image that is added back into the original.
// threshold_
// the threshold in pixels needed to apply the diffence amount.
void unsharpmask ( const double radius_,
const double sigma_,
const double gain_ );
const double amount_,
const double threshold_ );
void unsharpmaskChannel ( const ChannelType channel_,
const double radius_,
const double sigma_,
const double gain_ );
const double amount_,
const double threshold_ );
// Map image pixels to a sine wave
void wave ( const double amplitude_ = 25.0,
+2 -1
View File
@@ -389,12 +389,13 @@ namespace Magick
class MagickPPExport edgeImage : public std::unary_function<Image&,void>
{
public:
edgeImage( const double radius_ = 0.0 );
edgeImage( const double radius_ = 0.0, const double sigma_ = 0.5 );
void operator()( Image &image_ ) const;
private:
double _radius;
double _sigma;
};
// Emboss image (hilight edges with 3D effect)
+117 -18
View File
@@ -3325,7 +3325,8 @@ MagickExport Image *SpreadImage(const Image *image,const double radius,
% The format of the UnsharpMaskImage method is:
%
% Image *UnsharpMaskImage(const Image *image,const double radius,
% const double sigma,const double gain,ExceptionInfo *exception)
% const double sigma,const double amount,const double threshold,
% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
@@ -3339,37 +3340,135 @@ MagickExport Image *SpreadImage(const Image *image,const double radius,
% o gain: the percentage of the difference between the original and the
% blur image that is added back into the original.
%
% o threshold: the threshold in pixels needed to apply the diffence gain.
%
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport Image *UnsharpMaskImage(const Image *image,const double radius,
const double sigma,const double gain,ExceptionInfo *exception)
const double sigma,const double gain,const double threshold,
ExceptionInfo *exception)
{
char
geometry[MaxTextExtent];
#define SharpenImageTag "Sharpen/Image"
KernelInfo
*kernel_info;
CacheView
*image_view,
*unsharp_view;
Image
*unsharp_image;
MagickBooleanType
status;
MagickOffsetType
progress;
double
quantum_threshold;
ssize_t
y;
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickSignature);
(void) FormatLocaleString(geometry,MaxTextExtent,"Blur:%.20gx%.20g>",
radius,sigma);
kernel_info=AcquireKernelInfo(geometry);
if (kernel_info == (KernelInfo *) NULL)
ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
(void) FormatLocaleString(geometry,MaxTextExtent,"%.20g,%.20g%%",
-100.0+gain*100.0,200.0-gain*100.0);
ScaleGeometryKernelInfo(kernel_info,geometry);
unsharp_image=MorphologyImage(image,ConvolveMorphology,1,kernel_info,
exception);
kernel_info=DestroyKernelInfo(kernel_info);
unsharp_image=BlurImage(image,radius,sigma,exception);
if (unsharp_image == (Image *) NULL)
return((Image *) NULL);
quantum_threshold=(double) QuantumRange*threshold;
/*
Unsharp-mask image.
*/
status=MagickTrue;
progress=0;
image_view=AcquireVirtualCacheView(image,exception);
unsharp_view=AcquireAuthenticCacheView(unsharp_image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp parallel for schedule(static,4) shared(progress,status) \
magick_threads(image,unsharp_image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
register const Quantum
*restrict p;
register Quantum
*restrict q;
register ssize_t
x;
if (status == MagickFalse)
continue;
p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
q=QueueCacheViewAuthenticPixels(unsharp_view,0,y,unsharp_image->columns,1,
exception);
if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
{
status=MagickFalse;
continue;
}
for (x=0; x < (ssize_t) image->columns; x++)
{
register ssize_t
i;
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
{
double
pixel;
PixelChannel
channel;
PixelTrait
traits,
unsharp_traits;
channel=GetPixelChannelChannel(image,i);
traits=GetPixelChannelTraits(image,channel);
unsharp_traits=GetPixelChannelTraits(unsharp_image,channel);
if ((traits == UndefinedPixelTrait) ||
(unsharp_traits == UndefinedPixelTrait))
continue;
if (((unsharp_traits & CopyPixelTrait) != 0) ||
(GetPixelMask(image,p) != 0))
{
SetPixelChannel(unsharp_image,channel,p[i],q);
continue;
}
pixel=p[i]-(double) GetPixelChannel(unsharp_image,channel,q);
if (fabs(2.0*pixel) < quantum_threshold)
pixel=(double) p[i];
else
pixel=(double) p[i]+gain*pixel;
SetPixelChannel(unsharp_image,channel,ClampToQuantum(pixel),q);
}
p+=GetPixelChannels(image);
q+=GetPixelChannels(unsharp_image);
}
if (SyncCacheViewAuthenticPixels(unsharp_view,exception) == MagickFalse)
status=MagickFalse;
if (image->progress_monitor != (MagickProgressMonitor) NULL)
{
MagickBooleanType
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp critical (MagickCore_UnsharpMaskImage)
#endif
proceed=SetImageProgress(image,SharpenImageTag,progress++,image->rows);
if (proceed == MagickFalse)
status=MagickFalse;
}
}
unsharp_image->type=image->type;
unsharp_view=DestroyCacheView(unsharp_view);
image_view=DestroyCacheView(image_view);
if (status == MagickFalse)
unsharp_image=DestroyImage(unsharp_image);
return(unsharp_image);
}
+1 -1
View File
@@ -80,7 +80,7 @@ extern MagickExport Image
*SpreadImage(const Image *,const double,const PixelInterpolateMethod,
ExceptionInfo *),
*UnsharpMaskImage(const Image *,const double,const double,const double,
ExceptionInfo *);
const double,ExceptionInfo *);
#if defined(__cplusplus) || defined(c_plusplus)
}
+7 -3
View File
@@ -11925,7 +11925,8 @@ WandExport MagickBooleanType MagickUniqueImageColors(MagickWand *wand)
% The format of the MagickUnsharpMaskImage method is:
%
% MagickBooleanType MagickUnsharpMaskImage(MagickWand *wand,
% const double radius,const double sigma,const double gain)
% const double radius,const double sigma,const double gain,
% const double threshold)
%
% A description of each parameter follows:
%
@@ -11939,9 +11940,12 @@ WandExport MagickBooleanType MagickUniqueImageColors(MagickWand *wand)
% o gain: the percentage of the difference between the original and the
% blur image that is added back into the original.
%
% o threshold: the threshold in pixels needed to apply the diffence gain.
%
*/
WandExport MagickBooleanType MagickUnsharpMaskImage(MagickWand *wand,
const double radius,const double sigma,const double gain)
const double radius,const double sigma,const double gain,
const double threshold)
{
Image
*unsharp_image;
@@ -11952,7 +11956,7 @@ WandExport MagickBooleanType MagickUnsharpMaskImage(MagickWand *wand,
(void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
if (wand->images == (Image *) NULL)
ThrowWandException(WandError,"ContainsNoImages",wand->name);
unsharp_image=UnsharpMaskImage(wand->images,radius,sigma,gain,
unsharp_image=UnsharpMaskImage(wand->images,radius,sigma,gain,threshold,
wand->exception);
if (unsharp_image == (Image *) NULL)
return(MagickFalse);
+2 -1
View File
@@ -304,7 +304,8 @@ extern WandExport MagickBooleanType
MagickThumbnailImage(MagickWand *,const size_t,const size_t),
MagickTrimImage(MagickWand *,const double),
MagickUniqueImageColors(MagickWand *),
MagickUnsharpMaskImage(MagickWand *,const double,const double,const double),
MagickUnsharpMaskImage(MagickWand *,const double,const double,const double,
const double),
MagickVignetteImage(MagickWand *,const double,const double,const ssize_t,
const ssize_t),
MagickWaveImage(MagickWand *,const double,const double,
+2 -1
View File
@@ -3046,7 +3046,8 @@ WandExport MagickBooleanType MogrifyImage(ImageInfo *image_info,const int argc,
if ((flags & PsiValue) == 0)
geometry_info.psi=0.05;
mogrify_image=UnsharpMaskImage(*image,geometry_info.rho,
geometry_info.sigma,geometry_info.xi,exception);
geometry_info.sigma,geometry_info.xi,geometry_info.psi,
exception);
break;
}
break;
+1 -1
View File
@@ -3336,7 +3336,7 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
if ((flags & PsiValue) == 0)
geometry_info.psi=0.05;
new_image=UnsharpMaskImage(_image,geometry_info.rho,
geometry_info.sigma,geometry_info.xi,_exception);
geometry_info.sigma,geometry_info.xi,geometry_info.psi,_exception);
break;
}
CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
+6 -3
View File
@@ -390,7 +390,8 @@ static struct
{ "black-point-compensation", MagickBooleanOptions} } },
{ "UnsharpMask", { {"geometry", StringReference},
{"radius", RealReference}, {"sigma", RealReference},
{"gain", RealReference}, {"channel", MagickChannelOptions} } },
{"gain", RealReference}, {"threshold", RealReference},
{"channel", MagickChannelOptions} } },
{ "MotionBlur", { {"geometry", StringReference},
{"radius", RealReference}, {"sigma", RealReference},
{"angle", RealReference}, {"channel", MagickChannelOptions} } },
@@ -9487,10 +9488,12 @@ Mogrify(ref,...)
if (attribute_flag[3] != 0)
geometry_info.xi=argument_list[3].real_reference;
if (attribute_flag[4] != 0)
channel=(ChannelType) argument_list[4].integer_reference;
geometry_info.psi=argument_list[4].real_reference;
if (attribute_flag[5] != 0)
channel=(ChannelType) argument_list[5].integer_reference;
channel_mask=SetImageChannelMask(image,channel);
image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
geometry_info.xi,exception);
geometry_info.xi,geometry_info.psi,exception);
if (image != (Image *) NULL)
(void) SetImageChannelMask(image,channel_mask);
break;