mirror of
https://github.com/ImageMagick/ImageMagick.git
synced 2026-06-12 15:37:14 +02:00
...
This commit is contained in:
@@ -341,7 +341,6 @@ static const OptionInfo
|
||||
{ " normalize", 0, UndefinedOptionFlag, MagickFalse },
|
||||
{ " opaque", 0, UndefinedOptionFlag, MagickFalse },
|
||||
{ " ordered-dither", 0, UndefinedOptionFlag, MagickFalse },
|
||||
{ " otsu-threshold", 0, UndefinedOptionFlag, MagickFalse },
|
||||
{ " paint", 0, UndefinedOptionFlag, MagickFalse },
|
||||
{ " posterize", 0, UndefinedOptionFlag, MagickFalse },
|
||||
{ " raise", 0, UndefinedOptionFlag, MagickFalse },
|
||||
@@ -895,8 +894,6 @@ static const OptionInfo
|
||||
{ "-ordered-dither", 1L, SimpleOperatorFlag, MagickFalse },
|
||||
{ "+orient", 0L, ImageInfoOptionFlag, MagickFalse },
|
||||
{ "-orient", 1L, ImageInfoOptionFlag, MagickFalse },
|
||||
{ "+otsu-threshold", 0L, DeprecateOptionFlag | FireOptionFlag, MagickTrue },
|
||||
{ "-otsu-threshold", 0L, ListOperatorFlag | FireOptionFlag, MagickFalse },
|
||||
{ "+page", 0L, ImageInfoOptionFlag, MagickFalse },
|
||||
{ "-page", 1L, ImageInfoOptionFlag, MagickFalse },
|
||||
{ "+paint", 0L, DeprecateOptionFlag, MagickTrue },
|
||||
|
||||
@@ -1836,164 +1836,6 @@ MagickExport MagickBooleanType OrderedDitherImage(Image *image,
|
||||
% %
|
||||
% %
|
||||
% %
|
||||
% O T S U T h r e s h o l d I m a g e %
|
||||
% %
|
||||
% %
|
||||
% %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% OTSUThresholdImage() automatically performs clustering-based image
|
||||
% thresholding. The algorithm calculates the optimum threshold separates into
|
||||
% two classes so that their combined spread (intra-class variance) is minimal,
|
||||
% and their inter-class variance is maximal.
|
||||
%
|
||||
% The format of the OTSUThresholdImage method is:
|
||||
%
|
||||
% MagickBooleanType OTSUThresholdImage(Image *image,
|
||||
% ExceptionInfo *exception)
|
||||
%
|
||||
% A description of each parameter follows:
|
||||
%
|
||||
% o image: the image.
|
||||
%
|
||||
% o exception: return any errors or warnings in this structure.
|
||||
%
|
||||
*/
|
||||
MagickExport MagickBooleanType OTSUThresholdImage(Image *image,
|
||||
ExceptionInfo *exception)
|
||||
{
|
||||
#define ThresholdImageTag "Threshold/Image"
|
||||
|
||||
CacheView
|
||||
*image_view;
|
||||
|
||||
GeometryInfo
|
||||
geometry_info;
|
||||
|
||||
MagickBooleanType
|
||||
status;
|
||||
|
||||
MagickOffsetType
|
||||
progress;
|
||||
|
||||
PixelInfo
|
||||
threshold;
|
||||
|
||||
MagickStatusType
|
||||
flags;
|
||||
|
||||
ssize_t
|
||||
y;
|
||||
|
||||
assert(image != (Image *) NULL);
|
||||
assert(image->signature == MagickCoreSignature);
|
||||
if (image->debug != MagickFalse)
|
||||
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
|
||||
if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
|
||||
return(MagickFalse);
|
||||
if (IsGrayColorspace(image->colorspace) != MagickFalse)
|
||||
(void) TransformImageColorspace(image,sRGBColorspace,exception);
|
||||
GetPixelInfo(image,&threshold);
|
||||
flags=ParseGeometry("100",&geometry_info);
|
||||
threshold.red=geometry_info.rho;
|
||||
threshold.green=geometry_info.rho;
|
||||
threshold.blue=geometry_info.rho;
|
||||
threshold.black=geometry_info.rho;
|
||||
threshold.alpha=100.0;
|
||||
if ((flags & SigmaValue) != 0)
|
||||
threshold.green=geometry_info.sigma;
|
||||
if ((flags & XiValue) != 0)
|
||||
threshold.blue=geometry_info.xi;
|
||||
if ((flags & PsiValue) != 0)
|
||||
threshold.alpha=geometry_info.psi;
|
||||
if (threshold.colorspace == CMYKColorspace)
|
||||
{
|
||||
if ((flags & PsiValue) != 0)
|
||||
threshold.black=geometry_info.psi;
|
||||
if ((flags & ChiValue) != 0)
|
||||
threshold.alpha=geometry_info.chi;
|
||||
}
|
||||
if ((flags & PercentValue) != 0)
|
||||
{
|
||||
threshold.red*=(MagickRealType) (QuantumRange/100.0);
|
||||
threshold.green*=(MagickRealType) (QuantumRange/100.0);
|
||||
threshold.blue*=(MagickRealType) (QuantumRange/100.0);
|
||||
threshold.black*=(MagickRealType) (QuantumRange/100.0);
|
||||
threshold.alpha*=(MagickRealType) (QuantumRange/100.0);
|
||||
}
|
||||
/*
|
||||
OTSU threshold image.
|
||||
*/
|
||||
status=MagickTrue;
|
||||
progress=0;
|
||||
image_view=AcquireAuthenticCacheView(image,exception);
|
||||
#if defined(MAGICKCORE_OPENMP_SUPPORT)
|
||||
#pragma omp parallel for schedule(static) shared(progress,status) \
|
||||
magick_number_threads(image,image,image->rows,1)
|
||||
#endif
|
||||
for (y=0; y < (ssize_t) image->rows; y++)
|
||||
{
|
||||
register ssize_t
|
||||
x;
|
||||
|
||||
register Quantum
|
||||
*magick_restrict q;
|
||||
|
||||
if (status == MagickFalse)
|
||||
continue;
|
||||
q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
|
||||
if (q == (Quantum *) NULL)
|
||||
{
|
||||
status=MagickFalse;
|
||||
continue;
|
||||
}
|
||||
for (x=0; x < (ssize_t) image->columns; x++)
|
||||
{
|
||||
double
|
||||
pixel;
|
||||
|
||||
register ssize_t
|
||||
i;
|
||||
|
||||
pixel=GetPixelIntensity(image,q);
|
||||
for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
|
||||
{
|
||||
PixelChannel channel = GetPixelChannelChannel(image,i);
|
||||
PixelTrait traits = GetPixelChannelTraits(image,channel);
|
||||
if ((traits & UpdatePixelTrait) == 0)
|
||||
continue;
|
||||
if (image->channel_mask != DefaultChannels)
|
||||
pixel=(double) q[i];
|
||||
if (pixel > GetPixelInfoChannel(&threshold,channel))
|
||||
q[i]=QuantumRange;
|
||||
}
|
||||
q+=GetPixelChannels(image);
|
||||
}
|
||||
if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
|
||||
status=MagickFalse;
|
||||
if (image->progress_monitor != (MagickProgressMonitor) NULL)
|
||||
{
|
||||
MagickBooleanType
|
||||
proceed;
|
||||
|
||||
#if defined(MAGICKCORE_OPENMP_SUPPORT)
|
||||
#pragma omp atomic
|
||||
#endif
|
||||
progress++;
|
||||
proceed=SetImageProgress(image,ThresholdImageTag,progress,image->rows);
|
||||
if (proceed == MagickFalse)
|
||||
status=MagickFalse;
|
||||
}
|
||||
}
|
||||
image_view=DestroyCacheView(image_view);
|
||||
return(status);
|
||||
}
|
||||
|
||||
/*
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% %
|
||||
% %
|
||||
% %
|
||||
% P e r c e p t i b l e I m a g e %
|
||||
% %
|
||||
% %
|
||||
|
||||
@@ -48,7 +48,6 @@ extern MagickExport MagickBooleanType
|
||||
ClampImage(Image *,ExceptionInfo *),
|
||||
ListThresholdMaps(FILE *,ExceptionInfo *),
|
||||
OrderedDitherImage(Image *,const char *,ExceptionInfo *),
|
||||
OTSUThresholdImage(Image *,ExceptionInfo *),
|
||||
PerceptibleImage(Image *,const double,ExceptionInfo *),
|
||||
RandomThresholdImage(Image *,const double,const double,ExceptionInfo *),
|
||||
RangeThresholdImage(Image *,const double,const double,const double,
|
||||
|
||||
@@ -7559,42 +7559,6 @@ WandExport MagickBooleanType MagickOrderedDitherImage(MagickWand *wand,
|
||||
% %
|
||||
% %
|
||||
% %
|
||||
% M a g i c k O T S U T h r e s h o l d I m a g e %
|
||||
% %
|
||||
% %
|
||||
% %
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%
|
||||
% MagickOTSUThresholdImage() automatically performs clustering-based image
|
||||
% thresholding. The algorithm calculates the optimum threshold separates into
|
||||
% two classes so that their combined spread (intra-class variance) is minimal,
|
||||
% and their inter-class variance is maximal.
|
||||
%
|
||||
% The format of the MagickOTSUThresholdImage method is:
|
||||
%
|
||||
% MagickBooleanType MagickOTSUThresholdImage(MagickWand *wand)
|
||||
%
|
||||
% A description of each parameter follows:
|
||||
%
|
||||
% o wand: the magick wand.
|
||||
%
|
||||
*/
|
||||
WandExport MagickBooleanType MagickOTSUThresholdImage(MagickWand *wand)
|
||||
{
|
||||
assert(wand != (MagickWand *) NULL);
|
||||
assert(wand->signature == MagickWandSignature);
|
||||
if (wand->debug != MagickFalse)
|
||||
(void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
|
||||
if (wand->images == (Image *) NULL)
|
||||
ThrowWandException(WandError,"ContainsNoImages",wand->name);
|
||||
return(OTSUThresholdImage(wand->images,wand->exception));
|
||||
}
|
||||
|
||||
/*
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
% %
|
||||
% %
|
||||
% %
|
||||
% M a g i c k P i n g I m a g e %
|
||||
% %
|
||||
% %
|
||||
|
||||
@@ -208,7 +208,6 @@ extern WandExport MagickBooleanType
|
||||
const double,const MagickBooleanType),
|
||||
MagickOptimizeImageTransparency(MagickWand *),
|
||||
MagickOrderedDitherImage(MagickWand *,const char *),
|
||||
MagickOTSUThresholdImage(MagickWand *),
|
||||
MagickTransparentPaintImage(MagickWand *,const PixelWand *,
|
||||
const double,const double,const MagickBooleanType invert),
|
||||
MagickPingImage(MagickWand *,const char *),
|
||||
|
||||
@@ -2336,12 +2336,6 @@ WandExport MagickBooleanType MogrifyImage(ImageInfo *image_info,const int argc,
|
||||
(void) OrderedDitherImage(*image,argv[i+1],exception);
|
||||
break;
|
||||
}
|
||||
if (LocaleCompare("otsu-threshold",option+1) == 0)
|
||||
{
|
||||
(void) SyncImageSettings(mogrify_info,*image,exception);
|
||||
(void) OTSUThresholdImage(*image,exception);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'p':
|
||||
@@ -5629,8 +5623,6 @@ WandExport MagickBooleanType MogrifyImageCommand(ImageInfo *image_info,
|
||||
argv[i]);
|
||||
break;
|
||||
}
|
||||
if (LocaleCompare("otsu-threshold",option+1) == 0)
|
||||
break;
|
||||
ThrowMogrifyException(OptionError,"UnrecognizedOption",option)
|
||||
}
|
||||
case 'p':
|
||||
|
||||
@@ -2895,11 +2895,6 @@ static MagickBooleanType CLISimpleOperatorImage(MagickCLI *cli_wand,
|
||||
(void) OrderedDitherImage(_image,arg1,_exception);
|
||||
break;
|
||||
}
|
||||
if (LocaleCompare("otsu-threshold",option+1) == 0)
|
||||
{
|
||||
(void) OTSUThresholdImage(_image,_exception);
|
||||
break;
|
||||
}
|
||||
CLIWandExceptionBreak(OptionError,"UnrecognizedOption",option);
|
||||
}
|
||||
case 'p':
|
||||
|
||||
@@ -575,7 +575,6 @@ static struct
|
||||
{ "CLAHE", { {"geometry", StringReference}, {"width", IntegerReference},
|
||||
{"height", IntegerReference}, {"number-bins", IntegerReference},
|
||||
{"clip-limit", RealReference} } },
|
||||
{ "OTSUThreshold", { {"channel", MagickChannelOptions} } },
|
||||
};
|
||||
|
||||
static SplayTreeInfo
|
||||
@@ -7648,8 +7647,6 @@ Mogrify(ref,...)
|
||||
RangeThresholdImage= 296
|
||||
CLAHE = 297
|
||||
CLAHEImage = 298
|
||||
OTSUThreshold = 299
|
||||
OTSUThresholdImage = 300
|
||||
MogrifyRegion = 666
|
||||
PPCODE:
|
||||
{
|
||||
@@ -11504,16 +11501,6 @@ Mogrify(ref,...)
|
||||
geometry_info.psi,exception);
|
||||
break;
|
||||
}
|
||||
case 150: /* OTSUThreshold */
|
||||
{
|
||||
if (attribute_flag[0] != 0)
|
||||
channel=(ChannelType) argument_list[0].integer_reference;
|
||||
channel_mask=SetImageChannelMask(image,channel);
|
||||
(void) OTSUThresholdImage(image,exception);
|
||||
if (image != (Image *) NULL)
|
||||
(void) SetImageChannelMask(image,channel_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (next != (Image *) NULL)
|
||||
(void) CatchImageException(next);
|
||||
|
||||
@@ -575,7 +575,6 @@ static struct
|
||||
{ "CLAHE", { {"geometry", StringReference}, {"width", IntegerReference},
|
||||
{"height", IntegerReference}, {"number-bins", IntegerReference},
|
||||
{"clip-limit", RealReference} } },
|
||||
{ "OTSUThreshold", { {"channel", MagickChannelOptions} } },
|
||||
};
|
||||
|
||||
static SplayTreeInfo
|
||||
@@ -7647,8 +7646,6 @@ Mogrify(ref,...)
|
||||
RangeThresholdImage= 296
|
||||
CLAHE = 297
|
||||
CLAHEImage = 298
|
||||
OTSUThreshold = 299
|
||||
OTSUThresholdImage = 300
|
||||
MogrifyRegion = 666
|
||||
PPCODE:
|
||||
{
|
||||
@@ -11510,16 +11507,6 @@ Mogrify(ref,...)
|
||||
geometry_info.psi,exception);
|
||||
break;
|
||||
}
|
||||
case 150: /* OTSUThreshold */
|
||||
{
|
||||
if (attribute_flag[0] != 0)
|
||||
channel=(ChannelType) argument_list[0].integer_reference;
|
||||
channel_mask=SetImageChannelMask(image,channel);
|
||||
(void) OTSUThresholdImage(image,exception);
|
||||
if (image != (Image *) NULL)
|
||||
(void) SetImageChannelMask(image,channel_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (next != (Image *) NULL)
|
||||
(void) CatchImageException(next);
|
||||
|
||||
+2
-1
@@ -1058,7 +1058,8 @@ static Image *ReadSIXELImage(const ImageInfo *image_info,ExceptionInfo *exceptio
|
||||
if (sixel_decode(image,(unsigned char *) sixel_buffer,&sixel_pixels,&image->columns,&image->rows,&sixel_palette,&image->colors,exception) == MagickFalse)
|
||||
{
|
||||
sixel_buffer=(char *) RelinquishMagickMemory(sixel_buffer);
|
||||
sixel_pixels=(unsigned char *) RelinquishMagickMemory(sixel_pixels);
|
||||
if (sixel_pixels != (unsigned char *) NULL)
|
||||
sixel_pixels=(unsigned char *) RelinquishMagickMemory(sixel_pixels);
|
||||
ThrowReaderException(CorruptImageError,"CorruptImage");
|
||||
}
|
||||
sixel_buffer=(char *) RelinquishMagickMemory(sixel_buffer);
|
||||
|
||||
Reference in New Issue
Block a user