From 36078f9903a14c1f52ebd3de9b67bfacfa1b0c44 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Sat, 6 May 2017 14:46:28 +0100 Subject: [PATCH] Switch to the libvips crop strategy implementations --- docs/changelog.md | 3 + src/operations.cc | 112 ------------------ src/operations.h | 16 --- src/pipeline.cc | 20 ++-- .../expected/crop-strategy-attention.jpg | Bin 0 -> 4514 bytes .../expected/crop-strategy-entropy.jpg | Bin 0 -> 6004 bytes test/fixtures/expected/crop-strategy.jpg | Bin 8715 -> 0 bytes test/unit/crop.js | 20 +--- 8 files changed, 15 insertions(+), 156 deletions(-) create mode 100644 test/fixtures/expected/crop-strategy-attention.jpg create mode 100644 test/fixtures/expected/crop-strategy-entropy.jpg delete mode 100644 test/fixtures/expected/crop-strategy.jpg diff --git a/docs/changelog.md b/docs/changelog.md index 48446e03..7644b1a9 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -22,6 +22,9 @@ Requires libvips v8.5.2. [#607](https://github.com/lovell/sharp/issues/607) [@puzrin](https://github.com/puzrin) +* Switch to the libvips implementation of "attention" and "entropy" crop strategies. + [#727](https://github.com/lovell/sharp/issues/727) + * Improve performance and accuracy of nearest neighbour integral upsampling. [#752](https://github.com/lovell/sharp/issues/752) [@MrIbby](https://github.com/MrIbby) diff --git a/src/operations.cc b/src/operations.cc index 1cfdb02b..274ec911 100644 --- a/src/operations.cc +++ b/src/operations.cc @@ -267,118 +267,6 @@ namespace sharp { } } - /* - Calculate the Shannon entropy - */ - double EntropyStrategy::operator()(VImage image) { - return image.hist_find().hist_entropy(); - } - - /* - Calculate the intensity of edges, skin tone and saturation - */ - double AttentionStrategy::operator()(VImage image) { - // Flatten RGBA onto a mid-grey background - if (image.bands() == 4 && HasAlpha(image)) { - double const midgrey = sharp::Is16Bit(image.interpretation()) ? 32768.0 : 128.0; - std::vector background { midgrey, midgrey, midgrey }; - image = image.flatten(VImage::option()->set("background", background)); - } - // Convert to LAB colourspace - VImage lab = image.colourspace(VIPS_INTERPRETATION_LAB); - VImage l = lab[0]; - VImage a = lab[1]; - VImage b = lab[2]; - // Edge detect luminosity with the Sobel operator - VImage sobel = vips::VImage::new_matrixv(3, 3, - -1.0, 0.0, 1.0, - -2.0, 0.0, 2.0, - -1.0, 0.0, 1.0); - VImage edges = l.conv(sobel).abs() + l.conv(sobel.rot90()).abs(); - // Skin tone chroma thresholds trained with http://humanae.tumblr.com/ - VImage skin = (a >= 3) & (a <= 22) & (b >= 4) & (b <= 31); - // Chroma >~50% saturation - VImage lch = lab.colourspace(VIPS_INTERPRETATION_LCH); - VImage c = lch[1]; - VImage saturation = c > 60; - // Find maximum in combined saliency mask - VImage mask = edges + skin + saturation; - return mask.max(); - } - - /* - Calculate crop area based on image entropy - */ - std::tuple Crop( - VImage image, int const outWidth, int const outHeight, std::function strategy - ) { - int left = 0; - int top = 0; - int const inWidth = image.width(); - int const inHeight = image.height(); - if (inWidth > outWidth) { - // Reduce width by repeated removing slices from edge with lowest score - int width = inWidth; - double leftScore = 0.0; - double rightScore = 0.0; - // Max width of each slice - int const maxSliceWidth = static_cast(ceil((inWidth - outWidth) / 8.0)); - while (width > outWidth) { - // Width of current slice - int const slice = std::min(width - outWidth, maxSliceWidth); - if (leftScore == 0.0) { - // Update score of left slice - leftScore = strategy(image.extract_area(left, 0, slice, inHeight)); - } - if (rightScore == 0.0) { - // Update score of right slice - rightScore = strategy(image.extract_area(width - slice - 1, 0, slice, inHeight)); - } - // Keep slice with highest score - if (leftScore >= rightScore) { - // Discard right slice - rightScore = 0.0; - } else { - // Discard left slice - leftScore = 0.0; - left = left + slice; - } - width = width - slice; - } - } - if (inHeight > outHeight) { - // Reduce height by repeated removing slices from edge with lowest score - int height = inHeight; - double topScore = 0.0; - double bottomScore = 0.0; - // Max height of each slice - int const maxSliceHeight = static_cast(ceil((inHeight - outHeight) / 8.0)); - while (height > outHeight) { - // Height of current slice - int const slice = std::min(height - outHeight, maxSliceHeight); - if (topScore == 0.0) { - // Update score of top slice - topScore = strategy(image.extract_area(0, top, inWidth, slice)); - } - if (bottomScore == 0.0) { - // Update score of bottom slice - bottomScore = strategy(image.extract_area(0, height - slice - 1, inWidth, slice)); - } - // Keep slice with highest score - if (topScore >= bottomScore) { - // Discard bottom slice - bottomScore = 0.0; - } else { - // Discard top slice - topScore = 0.0; - top = top + slice; - } - height = height - slice; - } - } - return std::make_tuple(left, top); - } - /* Insert a tile cache to prevent over-computation of any previous operations in the pipeline */ diff --git a/src/operations.h b/src/operations.h index 66836e77..529bca44 100644 --- a/src/operations.h +++ b/src/operations.h @@ -72,22 +72,6 @@ namespace sharp { */ VImage Sharpen(VImage image, double const sigma, double const flat, double const jagged); - /* - Crop strategy functors - */ - struct EntropyStrategy { - double operator()(VImage image); - }; - struct AttentionStrategy { - double operator()(VImage image); - }; - - /* - Calculate crop area based on given strategy (Entropy, Attention) - */ - std::tuple Crop( - VImage image, int const outWidth, int const outHeight, std::function strategy); - /* Insert a tile cache to prevent over-computation of any previous operations in the pipeline */ diff --git a/src/pipeline.cc b/src/pipeline.cc index f31540cb..47c50772 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -509,24 +509,20 @@ class PipelineWorker : public Nan::AsyncWorker { ->set("background", background)); } else if (baton->canvas != Canvas::IGNORE_ASPECT) { // Crop/max/min - int left; - int top; if (baton->crop < 9) { // Gravity-based crop + int left; + int top; std::tie(left, top) = sharp::CalculateCrop( image.width(), image.height(), baton->width, baton->height, baton->crop); - } else if (baton->crop == 16) { - // Entropy-based crop - std::tie(left, top) = sharp::Crop(image, baton->width, baton->height, sharp::EntropyStrategy()); + int width = std::min(image.width(), baton->width); + int height = std::min(image.height(), baton->height); + image = image.extract_area(left, top, width, height); } else { - // Attention-based crop - std::tie(left, top) = sharp::Crop(image, baton->width, baton->height, sharp::AttentionStrategy()); + // Attention-based or Entropy-based crop + image = image.smartcrop(baton->width, baton->height, VImage::option() + ->set("interesting", baton->crop == 16 ? VIPS_INTERESTING_ENTROPY : VIPS_INTERESTING_ATTENTION)); } - int width = std::min(image.width(), baton->width); - int height = std::min(image.height(), baton->height); - image = image.extract_area(left, top, width, height); - baton->cropCalcLeft = left; - baton->cropCalcTop = top; } } diff --git a/test/fixtures/expected/crop-strategy-attention.jpg b/test/fixtures/expected/crop-strategy-attention.jpg new file mode 100644 index 0000000000000000000000000000000000000000..16ddaa166b6958c5c764ea253bc137e85d63a0d2 GIT binary patch literal 4514 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 Z+DT!xq|Ewujf*E1VRlD-=0fdq;XfHp9LfLy literal 0 HcmV?d00001 diff --git a/test/fixtures/expected/crop-strategy-entropy.jpg b/test/fixtures/expected/crop-strategy-entropy.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8f236071a1e082209b87c1e452298d57d36871c6 GIT binary patch literal 6004 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 IZeP#-55>baZvX%Q literal 0 HcmV?d00001 diff --git a/test/fixtures/expected/crop-strategy.jpg b/test/fixtures/expected/crop-strategy.jpg deleted file mode 100644 index af12e8a37989445a0b316cb22744311d3316bbcd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8715 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 zΝOc?27=I=nFEAkvjb+lSG%Fn3KiD z)t(2y(z8`gs%Bi7z^G#VC?Wt-oFk?hPO5n9x^WZ)eu-gZ{f@<3W<2Z=n{~2xsefH9 zSD)zep+}%=r%ALaB@Rsj)?7Mcz0M;-V7$sET+^8|84Z7;yz$-A5qw8Xz^2IgCx9`H zdkC9gqB{ZMGBbqnlv~T|nO+4qtpyq7Uv@LKPe=BQi5%|Z7{6lXrIwG*NV|(wS5t}` L6zT&w?-&0Eknni$ diff --git a/test/unit/crop.js b/test/unit/crop.js index b8087a3a..9a5a2759 100644 --- a/test/unit/crop.js +++ b/test/unit/crop.js @@ -161,7 +161,7 @@ describe('Crop', function () { describe('Entropy-based strategy', function () { it('JPEG', function (done) { - sharp(fixtures.inputJpgWithCmykProfile) + sharp(fixtures.inputJpg) .resize(80, 320) .crop(sharp.strategy.entropy) .toBuffer(function (err, data, info) { @@ -170,9 +170,7 @@ describe('Crop', function () { assert.strictEqual(3, info.channels); assert.strictEqual(80, info.width); assert.strictEqual(320, info.height); - assert.strictEqual(250, info.cropCalcLeft); - assert.strictEqual(0, info.cropCalcTop); - fixtures.assertSimilar(fixtures.expected('crop-strategy.jpg'), data, done); + fixtures.assertSimilar(fixtures.expected('crop-strategy-entropy.jpg'), data, done); }); }); @@ -186,8 +184,6 @@ describe('Crop', function () { assert.strictEqual(4, info.channels); assert.strictEqual(320, info.width); assert.strictEqual(80, info.height); - assert.strictEqual(0, info.cropCalcLeft); - assert.strictEqual(80, info.cropCalcTop); fixtures.assertSimilar(fixtures.expected('crop-strategy.png'), data, done); }); }); @@ -202,8 +198,6 @@ describe('Crop', function () { assert.strictEqual(4, info.channels); assert.strictEqual(320, info.width); assert.strictEqual(80, info.height); - assert.strictEqual(0, info.cropCalcLeft); - assert.strictEqual(80, info.cropCalcTop); fixtures.assertSimilar(fixtures.expected('crop-strategy.png'), data, done); }); }); @@ -211,7 +205,7 @@ describe('Crop', function () { describe('Attention strategy', function () { it('JPEG', function (done) { - sharp(fixtures.inputJpgWithCmykProfile) + sharp(fixtures.inputJpg) .resize(80, 320) .crop(sharp.strategy.attention) .toBuffer(function (err, data, info) { @@ -220,9 +214,7 @@ describe('Crop', function () { assert.strictEqual(3, info.channels); assert.strictEqual(80, info.width); assert.strictEqual(320, info.height); - assert.strictEqual(250, info.cropCalcLeft); - assert.strictEqual(0, info.cropCalcTop); - fixtures.assertSimilar(fixtures.expected('crop-strategy.jpg'), data, done); + fixtures.assertSimilar(fixtures.expected('crop-strategy-attention.jpg'), data, done); }); }); @@ -236,8 +228,6 @@ describe('Crop', function () { assert.strictEqual(4, info.channels); assert.strictEqual(320, info.width); assert.strictEqual(80, info.height); - assert.strictEqual(0, info.cropCalcLeft); - assert.strictEqual(80, info.cropCalcTop); fixtures.assertSimilar(fixtures.expected('crop-strategy.png'), data, done); }); }); @@ -252,8 +242,6 @@ describe('Crop', function () { assert.strictEqual(4, info.channels); assert.strictEqual(320, info.width); assert.strictEqual(80, info.height); - assert.strictEqual(0, info.cropCalcLeft); - assert.strictEqual(80, info.cropCalcTop); fixtures.assertSimilar(fixtures.expected('crop-strategy.png'), data, done); }); });