{
  "id": "opencv/opticalflow-dual-layer-pyramid-failed",
  "signature": "cv::error: (-215:Assertion failed) !_prevImg.empty() && !_nextImg.empty() && prevImg.size() == nextImg.size() in function 'cv::DualTVL1OpticalFlow::calc'",
  "signature_zh": "cv::error: (-215:断言失败) !_prevImg.empty() && !_nextImg.empty() && prevImg.size() == nextImg.size() 在函数 'cv::DualTVL1OpticalFlow::calc' 中",
  "regex": "Assertion failed.*!_prevImg\\.empty\\(\\) && !_nextImg\\.empty\\(\\) && prevImg\\.size\\(\\) == nextImg\\.size\\(\\)",
  "domain": "opencv",
  "category": "assertion_error",
  "subcategory": null,
  "root_cause": "Input images for Dual TV-L1 optical flow are empty or have mismatched dimensions.",
  "root_cause_type": "generic",
  "root_cause_zh": "用于 Dual TV-L1 光流的输入图像为空或尺寸不匹配。",
  "versions": [
    {
      "version": "opencv-4.5.5",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "opencv-4.8.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "opencv-4.9.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    }
  ],
  "os_specific": {},
  "dead_ends": [
    {
      "action": "Convert images to grayscale using cvtColor(src, gray, COLOR_BGR2GRAY)",
      "why_fails": "The Dual TV-L1 algorithm expects single-channel float images, not 3-channel BGR. Grayscale conversion alone does not change dtype to float.",
      "fail_rate": 0.75,
      "condition": "",
      "sources": []
    },
    {
      "action": "Resize both images to the same size using cv::resize(img, img, cv::Size(640, 480))",
      "why_fails": "While size mismatch is checked, the error often arises from empty images due to failed imread, not just size. Resize doesn't fix empty Mat.",
      "fail_rate": 0.6,
      "condition": "",
      "sources": []
    },
    {
      "action": "Set the algorithm parameters to default by creating a new instance",
      "why_fails": "The error is a precondition check on input data, not algorithm configuration. Reinstantiating doesn't address empty or mismatched images.",
      "fail_rate": 0.9,
      "condition": "",
      "sources": []
    }
  ],
  "workarounds": [
    {
      "action": "Ensure both images are loaded successfully and convert to 32-bit float single-channel: cv::Mat prevGray, nextGray; cv::cvtColor(prevFrame, prevGray, cv::COLOR_BGR2GRAY); cv::cvtColor(nextFrame, nextGray, cv::COLOR_BGR2GRAY); prevGray.convertTo(prevGray, CV_32F, 1.0/255.0); nextGray.convertTo(nextGray, CV_32F, 1.0/255.0); Then call calc(prevGray, nextGray, flow).",
      "success_rate": 0.85,
      "how": "Ensure both images are loaded successfully and convert to 32-bit float single-channel: cv::Mat prevGray, nextGray; cv::cvtColor(prevFrame, prevGray, cv::COLOR_BGR2GRAY); cv::cvtColor(nextFrame, nextGray, cv::COLOR_BGR2GRAY); prevGray.convertTo(prevGray, CV_32F, 1.0/255.0); nextGray.convertTo(nextGray, CV_32F, 1.0/255.0); Then call calc(prevGray, nextGray, flow).",
      "condition": "",
      "sources": []
    },
    {
      "action": "Add explicit size check before calling calc: if (prevImg.size() != nextImg.size()) { cv::resize(nextImg, nextImg, prevImg.size()); }",
      "success_rate": 0.75,
      "how": "Add explicit size check before calling calc: if (prevImg.size() != nextImg.size()) { cv::resize(nextImg, nextImg, prevImg.size()); }",
      "condition": "",
      "sources": []
    },
    {
      "action": "Use cv::imread with cv::IMREAD_GRAYSCALE to directly load grayscale images and verify with if (prevImg.empty() || nextImg.empty()) { return; }",
      "success_rate": 0.9,
      "how": "Use cv::imread with cv::IMREAD_GRAYSCALE to directly load grayscale images and verify with if (prevImg.empty() || nextImg.empty()) { return; }",
      "condition": "",
      "sources": []
    }
  ],
  "workarounds_zh": [
    "Ensure both images are loaded successfully and convert to 32-bit float single-channel: cv::Mat prevGray, nextGray; cv::cvtColor(prevFrame, prevGray, cv::COLOR_BGR2GRAY); cv::cvtColor(nextFrame, nextGray, cv::COLOR_BGR2GRAY); prevGray.convertTo(prevGray, CV_32F, 1.0/255.0); nextGray.convertTo(nextGray, CV_32F, 1.0/255.0); Then call calc(prevGray, nextGray, flow).",
    "Add explicit size check before calling calc: if (prevImg.size() != nextImg.size()) { cv::resize(nextImg, nextImg, prevImg.size()); }",
    "Use cv::imread with cv::IMREAD_GRAYSCALE to directly load grayscale images and verify with if (prevImg.empty() || nextImg.empty()) { return; }"
  ],
  "transition_graph": {
    "leads_to": [],
    "preceded_by": [],
    "frequently_confused_with": []
  },
  "official_doc_url": "https://docs.opencv.org/4.x/dc/d6b/classcv_1_1DualTVL1OpticalFlow.html",
  "official_doc_section": null,
  "error_code": null,
  "verification_tier": "ai_generated",
  "confidence": 0.85,
  "fix_success_rate": 0.85,
  "resolvable": "true",
  "first_seen": "2023-05-12",
  "last_confirmed": "2024-06-01",
  "last_updated": "2024-06-01",
  "evidence_count": 1,
  "tags": [],
  "locale": "en",
  "aliases": []
}