defmodule ItsfoundRekognition.ImageLabelParser do @moduledoc """ """ require Logger @filter_by 90 @doc """ this parses will parse the rekognition result (1) first by filtering out results above a threshold - here we default to 90% (2) then by pulling out just the label `name` and `confidence` fields The results should look like this: [ %{match: 99.46314239501953, name: "Outdoors"}, %{match: 99.45779418945313, name: "Nature"}, %{match: 99.23141479492188, name: "Scenery"}, %{match: 98.38043212890625, name: "Green"}, %{match: 97.57438659667969, name: "Landscape"}, %{match: 91.14559936523438, name: "Land"} ] """ def parse(labels, log_func \\ &no_log_result/1) def parse(%{"LabelModelVersion" => _version, "Labels" => labels}, log_func) do parsed = labels |> parse_labels_for_name(@filter_by) |> log_func.() {:ok, parsed} end def parse(_, log_func) do message = "invalid response from aws rekognition" log_func.(message) {:error, message} end def parse_top(labels, log_func \\ &no_log_result/1) def parse_top(%{"LabelModelVersion" => _version, "Labels" => labels}, log_func) do parsed = labels |> parse_labels_for_name(@filter_by) |> select_top() |> log_func.() {:ok, parsed} end def parse_top(_, log_func) do message = "invalid response from aws rekognition" log_func.(message) {:error, message} end def parse_labels_for_name(labels, filter \\ 90) do labels |> filter_labels(filter) |> Enum.map(fn l -> %{"Name" => name, "Confidence" => confidence} = l %{name: name, match: confidence} end) end def log_result(result) do Logger.info("\n Parse AWS Rekognition label results: \n") Logger.info(inspect(result)) Logger.info("\n DONE \n") result end def no_log_result(result), do: result def select_top([]), do: nil def select_top(labels) do [top | _] = labels top end defp filter_labels(labels, filter) do labels |> Enum.filter(fn l -> %{"Confidence" => confidence} = l confidence >= filter end) end end