## -----------------------------------------------------------------------------
#| label: setup
library(kuzco)
library(purrr)
library(mirai)


## -----------------------------------------------------------------------------
#| include: FALSE

# download a set of dog pictures: 
url <- "https://github.com/laxmimerit/dog-cat-full-dataset/tree/master/data/test/dogs/"

raw <- "https://raw.githubusercontent.com/laxmimerit/dog-cat-full-dataset/master/data/test/dogs/"
dog_api <- "https://api.github.com/repos/laxmimerit/dog-cat-full-dataset/contents/data/test/dogs/"


res <- httr::GET(dog_api)
files_info <- jsonlite::fromJSON(rawToChar(res$content))
image_list <- files_info$name[grepl("\\.(jpg|jpeg|png)$", files_info$name, ignore.case = TRUE)]


# let's just grab ~ 20 for demonstration purposes
image_urls <- paste0(raw, image_list[2:22])


## -----------------------------------------------------------------------------
#| include: FALSE

image_files <- purrr::map_chr(image_urls, ~ tempfile(fileext = ".jpg"))
map2(image_urls, image_files, ~ download.file(.x, .y, mode = "wget"))


## -----------------------------------------------------------------------------

mirai::daemons(20, .compute = "gpu")
llm_results <- purrr::map(image_files, 
                          purrr::in_parallel(\(img) kuzco::llm_image_classification(image = img)))
mirai::daemons(0)



## -----------------------------------------------------------------------------
odin <- system.file("img/test_img.jpg", package = "kuzco")
kuzco::view_image(odin)


## -----------------------------------------------------------------------------

vision_workflow <- \(img){
  
  qwen_classifier <- kuzco::llm_image_classification(
    image = img,
    llm_model = "qwen2.5vl",
    backend = 'ellmer'
  )
  
  pixtral_classifier <- kuzco::llm_image_classification(
    image = img,
    llm_model = "pixtral-12b",
    provider = 'mistral',
    backend = 'ellmer'
  )
  
  pixtral_sentiment <- kuzco::llm_image_sentiment(
    image = img,
    llm_model = "pixtral-12b",
    provider = 'mistral',
    backend = "ellmer"
  )
}

mirai::daemons(20, .compute = "gpu")
llm_results <- purrr::map(odin, 
                          purrr::in_parallel(\(img) vision_workflow(image = img)))
mirai::daemons(0)



## -----------------------------------------------------------------------------
# Written by Mete Akcaoglu, edited by Frank Hull
# https://github.com/meteakca
# https://github.com/frankiethull/kuzco/issues/22#issuecomment-2957159732

process_image <- function(img_path) {
  # Classification
  classification <- llm_image_classification(
    llm_model = "qwen2.5vl",
    image = img_path,
    backend = 'ellmer'
  )
  
  # Object detection (e.g., detecting people)
  detection <- llm_image_recognition(
    llm_model = "qwen2.5vl",
    image = img_path,
    recognize_object = "dogs",
    backend = 'ellmer'
  )
  
  # Return as tibble
  tibble::tibble(
    file = img_path,
    image_classification = classification$image_classification,
    primary_object = classification$primary_object,
    secondary_object = classification$secondary_object,
    image_description = classification$image_description,
    image_colors = classification$image_colors,
    image_proba_names = paste(unlist(classification$image_proba_names), collapse = ", "),
    image_proba_values = paste(unlist(classification$image_proba_values), collapse = ", "),
    object_recognized = detection$object_recognized,
    object_count = detection$object_count,
    object_description = detection$object_description,
    object_location = detection$object_location
  )
}

tictoc::tic()
# Apply to all images and combine into one data frame
results_df <- map_dfr(image_files, process_image)
tictoc::toc()


## -----------------------------------------------------------------------------
tictoc::tic()
mirai::daemons(20, .compute = "gpu")
results_df <- map_dfr(image_files, 
                      purrr::in_parallel(\(img) process_image(img_path = jmg)))
mirai::daemons(0)
tictoc::toc()


## -----------------------------------------------------------------------------
tictoc::tic()
image_tasks <- list(classify  = kuzco::llm_image_classification,
                    sentiment = kuzco::llm_image_sentiment
                    )

grid <- expand.grid(files = image_files, tasks = image_tasks)

mirai::daemons(20, .compute = "gpu")
llm_results <- purrr::map2(as.character(grid$files), 
                           grid$tasks,
                           purrr::in_parallel(\(img, task) (task(image = img))))
mirai::daemons(0)
tictoc::toc()

