I was wanting to brainstorm some simple ideas for ML/Vision type experiments. One of the first I came up with is that we take a whole lot of pictures with Tulip, so I thought - It would be useful to check if the image was blurry. Actually maybe this would be useful to be built into the camera widget itself
First off, what are your ideas for simple, very foundational ML/Vision/LLM experiments to try?
I wanted to play with a bit of the opencv vision library, and use it for basic blur detection. This is what I came up with.
First up, trying to get a lambda layer for opencv
This guy has a video on it https://www.youtube.com/watch?v=Y2rWypy8OaM
Or, you can get a pre built one from here
I think you need to use opencv-python-headless-4.6.0.66.zip since 4.7 throws a opencv-aws-lambda-lib64-libz-so-1-version-zlib-1-2-9-not-found
And then why you are at it, create an imutils layer. I think the easiest method is the ec2 micro method with How to Create a Python Layer in Aws Lambda | by Rafael Campana | BRLink | Medium
Ok, so how do we figure out if an image is blurry or not? Luckily, this guy knows how
variation of the Laplacian
Make a little lambda function (add your lambda layers)
59 import
boto3
import
logging
import
urllib3
import
os
import
numpy as np
import
argparse
import
cv2
import
json
# Configure Logger
logger
=
logging.getLogger()
logger.setLevel(logging.DEBUG)
# AWS Runtime Region
aws_runtime_region
=
os.environ[
'AWS_REGION'
]
# Argument Parsing
arg_parser
=
argparse.ArgumentParser()
arg_parser.add_argument(
"-t"
,
"--threshold"
,
type
=
float
, default
=
100.0
,
help
=
"focus measures below this value are considered 'blurry'"
)
cmd_args
=
vars
(arg_parser.parse_args())
def
compute_laplacian_variance(image):
return
cv2.Laplacian(image, cv2.CV_64F).var()
def
download_image(url):
http_client
=
urllib3.PoolManager()
try
:
response
=
http_client.request(
'GET'
, url)
image_data
=
np.asarray(bytearray(response.data), dtype
=
"uint8"
)
return
cv2.imdecode(image_data, cv2.IMREAD_COLOR)
except
Exception as error:
logger.error(f
"Error in downloading image: {error}"
)
return
None
def
lambda_handler(event, context):
logger.debug(f
"Event: {event}"
)
image_url
=
event.get(
"url"
)
if
not
image_url:
return
{
'statusCode'
:
400
,
'body'
: json.dumps({
'error'
:
'No URL provided'
})}
image
=
download_image(image_url)
if
image
is
None
or
not
image.size:
return
{
'statusCode'
:
400
,
'body'
: json.dumps({
'error'
:
'Failed to download image'
})}
gray_image
=
cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
laplacian_variance
=
compute_laplacian_variance(gray_image)
logger.debug(f
"Laplacian Variance: {laplacian_variance}"
)
is_blurry
=
laplacian_variance < cmd_args[
"threshold"
]
is_blurry
=
bool
(is_blurry)
if
is_blurry:
logger.debug(
"Image is blurry."
)
else
:
logger.debug(
"Image is not blurry."
)
return
{
'statusCode'
:
200
,
'body'
: {
'is_blurry'
: is_blurry}}
Create permissions, and then a postgres function to call it
CREATE
OR
REPLACE
FUNCTION
public
.check_image_for_blur(url text)
RETURNS
boolean
LANGUAGE plpgsql
AS
$
function
$
declare
create_json TEXT;
response TEXT;
is_blurry_boolean boolean;
begin
RAISE INFO
'Started'
;
-- Create Json
select
into
create_json row_to_json(t)
from
(
select
url
) t;
SELECT
into
response payload
FROM
aws_lambda.invoke(aws_commons.create_lambda_function_arn(
'check-image-for-blur'
,
'us-east-1'
),
create_json::json,
'RequestResponse'
);
RAISE INFO
'response:%'
,response;
-- Parse the response to get is_blurry
select
into
is_blurry_boolean (response::json->
'body'
->>
'is_blurry'
)::boolean;
-- Return the is_blurry boolean value
return
is_blurry_boolean;
end
;
$
function
$
;
Make your tulip function (use image_url as the input)
Then a trigger off a camera widget