opencv assertion_error ai_generated true

cv::error: (-215:Assertion failed) !_prevImg.empty() && !_nextImg.empty() && prevImg.size() == nextImg.size() in function 'cv::DualTVL1OpticalFlow::calc'

ID: opencv/opticalflow-dual-layer-pyramid-failed

Also available as: JSON · Markdown · 中文
85%Fix Rate
85%Confidence
1Evidence
2023-05-12First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
opencv-4.5.5 active
opencv-4.8.0 active
opencv-4.9.0 active

Root Cause

Input images for Dual TV-L1 optical flow are empty or have mismatched dimensions.

generic

中文

用于 Dual TV-L1 光流的输入图像为空或尺寸不匹配。

Official Documentation

https://docs.opencv.org/4.x/dc/d6b/classcv_1_1DualTVL1OpticalFlow.html

Workarounds

  1. 85% success 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).
    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).
  2. 75% success Add explicit size check before calling calc: if (prevImg.size() != nextImg.size()) { cv::resize(nextImg, nextImg, prevImg.size()); }
    Add explicit size check before calling calc: if (prevImg.size() != nextImg.size()) { cv::resize(nextImg, nextImg, prevImg.size()); }
  3. 90% success Use cv::imread with cv::IMREAD_GRAYSCALE to directly load grayscale images and verify with if (prevImg.empty() || nextImg.empty()) { return; }
    Use cv::imread with cv::IMREAD_GRAYSCALE to directly load grayscale images and verify with if (prevImg.empty() || nextImg.empty()) { return; }

中文步骤

  1. 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).
  2. Add explicit size check before calling calc: if (prevImg.size() != nextImg.size()) { cv::resize(nextImg, nextImg, prevImg.size()); }
  3. Use cv::imread with cv::IMREAD_GRAYSCALE to directly load grayscale images and verify with if (prevImg.empty() || nextImg.empty()) { return; }

Dead Ends

Common approaches that don't work:

  1. Convert images to grayscale using cvtColor(src, gray, COLOR_BGR2GRAY) 75% fail

    The Dual TV-L1 algorithm expects single-channel float images, not 3-channel BGR. Grayscale conversion alone does not change dtype to float.

  2. Resize both images to the same size using cv::resize(img, img, cv::Size(640, 480)) 60% fail

    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.

  3. Set the algorithm parameters to default by creating a new instance 90% fail

    The error is a precondition check on input data, not algorithm configuration. Reinstantiating doesn't address empty or mismatched images.