Add contrast limiting adaptive histogram equalization (CLAHE) operator (#2726)

This commit is contained in:
Brad Parham
2021-05-23 18:36:04 +02:00
committed by GitHub
parent b69a54fc75
commit 4b6b6189bf
19 changed files with 245 additions and 6 deletions

View File

@@ -92,6 +92,13 @@ namespace sharp {
return image;
}
/*
* Contrast limiting adapative histogram equalization (CLAHE)
*/
VImage Clahe(VImage image, int const width, int const height, int const maxSlope) {
return image.hist_local(width, height, VImage::option()->set("max_slope", maxSlope));
}
/*
* Gamma encoding/decoding
*/

View File

@@ -35,6 +35,11 @@ namespace sharp {
*/
VImage Normalise(VImage image);
/*
* Contrast limiting adapative histogram equalization (CLAHE)
*/
VImage Clahe(VImage image, int const width, int const height, int const maxSlope);
/*
* Gamma encoding/decoding
*/

View File

@@ -345,6 +345,7 @@ class PipelineWorker : public Napi::AsyncWorker {
bool const shouldApplyMedian = baton->medianSize > 0;
bool const shouldComposite = !baton->composite.empty();
bool const shouldModulate = baton->brightness != 1.0 || baton->saturation != 1.0 || baton->hue != 0.0;
bool const shouldApplyClahe = baton->claheWidth != 0 && baton->claheHeight != 0;
if (shouldComposite && !sharp::HasAlpha(image)) {
image = sharp::EnsureAlpha(image, 1);
@@ -650,6 +651,11 @@ class PipelineWorker : public Napi::AsyncWorker {
image = sharp::Normalise(image);
}
// Apply contrast limiting adaptive histogram equalization (CLAHE)
if (shouldApplyClahe) {
image = sharp::Clahe(image, baton->claheWidth, baton->claheHeight, baton->claheMaxSlope);
}
// Apply bitwise boolean operation between images
if (baton->boolean != nullptr) {
VImage booleanImage;
@@ -1330,6 +1336,9 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
baton->linearB = sharp::AttrAsDouble(options, "linearB");
baton->greyscale = sharp::AttrAsBool(options, "greyscale");
baton->normalise = sharp::AttrAsBool(options, "normalise");
baton->claheWidth = sharp::AttrAsUint32(options, "claheWidth");
baton->claheHeight = sharp::AttrAsUint32(options, "claheHeight");
baton->claheMaxSlope = sharp::AttrAsUint32(options, "claheMaxSlope");
baton->useExifOrientation = sharp::AttrAsBool(options, "useExifOrientation");
baton->angle = sharp::AttrAsInt32(options, "angle");
baton->rotationAngle = sharp::AttrAsDouble(options, "rotationAngle");

View File

@@ -109,6 +109,9 @@ struct PipelineBaton {
double gammaOut;
bool greyscale;
bool normalise;
int claheWidth;
int claheHeight;
int claheMaxSlope;
bool useExifOrientation;
int angle;
double rotationAngle;
@@ -234,6 +237,9 @@ struct PipelineBaton {
gamma(0.0),
greyscale(false),
normalise(false),
claheWidth(0),
claheHeight(0),
claheMaxSlope(3),
useExifOrientation(false),
angle(0),
rotationAngle(0.0),