mirror of
https://github.com/lovell/sharp.git
synced 2025-12-19 07:15:08 +01:00
Add support to normalise for lower and upper percentiles (#3583)
This commit is contained in:
committed by
Lovell Fuller
parent
1eefd4e562
commit
d7776e3b98
@@ -6,7 +6,6 @@
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include <vips/vips8>
|
||||
|
||||
#include "common.h"
|
||||
@@ -46,7 +45,7 @@ namespace sharp {
|
||||
/*
|
||||
* Stretch luminance to cover full dynamic range.
|
||||
*/
|
||||
VImage Normalise(VImage image) {
|
||||
VImage Normalise(VImage image, int const lower, int const upper) {
|
||||
// Get original colourspace
|
||||
VipsInterpretation typeBeforeNormalize = image.interpretation();
|
||||
if (typeBeforeNormalize == VIPS_INTERPRETATION_RGB) {
|
||||
@@ -56,9 +55,11 @@ namespace sharp {
|
||||
VImage lab = image.colourspace(VIPS_INTERPRETATION_LAB);
|
||||
// Extract luminance
|
||||
VImage luminance = lab[0];
|
||||
|
||||
// Find luminance range
|
||||
int const min = luminance.percent(1);
|
||||
int const max = luminance.percent(99);
|
||||
int const min = lower == 0 ? luminance.min() : luminance.percent(lower);
|
||||
int const max = upper == 100 ? luminance.max() : luminance.percent(upper);
|
||||
|
||||
if (std::abs(max - min) > 1) {
|
||||
// Extract chroma
|
||||
VImage chroma = lab.extract_band(1, VImage::option()->set("n", 2));
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace sharp {
|
||||
/*
|
||||
* Stretch luminance to cover full dynamic range.
|
||||
*/
|
||||
VImage Normalise(VImage image);
|
||||
VImage Normalise(VImage image, int const lower, int const upper);
|
||||
|
||||
/*
|
||||
* Contrast limiting adapative histogram equalization (CLAHE)
|
||||
|
||||
@@ -74,6 +74,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
VipsAngle autoRotation = VIPS_ANGLE_D0;
|
||||
bool autoFlip = FALSE;
|
||||
bool autoFlop = FALSE;
|
||||
|
||||
if (baton->useExifOrientation) {
|
||||
// Rotate and flip image according to Exif orientation
|
||||
std::tie(autoRotation, autoFlip, autoFlop) = CalculateExifRotationAndFlip(sharp::ExifOrientation(image));
|
||||
@@ -682,7 +683,7 @@ class PipelineWorker : public Napi::AsyncWorker {
|
||||
|
||||
// Apply normalisation - stretch luminance to cover full dynamic range
|
||||
if (baton->normalise) {
|
||||
image = sharp::Normalise(image);
|
||||
image = sharp::Normalise(image, baton->normaliseLower, baton->normaliseUpper);
|
||||
}
|
||||
|
||||
// Apply contrast limiting adaptive histogram equalization (CLAHE)
|
||||
@@ -1483,6 +1484,8 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
||||
baton->linearB = sharp::AttrAsVectorOfDouble(options, "linearB");
|
||||
baton->greyscale = sharp::AttrAsBool(options, "greyscale");
|
||||
baton->normalise = sharp::AttrAsBool(options, "normalise");
|
||||
baton->normaliseLower = sharp::AttrAsUint32(options, "normaliseLower");
|
||||
baton->normaliseUpper = sharp::AttrAsUint32(options, "normaliseUpper");
|
||||
baton->tintA = sharp::AttrAsDouble(options, "tintA");
|
||||
baton->tintB = sharp::AttrAsDouble(options, "tintB");
|
||||
baton->claheWidth = sharp::AttrAsUint32(options, "claheWidth");
|
||||
|
||||
@@ -99,6 +99,8 @@ struct PipelineBaton {
|
||||
double gammaOut;
|
||||
bool greyscale;
|
||||
bool normalise;
|
||||
int normaliseLower;
|
||||
int normaliseUpper;
|
||||
int claheWidth;
|
||||
int claheHeight;
|
||||
int claheMaxSlope;
|
||||
@@ -262,6 +264,8 @@ struct PipelineBaton {
|
||||
gamma(0.0),
|
||||
greyscale(false),
|
||||
normalise(false),
|
||||
normaliseLower(1),
|
||||
normaliseUpper(99),
|
||||
claheWidth(0),
|
||||
claheHeight(0),
|
||||
claheMaxSlope(3),
|
||||
|
||||
Reference in New Issue
Block a user