我正在做一个搜索图像数据库的项目,当我找到一些查询的结果--5个数据库图像时,我想直观地显示结果.我没有将所有图像保存在内存中,所以我先加载图像以显示它.
在伪代码中,我有一些简单的想法:
for image 1..5
load images
display image in a window
wait for any keypress
close the window
Run Code Online (Sandbox Code Playgroud)
这里是我的代码片段C++
使用OpenCV
用于此目的:
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);
}
Run Code Online (Sandbox Code Playgroud)
images
这里使用的数组并不存在于我的代码中,但是为了问题,它包含相对于当前程序运行点(如果是其name
成员)的图像的文件名.我在项目中存储的图像名称略有不同.
上面的代码几乎可以工作:我可以迭代4/5图像OK,但是当显示最后一个图像并按下一个键时,图像变为灰色,我无法关闭图像窗口而不会崩溃我的应用程序的其余部分.
我的第一个想法是因为编译时优化,cvReleaseImage
在cvDestroyWindow
完成之前释放图像,并以某种方式使其冻结.但是,我已经尝试添加一些等待时间(因此sleep(1)
我的代码注释掉了)并没有帮助.
我从我的控制台应用程序调用此显示功能,当图像冻结时,控件返回到我的应用程序,我可以继续使用它(但图像窗口仍然在后台冻结).
你能给我一些关于如何解决这个问题的建议吗?
编辑
自从提出问题以来,我已经定期与一些处理计算机视觉和OpenCV的人交谈,但仍然没有想法.
我也发现了类似的stackoverflow问题,但仍然没有接受的答案.谷歌只是提出类似的问题,但没有答案.
任何关于尝试什么的想法(即使它们不是完整的解决方案)都非常感谢.
kar*_*lip 22
出于测试目的,下面的应用程序完全按照您在问题中所述的内容执行:它通过命令行逐个加载7个图像,并为每个要显示的图像创建一个新窗口.
它与Linux上的OpenCV 2.3.1完美配合.
#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;
}
Run Code Online (Sandbox Code Playgroud)
cvDestroyWindow()
通常只会启动非常复杂的窗口破坏程序.此过程需要在窗口系统和应用程序之间进行一些交互(事件交换).在此过程完成之前,窗口无法完全销毁.这就是为什么当应用程序执行与GUI无关的操作时,您会看到部分销毁窗口的原因.
可以以系统相关的方式执行事件交换.在Windows中,这意味着(直接或间接)调用GetMessage
或MsgWaitFor*
运行和处理结果.对于Unix,这意味着(直接或间接)调用XNextEvent
和处理结果.
OpenCV允许以独立于系统的方式进行此事件交换.有两种记录方法可以做到这一点.第一个是cvWaitKey()
(cvWaitKey(1)
在关闭最后一个图像后调用).第二个是cvStartWindowThread()
在程序开始时调用,以允许OpenCV自动更新其窗口.
这些方法中只有一种在我的Linux机器上使用libcv2.1正常工作:cvStartWindowThread()
.
更新(使用cvStartWindowThread()的代码片段)
//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;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
60208 次 |
最近记录: |