我尝试使用打开文件对话框,允许我的程序用户选择一个图像,然后使用opencv进行处理。
我有一个功能,我打开对话框并尝试加载图像:
Mat load_image()
{
OPENFILENAME ofn; // common dialog box structure
TCHAR szFile[260]; // buffer for file name
HWND hwnd; // owner window
HANDLE hf; // file handle
// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = szFile;
// Set lpstrFile[0] to '\0' so that GetOpenFileName does not
// use the contents of szFile to initialize itself.
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = L"All\0*.*\0Text\0*.TXT\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
// Display the Open dialog box.
if (GetOpenFileName(&ofn)==TRUE)
hf = CreateFile(ofn.lpstrFile,
GENERIC_READ,
0,
(LPSECURITY_ATTRIBUTES) NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
char filepath[260];
wcstombs(filepath, ofn.lpstrFile, 260);
cout << filepath << endl;
Mat src = imread(filepath);
//imshow("src", src);
return src;
}
您在此处看到的代码可以使用,打开对话框并允许用户选择文件。然后将文件路径转换为字符串(将传递给imread)。当我尝试与图像src交互时,会出现问题。
例如,如果我取消注释&#39; imshow&#39; line,GetOpenFileName将返回0并且对话框甚至不会打开。这种情况发生的比较多,我实际上无法访问图像,因为我尝试的一切都会导致这种情况发生。
为了使函数起作用,它被调用如下:
load_image();
但如果我尝试分配图像,即:
img = load_image();
出现同样的问题。救命!可能导致这种情况的原因是什么?
答案 0 :(得分:1)
这些只是我在你的代码中注意到的事情......所以我不希望这会有用,但也许会有所帮助。
imread
可能失败了。您使用CreateFile
打开了文件,并在打开文件时将其锁定(无共享属性。有关详细信息,请参阅CreateFile)。 imread
尝试打开文件,因此您不需要创建自己的句柄!只需使用收到的文件路径,然后拨打imread
,而不是使用CreateFile
。
Mat src;
if (GetOpenFileName(&ofn)==TRUE)
{
// Succeeded in choosing a file
char filepath[260];
wcstombs(filepath, ofn.lpstrFile, 260);
cout << filepath << endl;
src = imread(filepath);
}
如果你没有hwnd
,那么你应该设置ofn.hwndOwner=NULL
而不是任意设置它。
如果您选择使用CreateFile(可能您希望在OpenCV之外为自己的目的打开它以进行手动读取访问),那么请确保在再次打开文件之前调用文件句柄上的CloseHandle( HANDLE h )
答案 1 :(得分:1)
正如上一条评论中所提到的,CreateFile
方法锁定了图像文件,因此cv::imread()
无法访问/读取其内容。
尽量避免使用CreateFile
,我认为没有理由在您的代码中使用它,以下代码运行良好:
cv::Mat load_image()
{
cv::Mat outMat;
OPENFILENAME ofn; // common dialog box structure
TCHAR szFile[260]; // buffer for file name
// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = L"All\0*.*\0Text\0*.TXT\0";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
// Display the Open dialog box.
if (GetOpenFileName(&ofn) == TRUE)
{
char filepath[260];
wcstombs(filepath, ofn.lpstrFile, 260);
cout << filepath << endl;
outMat = cv::imread(filepath);
}
return outMat;
}
int main()
{
cv::Mat image = load_image();
cv::imshow("image", image);
cv::waitKey(-1);
return 0;
}