OpenCV convertToD3D11Texture2D 函数导致访问冲突
OpenCV convertToD3D11Texture2D function causes access violation
我正在创建一个 C++ Windows 应用程序,它使用 DirectX 在 HDR 中显示 PPM 图像。我正在使用 cv::imread
将文件读入 Mat
,然后创建一个 ID3D11Texture2D*
纹理。但是,当我 运行 它在 运行ning cv::directx::convertToD3D11Texture2D(mat, tex)
时出现访问冲突,它说 tex
是 NULL
。
根据我的理解,CreateTexture2D
初始化纹理,convertToD3D11Texture2D
将图像复制到纹理。
这是相关代码:
auto mat = cv::imread("fileL.ppm", cv::IMREAD_ANYCOLOR | cv::IMREAD_ANYDEPTH);
D3D11_TEXTURE2D_DESC desc;
desc.Width = 3840;
desc.Height = 2160;
desc.MipLevels = desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
ID3D11Texture2D* tex = nullptr;
m_resources->GetDevice()->CreateTexture2D(&desc, nullptr, &tex);
cv::directx::convertToD3D11Texture2D(mat, tex);
具体错误是:
0x00007FFC4750A839 in file.exe: Microsoft C++ exception: _com_error at memory location 0x00000045A28FF340.
Exception thrown at 0x00007FFBCD08A390 (opencv_world410d.dll) in file.exe: 0xC0000005: Access violation reading location 0x0000000000000000.
编辑:添加 desc.SampleDesc.quality = 0
后,我不再收到 CreateTexture2D
的错误,但我在 convertToD3D11Texture2D:
处收到一般异常Exception at memory location 0x0000002A3836E8D0
编辑2:缓存异常后,异常信息为:
OpenCV(4.1.0) c:\build\master_winpack-build-win64-vc15\opencv\modules\core\src\directx.cpp:1040: error: (-215:Assertion failed) textureType == srcType in function 'cv::directx::__convertToD3D11Texture2DNV'
终于能够正确调试错误后,我发现问题是由于我的输入矩阵有 3 个通道,而不是 4 个。为了修复它,我使用 cv::mixChannels
添加一个空的 alpha 通道,所以现在我的纹理类型和矩阵匹配。
工作代码:
cv::Mat mat = cv::imread("file.ppm", cv::IMREAD_ANYCOLOR | cv::IMREAD_ANYDEPTH);
cv::Mat as4channelMat(mat.size(), CV_MAKE_TYPE(mat.depth(), 4));
int conversion[] = { 0, 0, 1, 1, 2, 2, -1, 3 };
cv::mixChannels(&mat, 1, &as4channelMat, 1, conversion, 4);
D3D11_TEXTURE2D_DESC desc;
desc.Width = 3840;
desc.Height = 2160;
desc.MipLevels = desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R16G16B16A16_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
ID3D11Texture2D* tex = nullptr;
auto hr = m_resources->GetDevice()->CreateTexture2D(&desc, nullptr, &tex);
if FAILED(hr)
{
_com_error err(hr);
LPCTSTR errMsg = err.ErrorMessage();
}
try {
cv::directx::convertToD3D11Texture2D(as4channelMat, tex);
} catch (cv::Exception& e)
{
std::cerr << "ERROR: " << e.msg << std::endl;
throw e;
}
我正在创建一个 C++ Windows 应用程序,它使用 DirectX 在 HDR 中显示 PPM 图像。我正在使用 cv::imread
将文件读入 Mat
,然后创建一个 ID3D11Texture2D*
纹理。但是,当我 运行 它在 运行ning cv::directx::convertToD3D11Texture2D(mat, tex)
时出现访问冲突,它说 tex
是 NULL
。
根据我的理解,CreateTexture2D
初始化纹理,convertToD3D11Texture2D
将图像复制到纹理。
这是相关代码:
auto mat = cv::imread("fileL.ppm", cv::IMREAD_ANYCOLOR | cv::IMREAD_ANYDEPTH);
D3D11_TEXTURE2D_DESC desc;
desc.Width = 3840;
desc.Height = 2160;
desc.MipLevels = desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DYNAMIC;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = 0;
ID3D11Texture2D* tex = nullptr;
m_resources->GetDevice()->CreateTexture2D(&desc, nullptr, &tex);
cv::directx::convertToD3D11Texture2D(mat, tex);
具体错误是:
0x00007FFC4750A839 in file.exe: Microsoft C++ exception: _com_error at memory location 0x00000045A28FF340.
Exception thrown at 0x00007FFBCD08A390 (opencv_world410d.dll) in file.exe: 0xC0000005: Access violation reading location 0x0000000000000000.
编辑:添加 desc.SampleDesc.quality = 0
后,我不再收到 CreateTexture2D
的错误,但我在 convertToD3D11Texture2D:
处收到一般异常Exception at memory location 0x0000002A3836E8D0
编辑2:缓存异常后,异常信息为:
OpenCV(4.1.0) c:\build\master_winpack-build-win64-vc15\opencv\modules\core\src\directx.cpp:1040: error: (-215:Assertion failed) textureType == srcType in function 'cv::directx::__convertToD3D11Texture2DNV'
终于能够正确调试错误后,我发现问题是由于我的输入矩阵有 3 个通道,而不是 4 个。为了修复它,我使用 cv::mixChannels
添加一个空的 alpha 通道,所以现在我的纹理类型和矩阵匹配。
工作代码:
cv::Mat mat = cv::imread("file.ppm", cv::IMREAD_ANYCOLOR | cv::IMREAD_ANYDEPTH);
cv::Mat as4channelMat(mat.size(), CV_MAKE_TYPE(mat.depth(), 4));
int conversion[] = { 0, 0, 1, 1, 2, 2, -1, 3 };
cv::mixChannels(&mat, 1, &as4channelMat, 1, conversion, 4);
D3D11_TEXTURE2D_DESC desc;
desc.Width = 3840;
desc.Height = 2160;
desc.MipLevels = desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R16G16B16A16_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = 0;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
desc.MiscFlags = 0;
ID3D11Texture2D* tex = nullptr;
auto hr = m_resources->GetDevice()->CreateTexture2D(&desc, nullptr, &tex);
if FAILED(hr)
{
_com_error err(hr);
LPCTSTR errMsg = err.ErrorMessage();
}
try {
cv::directx::convertToD3D11Texture2D(as4channelMat, tex);
} catch (cv::Exception& e)
{
std::cerr << "ERROR: " << e.msg << std::endl;
throw e;
}