You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R+Python开发Shiny调用YOLOv8时yolov8_loader返回NULL求助

解决Shiny应用中调用Python模块返回NULL的问题

问题描述

开发结合R与Python的Shiny应用,需调用基于Python的YOLOv8模型,尝试加载目录下的yolov8_loader.py文件时,yolov8_loader对象始终返回NULL。相关代码及错误情况如下:

原R代码

library(shiny)
library(shinydashboard)
library(rsconnect)
library(tidyverse)
library(reticulate)
library(purrr)
library(stringr)

# Create a py_env environment and install: pip install ultralytics
setwd('C:/Users/IFMT/anaconda3/envs/py_env')
renv::init()
Sys.setenv(RENV_PATHS_CACHE = 'C:/Users/IFMT/anaconda3/envs/py_env')
renv::use_python(type = 'conda', name = 'py_env')
# 

#Create a new Python file, e.g., yolov8_loader.py, with the following content inside the py_env environment:
# import ultralytics as yolo
#
#   def load_model():
#   model = yolo.YOLO("https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt")
# return model

# Load the Python module
yolov8_loader <- source_python("yolov8_loader.py")

# Import the load_model function
load_model <- yolov8_loader$load_model

# Load the model
model <- load_model()

# Define the UI
ui <- fluidPage(
  # App title ----
  titlePanel("Hello YOLOv8!"),
  # Sidebar layout with input and output definitions ----
  sidebarLayout(
    # Sidebar panel for inputs ----
    sidebarPanel(
      # Input: File upload
      fileInput("image_path", label = "Input a JPEG image")
    ),
    # Main panel for displaying outputs ----
    mainPanel(
      # Output: Histogram ----
      textOutput(outputId = "prediction"),
      plotOutput(outputId = "image")
    )
  )
)

# Define server logic required to draw a histogram ----
server <- function(input, output) {
  image <- reactive({
    req(input$image_path)
    jpeg::readJPEG(input$image_path$datapath)
  })
  
  output$prediction <- renderText({
    img <- image() %>% 
      array_reshape(., dim = c(1, dim(.), 1))
    
    # Use the loaded model to make predictions
    prediction <- model(img)
    paste0("The predicted class is ", prediction)
  })
  
  output$image <- renderPlot({
    plot(as.raster(image()))
  })
}

shinyApp(ui, server)

错误情况

运行后yolov8_loader返回:

NULL

解决方案

1. 修正Python环境关联逻辑

renv主要用于R包版本管理,reticulate关联conda环境推荐使用use_condaenv,同时避免将工作目录设置为conda环境目录(会导致脚本找不到Python文件):

# 关联conda环境
library(reticulate)
use_condaenv("py_env", required = TRUE)
# 验证环境是否正确加载
py_config()

执行py_config()后,确认输出中的Python路径指向C:/Users/IFMT/anaconda3/envs/py_env/python.exe。

2. 修复Python文件语法与路径问题

  • 修正yolov8_loader.py的缩进错误:Python对缩进敏感,原代码中函数体内代码未正确缩进,修正后内容如下:
import ultralytics as yolo

def load_model():
    model = yolo.YOLO("https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt")
    return model
  • 确保Python文件路径正确:将yolov8_loader.py放在R脚本的同一目录下,或者使用绝对路径加载:
# 绝对路径示例,替换为你的实际路径
yolov8_loader <- source_python("C:/path/to/your/script/directory/yolov8_loader.py")

3. 调整模型加载时机(避免全局加载失败)

建议将模型加载逻辑放在Shiny的server函数中,避免在应用启动前加载导致的初始化错误:

server <- function(input, output) {
  # 延迟加载模型
  model <- reactive({
    yolov8_loader <- source_python("yolov8_loader.py")
    load_model <- yolov8_loader$load_model
    load_model()
  })
  
  image <- reactive({
    req(input$image_path)
    jpeg::readJPEG(input$image_path$datapath)
  })
  
  output$prediction <- renderText({
    req(model(), image())
    img <- image() %>% 
      array_reshape(., dim = c(1, dim(.), 1))
    
    # 调用模型预测
    prediction <- model()(img)
    # 提取预测结果(YOLOv8返回的结果需要解析,此处示例取第一个结果的类别)
    paste0("The predicted class is ", prediction$names[prediction$boxes$cls[1]+1])
  })
  
  output$image <- renderPlot({
    plot(as.raster(image()))
  })
}

4. 验证Python依赖是否安装

进入py_env环境,确认ultralytics已安装:

conda activate py_env
pip install ultralytics

修正后的完整R代码

library(shiny)
library(tidyverse)
library(reticulate)
library(purrr)

# 关联conda环境
use_condaenv("py_env", required = TRUE)

# Define the UI
ui <- fluidPage(
  titlePanel("Hello YOLOv8!"),
  sidebarLayout(
    sidebarPanel(
      fileInput("image_path", label = "Input a JPEG image")
    ),
    mainPanel(
      textOutput(outputId = "prediction"),
      plotOutput(outputId = "image")
    )
  )
)

# Define server logic
server <- function(input, output) {
  # 延迟加载YOLO模型
  model <- reactive({
    yolov8_loader <- source_python("yolov8_loader.py")
    load_model <- yolov8_loader$load_model
    load_model()
  })
  
  image <- reactive({
    req(input$image_path)
    jpeg::readJPEG(input$image_path$datapath)
  })
  
  output$prediction <- renderText({
    req(model(), image())
    img <- image() %>% 
      array_reshape(., dim = c(1, dim(.), 1))
    
    # 执行预测并解析结果
    prediction_result <- model()(img)
    class_name <- prediction_result$names[[as.integer(prediction_result$boxes$cls[1]) + 1]]
    paste0("The predicted class is ", class_name)
  })
  
  output$image <- renderPlot({
    plot(as.raster(image()))
  })
}

shinyApp(ui, server)

内容的提问来源于stack exchange,提问作者Leprechault

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 20:43:12