Add ability to choose photos to stitch, directly from dialog (GUI)
=============FileDialog.cpp================
#include <new> #include <shlobj.h> #include <shlwapi.h> #include <vector> #include <string> #include <iostream> using namespace std; const COMDLG_FILTERSPEC c_rgFileTypes[] = { { L"Images", L"*.jpg;*.jpeg" }, { L"All Files (*.*)", L"*.*" } }; void MultiselectInvoke(vector<string> *ret) { ret->clear(); // CHM - Initialise for COM objects IFileOpenDialog *pfd = NULL; // CoCreate the dialog object. HRESULT hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd)); if (SUCCEEDED(hr)) { DWORD dwOptions; // Specify multiselect. hr = pfd->GetOptions(&dwOptions); if (SUCCEEDED(hr)) { hr = pfd->SetOptions(dwOptions | FOS_ALLOWMULTISELECT); } // Set the file types to display only. // Notice that this is a 1-based array. pfd->SetFileTypes(ARRAYSIZE(c_rgFileTypes), c_rgFileTypes); pfd->SetTitle(L"[CHM] Select of Images to Stitch"); if (SUCCEEDED(hr)) { // Show the Open dialog. hr = pfd->Show(GetFocus()); if (SUCCEEDED(hr)) { // Obtain the result of the user interaction. IShellItemArray *psiaResults; hr = pfd->GetResults(&psiaResults); if (SUCCEEDED(hr)) { DWORD dwFolderCount; hr = psiaResults->GetCount(&dwFolderCount); if (SUCCEEDED(hr)) { for (DWORD i = 0; i < dwFolderCount; i++) { IShellItem *psi = NULL; if (SUCCEEDED(psiaResults->GetItemAt(i, &psi))) { // Retrieve the file path. // CHM - It is ok not to initialise, as the pointer \ is assigned in the following function LPWSTR pszPath = NULL; if (SUCCEEDED(psi->GetDisplayName(SIGDN_FILESYSPATH,&pszPath))) { // Geting short version of path, elimating some problem (not all) \ of unicode path DWORD wlen = GetShortPathName(pszPath, NULL, 0); LPWSTR s_pszPath = new wchar_t[wlen]; GetShortPathName(pszPath, s_pszPath, wlen); int size_needed = WideCharToMultiByte(CP_ACP, NULL, s_pszPath, -1, NULL, NULL, NULL, NULL); LPSTR pszPathA = (char *)CoTaskMemAlloc(size_needed); WideCharToMultiByte(CP_ACP, NULL, s_pszPath, -1, pszPathA, size_needed, NULL, NULL); delete[] s_pszPath; ret->push_back(pszPathA); CoTaskMemFree(pszPathA); CoTaskMemFree(pszPath); } psi->Release(); } } } psiaResults->Release(); } } } pfd->Release(); } return; }
=============================================
===============main.cpp=========================
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> #include <opencv\cv.h> #include <opencv2\stitching\stitcher.hpp> #include <windows.h> #include "FileDialog.h" using namespace cv; using namespace std; int main(int argc, char** argv) { SetConsoleTitle(L"[CHM] Photo-Stitcher Demo"); cout << "Powered by OpenCV (2.4.9) libraries" << endl; cout << "Coded in Visual C++ 2013"<<endl; #if _WIN64 cout << "x64"<<endl; #else cout << "x86"<<endl; #endif #if _DEBUG cout << "Debug build"<<endl; #else cout << "Release build"<<endl; #endif cout << endl<< "====Program Start====" << endl << "Opening Photos..."; vector<string> imgpaths; CoInitialize(NULL); MultiselectInvoke(&imgpaths); while (imgpaths.size()<2) { int hr = MessageBox(GetFocus(), L"Two or more photos are required!", L"[CHM] Photo-Stitcher", MB_RETRYCANCEL | MB_ICONINFORMATION); if (hr == IDCANCEL) return 0; else if (hr == IDRETRY); MultiselectInvoke(&imgpaths); } CoUninitialize(); cout << " -Done" << endl; vector< Mat > vImg; Mat rImg; Mat image; image = imread(imgpaths[0], IMREAD_COLOR); // Read the file if (!image.data) // Check for invalid input { cout << "Could not open or find the image" << std::endl; return -1; } cout << "Blurring Function Test"; GaussianBlur( image, image, Size( 31, 31 ), 0, 0 ); namedWindow("[CHM] Display 1st pic", CV_WINDOW_NORMAL | CV_WINDOW_KEEPRATIO); resizeWindow("[CHM] Display 1st pic", image.cols*0.1, image.rows*0.1); imshow("[CHM] Display 1st pic", image); cout << " -Done" << endl; waitKey(0); // Wait for a keystroke in the window destroyAllWindows(); cout <<endl<< "Stitching Test" << endl; cout << "> Loading Photos... "; DWORD i, n; n = imgpaths.size(); for (i = 0; i < n; i++) { vImg.push_back(imread(imgpaths[i])); } cout << " -Done" << endl; cout << "> Resolution is " << vImg.at(0).cols<<"W" << " * " << vImg.at(0).rows <<"H, for Each Photo" <<endl; Stitcher stitcher = Stitcher::createDefault(); unsigned long AAtime = 0, BBtime = 0; //check processing time AAtime = getTickCount(); //check processing time stitcher.stitch(vImg, rImg); BBtime = getTickCount(); //check processing time cout << "Done,"; printf("%.2lf sec \n", (BBtime - AAtime) / getTickFrequency()); //check processing time namedWindow("[CHM]Stitching Result", CV_WINDOW_NORMAL | CV_WINDOW_KEEPRATIO); resizeWindow("[CHM]Stitching Result", rImg.cols*0.19, rImg.rows*0.19); imshow("[CHM]Stitching Result", rImg); #ifndef _DEBUG SYSTEMTIME systime; GetLocalTime(&systime); stringstream outpath; outpath << "PanoramaCV_" << setfill('0') << setw(2) << systime.wMonth << "_" << setfill('0') << setw(2) << systime.wDay << ".jpg"; imwrite(outpath.str(), rImg); waitKey(0); // Wait for a keystroke in the window #endif cout << "====End of Program====" << endl; return 0; }
=======================================================