babalae/better-genshin-impact · critical · FileNotFoundException

预热图片未找到: {modelType.PreHeatImagePath}

Error message

预热图片未找到: {modelType.PreHeatImagePath}

What it means

The PaddleOcrService constructor warm-starts the detection and recognition pipeline by running OCR on a bundled test PNG (test_pp_ocr.png, or test_pp_ocr_number.png for the V4 English model). Bv.ImRead returns null when the image cannot be read, and the null-coalesce throws FileNotFoundException, aborting construction so OCR is entirely unavailable.

Source

Thrown at BetterGenshinImpact/Core/Recognition/OCR/Paddle/PaddleOcrService.cs:257

                return V4;
            }
            else
            {
                return v5;
            }
        }
    }

    public PaddleOcrService(BgiOnnxFactory bgiOnnxFactory, PaddleOcrModelType modelType)
    {
        var (modelsDet, modelsRec) = modelType.Build(bgiOnnxFactory);
        _localDetModel = modelsDet;
        _localRecModel = modelsRec;

        // 预热模型
        using var preHeatImageMat = Bv.ImRead(modelType.PreHeatImagePath) ??
                                    throw new FileNotFoundException($"预热图片未找到: {modelType.PreHeatImagePath}");
        // Debug输出结果
        var preHeatResult = RunAll(preHeatImageMat, 1);
        Debug.WriteLine(
            $"PaddleOcrService 预热完成,使用模型: {modelType.DetectionModel.Name} 和 {modelType.RecognitionModel.Name},结果: {preHeatResult.Text}");
    }

    /// <summary>
    ///     推荐传入三通道BGR mat,虽然四通道和单通道也做了兼容,但是三通道最快
    /// </summary>
    public string Ocr(Mat mat)
    {
        return OcrResult(mat).Text;
    }

    /// <summary>
    ///     推荐传入三通道BGR mat,虽然四通道和单通道也做了兼容,但是三通道最快
    /// </summary>
    public OcrResult OcrResult(Mat mat)

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Restore test_pp_ocr.png (and test_pp_ocr_number.png) under Assets\Model\PaddleOCR\.
  2. Verify Global.Absolute(modelType.PreHeatImagePath) returns the expected absolute path.
  3. Build the model type with Create(..., preHeatImagePath: <valid path>) to point at an existing image.
  4. Check the image is not locked by another process and the build copies it to the output directory.

Example fix

// before: preheat image missing -> constructor throws
new PaddleOcrService(factory, modelType);

// after: guard the preheat path
if (!File.Exists(modelType.PreHeatImagePath))
    throw new InvalidOperationException($"Preheat image missing: {modelType.PreHeatImagePath}");
new PaddleOcrService(factory, modelType);
Defensive patterns

Strategy: validation

Validate before calling

bool IsPreheatImageAvailable(PaddleOcrModelType modelType)
    => File.Exists(modelType.PreHeatImagePath);

if (!IsPreheatImageAvailable(modelType))
    throw new InvalidOperationException($"PaddleOCR preheat image missing: {modelType.PreHeatImagePath}");

Try / catch

try
{
    _ocr = new PaddleOcrService(factory, modelType);
}
catch (FileNotFoundException ex) when (ex.Message.Contains("预热图片未找到"))
{
    Logger.LogError("Preheat image missing: {Path}", modelType.PreHeatImagePath);
    throw;
}

Prevention

When it happens

Trigger: Calling new PaddleOcrService(factory, modelType) when modelType.PreHeatImagePath (default Assets\Model\PaddleOCR\test_pp_ocr.png) does not exist or is not readable as an image.

Common situations: Preheat asset trimmed from the build output; image renamed; Global.Absolute resolving against the wrong working directory; file locked or permission denied; corrupt PNG.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/2dae704043d2dd0f. Report an issue: GitHub.