#include <fstream>
#include <iostream>
#include <cstdlib>
#include<atlstr.h>
#include<stdlib.h>
#include<math.h>
#include<direct.h>
#define NO_WIN32_LEAN_AND_MEAN
#include <shlobj.h>
#include<opencv.hpp>
#include<time.h>
#include <algorithm>
using namespace cv;
using namespace std;
CString Get_Filder_Path()
{
CString strpath;
TCHAR Buffer[MAX_PATH];
BROWSEINFO bi;
ZeroMemory(&bi, sizeof(BROWSEINFO));
bi.hwndOwner = NULL;
bi.ulFlags = BIF_RETURNONLYFSDIRS; //要求返回文件系统的目
bi.ulFlags = BIF_NEWDIALOGSTYLE; //窗口可以调整大小,有新建文件夹按钮
bi.pszDisplayName = Buffer; //此参数如为NULL则不能显示对话框
bi.lpszTitle = _T("请选择文件夹");
bi.lpfn = NULL;
LPITEMIDLIST pIDList = SHBrowseForFolder(&bi);//调用显示选择对话框
if (pIDList)
{
SHGetPathFromIDList(pIDList, Buffer);
//取得文件夹路径到Buffer里
strpath.Format(_T("%s"), Buffer);
}
else
{
strpath = _T(""); // 用户点了取消
}
LPMALLOC lpMalloc;
if (FAILED(SHGetMalloc(&lpMalloc)))
strpath = _T("");
//释放内存
lpMalloc->Free(pIDList);
lpMalloc->Release();
return strpath;
}
CString Get_File_Path()
{
CString strpath;
TCHAR szBuffer[MAX_PATH] = { 0 };
BROWSEINFO bi;
ZeroMemory(&bi, sizeof(BROWSEINFO));
bi.hwndOwner = NULL;
bi.pszDisplayName = szBuffer;
bi.lpszTitle = _T("从下面选择文件或文件夹:");
bi.ulFlags = BIF_BROWSEINCLUDEFILES;
LPITEMIDLIST idl = SHBrowseForFolder(&bi);
if (NULL == idl)
{
return strpath;
}
SHGetPathFromIDList(idl, szBuffer);
strpath.Format(_T("%s"), szBuffer);
LPMALLOC lpMalloc;
if (FAILED(SHGetMalloc(&lpMalloc)))
strpath = _T("");
//释放内存
lpMalloc->Free(idl);
lpMalloc->Release();
return strpath;
}
Mat mergeRows(Mat& A, Mat& B)//行[A ; B]
{
//CV_ASSERT(A.cols == B.cols&&A.type() == B.type());
int totalRows = A.rows + B.rows;
Mat mergedDescriptors(totalRows, A.cols, B.type());
Mat submat = mergedDescriptors.rowRange(0, A.rows);
A.copyTo(submat);
submat = mergedDescriptors.rowRange(A.rows, totalRows);
B.copyTo(submat);
return mergedDescriptors;
}
Mat mergecols(Mat& A, Mat& B)//列[A B]
{
//CV_ASSERT(A.cols == B.cols&&A.type() == B.type());
int totalCols = A.cols + B.cols;
Mat mergedDescriptors(A.rows, totalCols, B.type());
Mat submat = mergedDescriptors.colRange(0, A.cols);
A.copyTo(submat);
submat = mergedDescriptors.colRange(A.cols, totalCols);
B.copyTo(submat);
return mergedDescriptors;
}
class picc
{
public:
Mat pic;
Point2i id;
picc()
{
}
picc(const picc &obj1)
{
pic = obj1.pic.clone();
id.x = obj1.id.x;
id.y = obj1.id.y;
}
void operator = (const picc& obj1)
{
pic = obj1.pic.clone();
id.x = obj1.id.x;
id.y = obj1.id.y;
}
};
class midle
{
public:
Mat tt;
vector<vector<picc> > arry;
vector<picc> start;
int raw = 2;
int col = 3;
Point2i cur;
int cur_index;
midle(Mat& tt)
{
this->tt = tt;
vector<vector<picc> > a(raw, vector<picc>(col));
arry = a;
}
void splid()
{
int x_step = tt.cols / col;
int y_step = tt.rows / raw;
srand((int)time(0));
cur.x = rand() % raw;
cur.y = rand() % col;
cout << "cur: " << cur.x << " " << cur.y << endl << endl;
for (int i = 0; i < raw; i++)
{
for (int j = 0; j < col; j++)
{
Point2i naw=Point2i{ i, j };
if (naw == cur)
{
Mat temm=Mat(y_step, x_step, CV_8UC3, Scalar(0, 0, 0));
arry[i][j].pic = temm.clone();
//cout << "i j : " << i << " " << j << endl << endl;
}
else
{
Mat temm(tt, Rect(x_step*j, y_step*i, x_step, y_step));
arry[i][j].pic = temm.clone();
}
arry[i][j].id = naw;
//imshow("cccc", arry[i][j].pic);
//waitKey(0);
}
}
}
void daluan()
{
vector<int>order;
for (int k = 0; k < 4; k++)
{
order.push_back(k);
}
for (int k = 0; k < 100; k++)
{
random_shuffle(order.begin(), order.end());
int mod = order[1];
Point2i nest = cur;
if (mod == 0)//上
{
nest.x += 1;
}
else if (mod == 1)//下
{
nest.x -= 1;
}
else if (mod == 2)//左
{
nest.y += 1;
}
else if (mod == 3)//右
{
nest.y -= 1;
}
if (nest.x < 0 || nest.x >= raw)
{
nest = cur;
}
if (nest.y<0 || nest.y >= col)
{
nest = cur;
}
if (nest == cur)continue;
picc temp = arry[cur.x][cur.y];
arry[cur.x][cur.y] = arry[nest.x][nest.y];
arry[nest.x][nest.y] = temp;
cur = nest;
}
}
void move()
{
int mod = waitKey(100);
Point2i nest = cur;
if (mod == 2490368)//上
{
nest.x += 1;
}
else if (mod == 2621440)//下
{
nest.x -= 1;
}
else if (mod == 2424832)//左
{
nest.y += 1;
}
else if (mod == 2555904)//右
{
nest.y -= 1;
}
if (nest.x < 0 || nest.x >= raw)
{
nest = cur;
}
if (nest.y < 0 || nest.y >= col)
{
nest = cur;
}
if (nest == cur)return;
picc temp = arry[cur.x][cur.y];
arry[cur.x][cur.y] = arry[nest.x][nest.y];
arry[nest.x][nest.y] = temp;
cur = nest;
}
void show()
{
Mat res;
for (int i = 0; i < raw; i++)
{
Mat raw = arry[i][0].pic;
for (int j = 1; j < col; j++)
{
raw = mergecols(raw, arry[i][j].pic);
}
if (i == 0)res = raw;
else
res = mergeRows(res, raw);
}
imshow("res", res);
waitKey(1);
}
bool if_finish()
{
for (int i = 0; i < raw; i++)
{
for (int j = 0; j < col; j++)
{
if (i != (arry[i][j].id.x) || j != (arry[i][j].id.y))return false;
}
}
return true;
}
};
int main()
{
//GetSavePath();
CString x;
x = Get_File_Path();
USES_CONVERSION;
string str(W2A(x));
Mat pic = imread(str);
imshow("your choice", pic);
midle my(pic);
my.splid();
my.daluan();
while (!my.if_finish())
{
my.move();
my.show();
}
cout << "finish";
waitKey(0);
return 0;
}