c++ - 使用 OpenCV 进行模板匹配的图像类型问题

标签 c++ windows opencv winapi visual-c++

我正在使用 OpenCVC++在屏幕截图和磁盘中的图像之间执行模板匹配。我的屏幕截图似乎有 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/

相关文章:

c++ - 如何导出 std::vector

.net - 标准 C++ 中的垃圾收集是自动的吗?

windows - 带有 "autopush"的 Git 客户端?

python - 在pygame Windows中播放声音时出现问题

python - 边距

visual-studio-2010 - opencv 特征检测器因未处理的异常错误而崩溃

c# - 在二维 ORPG 中保存 map 数据

windows - Git 管理的文件中出现外来字符

c++ - OpenCV IDFT 有奇怪的噪音和高通滤波器结果似乎是错误的

c++ - 在构造函数的初始化列表上初始化数组或 vector