opencv应用——以图拼图

一,准备图片

可以先手动分一分,有的是关键信息在中间,有的是在上面,主要就是这两种。

然后用程序先截出正方形的图片:

int main()
{
	for (int i = 1; i <= 10; i++) {
		Mat img = imread("D:/pic2/img (" + to_string(i) + ").jpg",0);
		int p = min(img.rows, img.cols);
		Mat img2 = img(Rect((img.cols - p) / 2, (img.rows - p) / 2, p, p));
		imwrite("D:/pic2/a" + to_string(i) + ".jpg",img2);
	}
	return 0;
}

截上面的:

int main()
{
	for (int i = 1; i <= 15; i++) {
		Mat img = imread("D:/pic2/img (" + to_string(i) + ").jpg",0);
		int p = min(img.rows, img.cols);
		Mat img2 = img(Rect(0, 0, p, p));
		imwrite("D:/pic2/a" + to_string(i) + ".jpg",img2);
	}
	return 0;
}

二,拼图

我们先把所有小图调整到统一的大小,然后按照亮度排序。

对于目标图像,按照分块,也分别统计亮度排序。

再根据排序结果进行匹配,把小图往对应位置填充就行了。

图片除了要做亮度匹配之外,在最后拼到大图上之前,还要做亮度调整,把整体亮度调到和分块亮度相同。

struct Nodes
{
	int t;
	int id;
	bool operator<(Nodes a) const
	{
		if (t == a.t)return id < a.id;
		return t < a.t;
	}
};

int imageSum(Mat img)
{
	int s = 0;
	for (int i = 0; i < img.rows; i++)for (int j = 0; j < img.cols; j++)
		s += img.at(i, j);
	return s;
}

int main()
{
	const int N = 9;
	const int NUM = N * N;
	const int SIZE = N * 2000;
	const int PIX = 100;
	const int R1 = SIZE / PIX;
	const int R = R1 / N * R1 / N;
	Mat imgs[NUM];
	for (int i = 1; i <= NUM; i++) {
		imgs[i - 1] = imread("D:/pic2/img (" + to_string(i) + ").jpg", 0);
		resize(imgs[i - 1], imgs[i - 1], Size(PIX, PIX));
	}
	Mat img = imread("D:/pic2/img (74).jpg", 0);
	resize(img, img, Size(SIZE, SIZE));
	Nodes node[NUM * R];
	Nodes node2[NUM * R];
	for (int i = 0; i < NUM * R; i++) {
		node[i].t = imageSum(imgs[i % NUM]);
		node[i].id = i % NUM;
		node2[i].t = imageSum(img(Rect(i % R1 * PIX, i / R1 * PIX, PIX, PIX)));
		node2[i].id = i;
	}
	sort(node, node + NUM * R);
	sort(node2, node2 + NUM * R);
	for (int i = 0; i < NUM * R; i++)
	{
		Mat image;
		imgs[node[i].id % NUM].copyTo(image);
		image *= 1.0 * node2[i].t / node[i].t;
		image.copyTo(img(Rect(node2[i].id % R1 * PIX, node2[i].id / R1 * PIX, PIX, PIX)));
	}
	//imshow("img", img);
	imwrite("D:/pic2/ans.png", img);
	cv::waitKey(0);
	return 0;
}

opencv应用——以图拼图_第1张图片

 拼接结果:

(头部)放大效果:

 (眼睛)放大效果:

 

三,优化思路

1,当前所用图片较少,如果图片多一点,效果会好一点。

2,因为图片少,每个图片都被用到多次。当前是每个图片被使用的次数相同,这一点可以优化一下,自适应的选择每个图片被使用的次数,效果应该会更好。

3,要想搞成彩色的,主要问题在于图片的匹配问题。灰度图像只需要按照亮度排序即可匹配,改成彩色图像相当于从一维变成三维。

你可能感兴趣的:(算法)