OpenCV实现拼图板小游戏

80后可能还对儿时玩过的一种经典木质的拼图板游戏记忆犹新,一般是一种4*4或5*5规格的手持活动板,通过挪动每个小板子的位置,拼出来板子上完整的图像,那时候还没有网吧,手机也还是大哥大的天下,所以这也可以算得上是最早的“手游”了吧。

今天我们用OpenCV来复现一下儿时的经典!

代码:

#include "core/core.hpp"

#include "highgui/highgui.hpp"

#include "imgproc/imgproc.hpp"

#include <time.h>

using namespace cv;

Mat Sourceimage, Spilteimage, Rebuildimage, Dstimage;

int rows, cols;

int Roirows, Roicols;

vector<Mat>arraryimage;

void Randarrary(vector<Mat> &vectorMat); //随机排列子图像序列函数

static int vectornumber = 0;

void OnMouseAction(int event, int x, int y, int flags, void *ustc); //鼠标回调事件函数

int mainFun()

{

Sourceimage = imread("D:\\test\\lena.jpg");

imshow("Source image", Sourceimage);

rows = 6; //将图像分割成rows行

cols = 4; //将图像分割成cols列

Roirows = Sourceimage.rows / rows;

Roicols = Sourceimage.cols / cols;

Spilteimage = Mat::zeros(Sourceimage.rows, Sourceimage.cols, Sourceimage.type());

Dstimage = Mat::zeros(Sourceimage.rows, Sourceimage.cols, Sourceimage.type());

for (int i = 0; i<rows; i++)

{

for (int j = 0; j<cols; j++)

{

Mat SourceRoi = Sourceimage(Rect(j*Roicols, i*Roirows, Roicols - 1, Roirows - 1));

arraryimage.push_back(SourceRoi);

}

}

// 随机函数

Randarrary(arraryimage);

for (int i = 0; i<rows; i++)

{

for (int j = 0; j<cols; j++)

{

Mat SpilterRoi = Spilteimage(Rect(j*Roicols, i*Roirows, Roicols - 1, Roirows - 1));

addWeighted(SpilterRoi, 0, arraryimage[vectornumber], 1, 0, SpilterRoi);

vectornumber++;

imshow("Splite image", Spilteimage);

waitKey(150);

}

}

setMouseCallback("Splite image", OnMouseAction);

waitKey();

return 0;

}

//*******************************************************************//

//随机调换所有的子图像序列的位置,用于在 Splite image中显示

//*******************************************************************//

void Randarrary(vector<Mat>& vectorMat)

{

for (int i = 0; i<vectorMat.size(); i++)

{

srand(int(time(0)));

int a = rand() % (vectorMat.size() - i) + i;

swap(vectorMat[i], vectorMat[a]);

}

}

//*******************************************************************//

//鼠标回调函数,用于获取需要查找的子图像在原图像中的位置,并在叠加显示在目标图像中

//*******************************************************************//

void OnMouseAction(int event, int x, int y, int flags, void *ustc)

{

if (event == CV_EVENT_LBUTTONDOWN)

{

Mat RoiSpilte, RoiSource;

int rows = (y / Roirows)*Roirows;

int clos = (x / Roicols)*Roicols;

RoiSpilte = Spilteimage(Rect(clos, rows, Roicols, Roirows));

imshow("Slice", RoiSpilte);

Mat image = Mat::zeros(Sourceimage.rows - Roirows, Sourceimage.cols - Roicols, CV_32FC1);

matchTemplate(Sourceimage, RoiSpilte, image, 1);

normalize(image, image, 0, 1, NORM_MINMAX);

double minV = 0;

double maxV = 0;

Point minP, maxP;

minMaxLoc(image, &minV, &maxV, &minP, &maxP);

Mat ROIDst = Dstimage(Rect(minP.x, minP.y, Roicols, Roirows));

addWeighted(ROIDst, 0, RoiSpilte, 1, 0, ROIDst, -1);

imshow("Jigsaw image", Dstimage);

}

}

//-----开始------

void COpenCVLearningDlg::OnBnClickedStartButton()

{

mainFun();

}

效果:

以上是 OpenCV实现拼图板小游戏 的全部内容, 来源链接: utcz.com/z/359431.html

回到顶部