Skip to content
This repository has been archived by the owner on Feb 8, 2023. It is now read-only.

Commit

Permalink
Merge pull request #7 from fishbrain/feature/env-to-control-rekogniti…
Browse files Browse the repository at this point in the history
…on-usage

Control use of Rekognition via env variable
  • Loading branch information
evdokimovn authored Aug 30, 2021
2 parents e2b21f3 + ef0897b commit 7478cf0
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 32 deletions.
9 changes: 8 additions & 1 deletion source/constructs/lib/constructs-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ export class ConstructsStack extends cdk.Stack {
description: 'The name of the default fallback image object key including prefix. e.g. prefix/image.jpg',
default: ''
});
const enableSmartCropRekognition = new CfnParameter(this, 'EnableSmartCropRekognition', {
type: 'String',
description: 'Use Rekognition as an object detection engine when smart cropping',
default: 'No',
allowedValues: ['Yes', 'No']
});

// CFN descrption
this.templateOptions.description = `(SO0023) - Serverless Image Handler with aws-solutions-constructs: This template deploys and configures a serverless architecture that is optimized for dynamic image manipulation and delivery at low latency and cost. Leverages SharpJS for image processing. Template version ${VERSION}`;
Expand Down Expand Up @@ -147,7 +153,8 @@ export class ConstructsStack extends cdk.Stack {
secretsManagerKeyParameter,
enableDefaultFallbackImageParameter,
fallbackImageS3BucketParameter,
fallbackImageS3KeyParameter
fallbackImageS3KeyParameter,
enableSmartCropRekognition
};

// Serverless Image Handler Construct
Expand Down
4 changes: 3 additions & 1 deletion source/constructs/lib/serverless-image-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export interface ServerlessImageHandlerProps {
readonly enableDefaultFallbackImageParameter: CfnParameter;
readonly fallbackImageS3BucketParameter: CfnParameter;
readonly fallbackImageS3KeyParameter: CfnParameter;
readonly enableSmartCropRekognition: CfnParameter;
}

/**
Expand Down Expand Up @@ -181,7 +182,8 @@ export class ServerlessImageHandler extends Construct {
SECRET_KEY: props.secretsManagerKeyParameter.valueAsString,
ENABLE_DEFAULT_FALLBACK_IMAGE: props.enableDefaultFallbackImageParameter.valueAsString,
DEFAULT_FALLBACK_IMAGE_BUCKET: props.fallbackImageS3BucketParameter.valueAsString,
DEFAULT_FALLBACK_IMAGE_KEY: props.fallbackImageS3KeyParameter.valueAsString
DEFAULT_FALLBACK_IMAGE_KEY: props.fallbackImageS3KeyParameter.valueAsString,
ENABLE_SMART_CROP_REKOGNITION: props.enableSmartCropRekognition.valueAsString
}
});
const cfnImageHandlerFunction = imageHandlerFunction.node.defaultChild as cdkLambda.CfnFunction;
Expand Down
12 changes: 12 additions & 0 deletions source/constructs/test/serverless-image-handler-test.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,15 @@
"Type": "String",
"Default": "",
"Description": "The name of the default fallback image object key including prefix. e.g. prefix/image.jpg"
},
"EnableSmartCropRekognition": {
"Type": "String",
"Default": "No",
"AllowedValues": [
"Yes",
"No"
],
"Description": "Use Rekognition as an object detection engine when smart cropping"
}
},
"Mappings": {
Expand Down Expand Up @@ -449,6 +458,9 @@
},
"DEFAULT_FALLBACK_IMAGE_KEY": {
"Ref": "FallbackImageS3Key"
},
"ENABLE_SMART_CROP_REKOGNITION": {
"Ref": "EnableSmartCropRekognition"
}
}
},
Expand Down
66 changes: 36 additions & 30 deletions source/image-handler/image-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,48 +210,54 @@ class ImageHandler {
options.height = cropHeight;
}
options.boost = []
try {
const [faceRekognitionResult, detectLabelsResult] = await Promise.all([this.rekognition.detectFaces({Image: {Bytes: imageBuffer}}).promise(), this.rekognition.detectLabels({Image: {Bytes: imageBuffer}, MinConfidence: 85}).promise()]);
faceRekognitionResult.FaceDetails.forEach(instance => {
if (instance.BoundingBox) {
options.boost.push({
x: instance.BoundingBox.Left * width,
y: instance.BoundingBox.Top * height,
width: instance.BoundingBox.Width * width,
height: instance.BoundingBox.Height * height,
weight: 0.6
})
}
})

for (const l of detectLabelsResult.Labels) {if (l.Name === 'Fish') {
l.Instances.forEach(instance => {
if (process.env.ENABLE_SMART_CROP_REKOGNITION === 'Yes') {
try {
const [faceRekognitionResult, detectLabelsResult] = await Promise.all([this.rekognition.detectFaces({Image: {Bytes: imageBuffer}}).promise(), this.rekognition.detectLabels({
Image: {Bytes: imageBuffer},
MinConfidence: 85
}).promise()]);
faceRekognitionResult.FaceDetails.forEach(instance => {
if (instance.BoundingBox) {
console.log(instance)
options.boost.push({
x: instance.BoundingBox.Left * width,
y: instance.BoundingBox.Top * height,
width: instance.BoundingBox.Width * width,
height: instance.BoundingBox.Height * height,
weight: 1
weight: 0.6
})
}
})
}}

var crop = await smartcrop.crop(imageBuffer, {width: options.width, height: options.height, boost: options.boost})
crop = crop.topCrop;
for (const l of detectLabelsResult.Labels) {
if (l.Name === 'Fish') {
l.Instances.forEach(instance => {
if (instance.BoundingBox) {
console.log(instance)
options.boost.push({
x: instance.BoundingBox.Left * width,
y: instance.BoundingBox.Top * height,
width: instance.BoundingBox.Width * width,
height: instance.BoundingBox.Height * height,
weight: 1
})
}
})
}
}
} catch (err) {
throw {
status: err.statusCode ? err.statusCode : 500,
code: err.code,
message: err.message
};
}
}

return await sharp(imageBuffer)
.extract({width: crop.width, height: crop.height, left: crop.x, top: crop.y}).toBuffer();
var crop = await smartcrop.crop(imageBuffer, {width: options.width, height: options.height, boost: options.boost})
crop = crop.topCrop;

} catch (err) {
throw {
status: err.statusCode ? err.statusCode : 500,
code: err.code,
message: err.message
};
}
return await sharp(imageBuffer)
.extract({width: crop.width, height: crop.height, left: crop.x, top: crop.y}).toBuffer();
}

/**
Expand Down

0 comments on commit 7478cf0

Please sign in to comment.