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

DirectXTex Resize返回空ScratchImage,OpenCV方案遇断言错误求助

问题解决思路

一、DirectXTex返回空Image的排查与修复

1. 必须检查Resize的返回值

DirectXTex的Resize函数返回HRESULT,你完全忽略了错误检查,这是核心问题。如果Resize过程出现错误(比如格式不支持、参数非法),DSResizedImage会处于空状态,此时GetImage(0,0,0)返回空指针,解引用必然出问题。修改代码如下:

DirectX::ScratchImage DSResizedImage;
HRESULT hr = DirectX::Resize(
    *tex->DSImage.GetImage(0, 0, 0),
    tex->scaleX, tex->scaleY,
    DirectX::TEX_FILTER_FLAGS::TEX_FILTER_DEFAULT,
    DSResizedImage
);

if (FAILED(hr)) {
    printf("Resize failed: 0x%08X\n", hr);
    // 这里添加错误处理逻辑,比如返回或终止流程
    return;
}

DirectX::Image* pResized1 = DSResizedImage.GetImage(0, 0, 0);
if (!pResized1) {
    // 极端情况兜底检查
    return;
}
DirectX::Image Resized1 = *pResized1;

2. 处理压缩格式图像

如果输入是压缩DDS格式(比如BC1/BC2/BC3等),DirectXTex的Resize无法直接处理,需要先转换为非压缩格式,再执行Resize,按需转回压缩格式:

// 先转换为非压缩格式
DirectX::ScratchImage tempImage;
hr = DirectX::Convert(
    *tex->DSImage.GetImage(0,0,0),
    DXGI_FORMAT_R8G8B8A8_UNORM,
    DirectX::TEX_FILTER_FLAGS::TEX_FILTER_DEFAULT,
    0.5f,
    tempImage
);
if (FAILED(hr)) { /* 错误处理 */ }

// 对非压缩图像执行Resize
hr = DirectX::Resize(
    *tempImage.GetImage(0,0,0),
    tex->scaleX, tex->scaleY,
    DirectX::TEX_FILTER_FLAGS::TEX_FILTER_DEFAULT,
    DSResizedImage
);
if (FAILED(hr)) { /* 错误处理 */ }

3. 确认目标尺寸参数合法性

DirectX::Resize的第三、第四个参数是目标图像的宽度和高度,不是缩放比例。确保scaleX/scaleY不为0或负数,且是合理的尺寸值。


二、OpenCV断言错误的修复

断言错误的原因是cv::Rect(tex->offsetX, tex->offsetY, tex->scaleX, tex->scaleY)超出了目标矩阵res的边界,本地无法复现是因为你的测试环境res尺寸足够,但部分用户的res尺寸不足或offset参数计算错误。

修复方案:

  1. 增加边界检查:
int roiRight = tex->offsetX + tex->scaleX;
int roiBottom = tex->offsetY + tex->scaleY;

if (tex->offsetX < 0 || tex->offsetY < 0 ||
    tex->scaleX <= 0 || tex->scaleY <= 0 ||
    roiRight > res.cols || roiBottom > res.rows)
{
    printf("ROI out of bounds! res size: %dx%d, ROI: %d,%d %dx%d\n",
        res.cols, res.rows, tex->offsetX, tex->offsetY, tex->scaleX, tex->scaleY);
    return;
}

cvIm.copyTo(res(cv::Rect(tex->offsetX, tex->offsetY, tex->scaleX, tex->scaleY)));
  1. 确保缩放后图像与ROI匹配:
    如果cvIm的原始尺寸和目标ROI尺寸不一致,先缩放再复制,避免隐式缩放带来的边界问题:
cv::Mat scaledIm;
cv::resize(cvIm, scaledIm, cv::Size(tex->scaleX, tex->scaleY));

cv::Rect roi(tex->offsetX, tex->offsetY, scaledIm.cols, scaledIm.rows);
if (!roi.inside(cv::Rect(0,0,res.cols,res.rows))) {
    // 错误处理
    return;
}
scaledIm.copyTo(res(roi));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 00:01:10