c ++ opencv在窗口上显示图像

Posted

技术标签:

【中文标题】c ++ opencv在窗口上显示图像【英文标题】:c++ opencv displaying image on a window 【发布时间】:2017-02-13 21:37:26 【问题描述】:

我想使用 OpenCV 加载图像,然后将其显示在窗口上。

我知道如何使用 opencv 加载图像以及如何使用 win32 创建窗口,但是之后如何将 Opencv 中的图像/垫子放在窗口上?

这就是我从 opencv 加载图像的方式:

#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <iostream>
#include <string>
using namespace cv;

using namespace std;

int main(int argc, char** argv)


    string imageName("C:/image.jpg"); // by default
    if (argc > 1)
    
        imageName = argv[1];
    

    Mat image;



    image = imread(imageName.c_str(), IMREAD_COLOR); 


    if (image.empty())     
    
        cout << "Could not open or find the image" << std::endl;
        return -1;
    


    namedWindow("Display window", WINDOW_AUTOSIZE);

    imshow("Display window", image); 


    waitKey(0);
    return 0;

编辑:我想这样做的原因实际上不是在运行时创建一个窗口然后在其上显示图像,而是我想使用 win32 的 FindWindow 函数找到一个窗口,然后在其上绘制一个图像:D

【问题讨论】:

imshow 有什么问题? 没什么,我只是想知道如何在 win32 窗口上显示来自 opencv 的图像 :) 但是……这是一个win32窗口……;) 好吧,老实说这是因为我实际上并不想在程序运行时创建一个新窗口来放置图像。我实际上想使用 win32 的 FindWindow 函数找到一个已经存在的窗口,然后在该窗口上绘图:p 检查how imshow is implemented on windows 【参考方案1】:

我经常在我的 MFC 项目中使用它。如果你只有 hwnd,没有 CWnd,那么你可能需要稍微改变一下。

这适用于 8 位 RGB 颜色和 1 通道单色图像。

    void DrawImage( CWnd *wnd, int width, int height, int bpp, const unsigned char *buffer)

    RECT rect;
    wnd->GetWindowRect(&rect);
    CDC *dc = wnd->GetDC();

    if( bpp == 3) // BGR
    
        BITMAPINFO bmpinfo;

        memset(&bmpinfo, 0, sizeof(bmpinfo));
        bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmpinfo.bmiHeader.biBitCount = 24;
        bmpinfo.bmiHeader.biClrImportant = 0;
        bmpinfo.bmiHeader.biClrUsed = 0;
        bmpinfo.bmiHeader.biCompression = BI_RGB;
        bmpinfo.bmiHeader.biWidth = width;
        bmpinfo.bmiHeader.biHeight = -height;
        bmpinfo.bmiHeader.biPlanes = 1;
        bmpinfo.bmiHeader.biSizeImage = 0;
        bmpinfo.bmiHeader.biXPelsPerMeter = 100;
        bmpinfo.bmiHeader.biYPelsPerMeter = 100;

        ::SetStretchBltMode( dc->GetSafeHdc(), COLORONCOLOR);
        ::StretchDIBits(    dc->GetSafeHdc(),
                        0,
                        0,
                        rect.right - rect.left, 
                        rect.bottom - rect.top,
                        0,
                        0,
                        width,
                        height,
                        buffer,
                        &bmpinfo,
                        DIB_RGB_COLORS,
                        SRCCOPY);
    
    else if ( bpp == 1) // monochrome.
    
        char bitmapInfoBuf[sizeof(BITMAPINFO) + 4 * 256];
        BITMAPINFO* pBmpInfo = (BITMAPINFO*)bitmapInfoBuf;

        memset(pBmpInfo, 0, sizeof(BITMAPINFO) + 4 * 256);
        pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        pBmpInfo->bmiHeader.biWidth = width;
        pBmpInfo->bmiHeader.biHeight = -height;
        pBmpInfo->bmiHeader.biCompression = BI_RGB;
        pBmpInfo->bmiHeader.biPlanes = 1;
        pBmpInfo->bmiHeader.biBitCount = 8;

        for(int i = 0; i < 256; i++)
        
            pBmpInfo->bmiColors[i].rgbBlue=i;
            pBmpInfo->bmiColors[i].rgbGreen=i;
            pBmpInfo->bmiColors[i].rgbRed=i;
            pBmpInfo->bmiColors[i].rgbReserved=255;
        

        ::SetStretchBltMode( dc->GetSafeHdc(), COLORONCOLOR);
        ::StretchDIBits( dc->GetSafeHdc(),
                        0, 
                        0, 
                        rect.right - rect.left, 
                        rect.bottom - rect.top, 
                        0, 
                        0, 
                        width, 
                        height, 
                        buffer, 
                        pBmpInfo, 
                        DIB_RGB_COLORS, 
                        SRCCOPY);
    

    wnd->ReleaseDC(dc);


void DrawCVImage(cv::Mat image, CWnd *picture)

    if (image.cols % 4 == 0)
    
        DrawImage(picture, 
            image.cols, 
            image.rows,
            image.channels() == 3 ? 3 : 1,
            image.data);
    
    else
    
        Mat image2(image.rows, image.cols + ( 4 - image.cols % 4), image.type());
        image2 = 0;
        image.copyTo(image2(Rect(0, 0, image.cols, image.rows)));

        DrawImage(picture, 
            image2.cols, 
            image2.rows,
            image2.channels() == 3 ? 3 : 1,
            image2.data);
    

【讨论】:

【参考方案2】:

嗯……

不要通过调用“namedWindow()”来创建新窗口。

然后拨打imshow(nameOfExistingWindow, image)

也许会起作用。

【讨论】:

谢谢,但我想绘制的窗口实际上没有名字,我只有一个 HWND :(

以上是关于c ++ opencv在窗口上显示图像的主要内容,如果未能解决你的问题,请参考以下文章

无法同时显示五个 Mat 图像(C++、OpenCV)

如何将利用OpenCV加载的图像显示在窗口指定位置

OpenCV下实现单窗口显示多幅图像的C++源码

如何利用openCV函数查看opencv版本

使用 OpenCV 在同一窗口中显示多个图像

OpenCV:自动将窗口大小调整为显示的图像