首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >OpenCV -关闭图像显示窗口

OpenCV -关闭图像显示窗口
EN

Stack Overflow用户
提问于 2012-01-13 05:53:36
回答 9查看 77.9K关注 0票数 21

我正在做一个通过图像数据库进行搜索的项目,当我找到一些查询数据库图像的结果时,我想直观地显示结果。我没有将所有的图像保存在内存中,所以我必须先加载图像才能显示它。

我有一个简单的想法,用伪代码:

代码语言:javascript
复制
for image 1..5
    load images
    display image in a window
    wait for any keypress
    close the window

下面是我在C++中使用OpenCV实现此目的的代码片段:

代码语言:javascript
复制
IplImage *img;

for (int i=0; i < 5; ++i){
    img = cvLoadImage(images[i].name.c_str(),1);
    cvShowImage(("Match" + images[i].name).c_str(), img);
    cvWaitKey(0);
    cvDestroyWindow(("Match" + images[i].name).c_str());
    // sleep(1);
    cvReleaseImage(&img);
}

这里使用的images数组在我的代码中并不存在,但为了解决这个问题,如果它是name成员,它包含相对于当前程序运行点的图像的文件名。我在我的项目中存储的图像名称略有不同。

上面的代码几乎可以工作:我可以迭代通过4/5的图像,但当最后一个图像显示并按下一个键时,图像变灰,并且我无法在不崩溃应用程序的其余部分的情况下关闭图像窗口。

我的第一个想法是,由于编译时优化,cvReleaseImagecvDestroyWindow完成之前就释放了图像,这以某种方式使它冻结。但是,我尝试添加一些等待时间(因此我的代码中注释掉了sleep(1)行),但没有帮助。

我从我的控制台应用程序调用这个显示功能,当图像冻结时,控件返回到我的应用程序,我可以继续使用它(但图像窗口仍然在背景中冻结)。

你能给我一些关于如何解决这个问题的建议吗?

编辑

自从提出这个问题以来,我已经和一些与计算机视觉和OpenCV打交道的人进行了定期的交谈,但仍然没有想法。

我也找到了一个类似的stackoverflow question,但仍然没有公认的答案。谷歌搜索的结果只是给出了类似的问题,但没有答案。

任何关于尝试什么的想法(即使它们不是完整的解决方案)都是非常感谢的。

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2012-01-26 20:21:55

出于测试目的,下面的应用程序执行您在问题中所述的操作:它通过命令行逐个加载7个图像,并为要显示的每个图像创建一个新窗口。

它可以完美地与Linux上的OpenCV 2.3.1兼容。

代码语言:javascript
复制
#include <cv.h>
#include <highgui.h>

#define NUM_IMGS 7

int main(int argc, char* argv[])
{
    if (argc < 8)
    {
        printf("Usage: %s <img1> <img2> <img3> <img4> <img5> <img6> <img7>\n", argv[0]);
        return -1;
    }

    // Array to store pointers for the images
    IplImage* images[NUM_IMGS] = { 0 };

    for (int i = 0; i < NUM_IMGS; i++)
    {
        // load image
        images[i] = cvLoadImage(argv[i+1], CV_LOAD_IMAGE_UNCHANGED);
        if (!images[i])
        {
            printf("!!! failed to load: %s\n", argv[i+1]);
            continue;
        }

        // display image in a window
        cvNamedWindow(argv[i+1], CV_WINDOW_AUTOSIZE); // creating a new window each time
        cvShowImage(argv[i+1], images[i]);

        // wait for keypress
        cvWaitKey(0);

        // close the window
        cvDestroyWindow(argv[i+1]);
        cvReleaseImage(&images[i]);
    }

    return 0;
}
票数 23
EN

Stack Overflow用户

发布于 2012-01-26 19:15:51

cvDestroyWindow()通常只启动相当复杂的窗口销毁过程。此过程需要在窗口系统和应用程序之间进行一些交互(事件交换)。在此过程完成之前,不能完全销毁窗口。这就是为什么当你的应用程序执行一些与GUI无关的事情时,你会看到部分被破坏的窗口。

事件交换可以以依赖于系统的方式执行。在Windows中,这意味着(直接或间接)调用GetMessageMsgWaitFor*函数并处理结果。对于Unixes,这意味着(直接或间接)调用XNextEvent并处理结果。

OpenCV允许以独立于系统的方式进行这种事件交换。有两种记录在案的方法可以做到这一点。第一个是cvWaitKey() (只需在关闭最后一个图像后调用cvWaitKey(1) )。第二种方法是在程序开始时调用cvStartWindowThread(),以允许OpenCV自动更新其窗口。

在我使用libcv2.1的Linux机器上,只有一种方法可以正常工作:cvStartWindowThread()

更新(使用cvStartWindowThread()的代码片段)

代码语言:javascript
复制
//gcc -std=c99 main.c -lcv -lcxcore -lhighgui
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <stdio.h>
#include <unistd.h>

#define NUM_IMGS 2

int main(int argc, char* argv[])
{
    if (argc < 2)
    {
        printf("Usage: %s <img1>\n", argv[0]);
        return -1;
    }

    cvStartWindowThread();

    // Array to store pointers for the images
    IplImage* images[NUM_IMGS] = { 0 };

    for (int i = 0; i < NUM_IMGS; i++)
    {
        // load image
        images[i] = cvLoadImage(argv[i+1], CV_LOAD_IMAGE_UNCHANGED);
        if (!images[i])
        {
            printf("!!! failed to load: %s\n", argv[i+1]);
            continue;
        }

        // display image in a window
        cvNamedWindow(argv[i+1], CV_WINDOW_AUTOSIZE); // creating a new window each time
        cvShowImage(argv[i+1], images[i]);

        // wait for keypress
        cvWaitKey(0);

        // close the window
        cvDestroyWindow(argv[i+1]);
        cvReleaseImage(&images[i]);
    }

    //    cvWaitKey(1);
    sleep(10);
    return 0;
}
票数 5
EN

Stack Overflow用户

发布于 2012-01-13 06:15:23

没有必要销毁每一帧上的窗口,您只需使用相同的窗口名称调用cvShowImage(),它将替换当前图像。

你只需要在关机时调用销毁窗口。您可以使用cvCreateWindow()在启动时创建窗口,但它将在第一次调用showWindow()时自动创建。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8842901

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档