GetOpenFileName 对话框和 opencv 的奇怪行为
Strange behaviour with GetOpenFileName dialog and opencv
我正在尝试使用打开文件对话框来允许我的程序的用户select一个图像,然后使用 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 '[=10=]' so that GetOpenFileName does not
// use the contents of szFile to initialize itself.
ofn.lpstrFile[0] = '[=10=]';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = L"All[=10=]*.*[=10=]Text[=10=]*.TXT[=10=]";
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 交互时出现问题。
例如,如果我取消注释 'imshow' 行,GetOpenFileName 将 return 0 并且对话框甚至不会打开。这种情况经常发生,我实际上无法访问图像,因为我尝试的一切都会导致这种情况发生。
为了使函数正常工作,它被这样调用:
load_image();
但是如果我尝试分配图像即:
img = load_image();
出现同样的问题。帮助!可能是什么原因造成的?
这些只是我在您的代码中注意到的事情...所以我不希望它起作用,但也许它会有所帮助。
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 )
再次归档。
正如前面评论中提到的,CreateFile
方法锁定了图像文件,因此 cv::imread()
无法 access/read 它的内容。
尽量避免使用 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] = '[=10=]';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = L"All[=10=]*.*[=10=]Text[=10=]*.TXT[=10=]";
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;
}
我正在尝试使用打开文件对话框来允许我的程序的用户select一个图像,然后使用 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 '[=10=]' so that GetOpenFileName does not
// use the contents of szFile to initialize itself.
ofn.lpstrFile[0] = '[=10=]';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = L"All[=10=]*.*[=10=]Text[=10=]*.TXT[=10=]";
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 交互时出现问题。
例如,如果我取消注释 'imshow' 行,GetOpenFileName 将 return 0 并且对话框甚至不会打开。这种情况经常发生,我实际上无法访问图像,因为我尝试的一切都会导致这种情况发生。
为了使函数正常工作,它被这样调用:
load_image();
但是如果我尝试分配图像即:
img = load_image();
出现同样的问题。帮助!可能是什么原因造成的?
这些只是我在您的代码中注意到的事情...所以我不希望它起作用,但也许它会有所帮助。
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 )
再次归档。
正如前面评论中提到的,CreateFile
方法锁定了图像文件,因此 cv::imread()
无法 access/read 它的内容。
尽量避免使用 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] = '[=10=]';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = L"All[=10=]*.*[=10=]Text[=10=]*.TXT[=10=]";
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;
}