我正在使用 OpenCV
在 C++
在屏幕截图和磁盘中的图像之间执行模板匹配。我的屏幕截图似乎有 CV_8UC4
类型但我的模板图像的类型为 CV_8UC3
.这会导致 matchTemplate
获取断言错误的函数:
OpenCV(4.3.0) C:\...\opencv4\src\4.3.0-0c6047baf6.clean\modules\imgproc\src\templmatch.cpp:1104: error: (-215:Assertion failed) (depth == CV_8U || depth == CV_32F) && type == _templ.type() && _img.dims() <= 2 in function 'cv::matchTemplate'
为了解决这个问题,我尝试同时转换 cv::Mat
s 使用 convertTo
转换为相同的类型功能:screen_shot.convertTo(screen_shot, CV_8UC3);
template_image.convertTo(template_image, CV_8UC3);
令人惊讶的是,这“什么都不做”。两者的类型cv::Mat
s 在调用后未修改。为什么?另一个尝试是修改屏幕截图创建代码以生成类型
CV_8UC3
直接地。然而,这使得 GetDIBits()
功能失败:bool dump_window_screen_to_opencv_mat(const HWND window_handle, cv::Mat& output_mat)
{
auto* const h_window_dc = GetDC(window_handle);
auto* const h_window_compatible_dc = CreateCompatibleDC(h_window_dc);
if (!h_window_compatible_dc)
{
return false;
}
if (!SetStretchBltMode(h_window_compatible_dc, COLORONCOLOR))
{
DeleteDC(h_window_compatible_dc);
return false;
}
const auto window_resolution = // ...
const auto loc_window_width = window_resolution.x;
const auto loc_window_height = window_resolution.y;
const auto h_bit_map = CreateCompatibleBitmap(h_window_dc, loc_window_width, loc_window_height);
if (!h_bit_map)
{
DeleteDC(h_window_compatible_dc);
return false;
}
BITMAPINFOHEADER bit_map_info_header;
bit_map_info_header.biSize = sizeof(BITMAPINFOHEADER);
bit_map_info_header.biWidth = loc_window_width;
bit_map_info_header.biHeight = -loc_window_height;
bit_map_info_header.biPlanes = 1;
bit_map_info_header.biBitCount = 32;
bit_map_info_header.biCompression = BI_RGB;
bit_map_info_header.biSizeImage = 0;
bit_map_info_header.biXPelsPerMeter = 0;
bit_map_info_header.biYPelsPerMeter = 0;
bit_map_info_header.biClrUsed = 0;
bit_map_info_header.biClrImportant = 0;
if (!SelectObject(h_window_compatible_dc, h_bit_map))
{
DeleteObject(h_bit_map);
DeleteDC(h_window_compatible_dc);
return false;
}
if (!StretchBlt(
h_window_compatible_dc,
0, 0,
loc_window_width, loc_window_height,
h_window_dc,
0, 0,
loc_window_width, loc_window_height,
SRCCOPY))
{
DeleteObject(h_bit_map);
DeleteDC(h_window_compatible_dc);
return false;
}
output_mat.create(loc_window_height, loc_window_width, CV_8UC4); // <-- Here we can specify the image type
const auto has_di_bits_succeeded = GetDIBits(
h_window_dc,
h_bit_map,
0,
loc_window_height,
output_mat.data,
reinterpret_cast<BITMAPINFO*>(&bit_map_info_header),
DIB_RGB_COLORS);
if (!has_di_bits_succeeded)
{
DeleteObject(h_bit_map);
DeleteDC(h_window_compatible_dc);
return false;
}
DeleteObject(h_bit_map);
DeleteDC(h_window_compatible_dc);
return true;
}
知道如何修复此代码以生成正确的图像类型,或者我可以尝试完全不同的东西吗?在
opencv.org
上查看此相关问题:https://answers.opencv.org/question/236225
最佳答案
在 cv::Mat::convertTo rtype
描述中的规范(第二个参数)它表示它是
desired output matrix type or, rather, the depth since the number of channels are the same as the input has; if rtype is negative, the output matrix will have the same type as the input.
我不确定这是否是问题所在,但找不到任何其他解释。
尝试使用 cv::cvtColor使用适当的 color code ,在您的情况下是
cv::COLOR_xxxA2xxx
之一,很可能是 cv::COLOR_BGRA2BGR
(或 cv::COLOR_RGBA2RGB
无关紧要,因为它们是相等的,并且只删除了 alpha channel )。或者如果您想将 Alpha channel 添加到最适合您的其他图像,则反之亦然。我主要使用它来将图像更改为灰度,如下所示:cv::Mat img_gray, image = imread(argv[1], cv::IMREAD_UNCHANGED);
cv::cvtColor(image, img_gray, cv::COLOR_BGR2GRAY);
关于c++ - 使用 OpenCV 进行模板匹配的图像类型问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64249235/