opencv实现拼图功能

简介

  在使用美图秀秀之类工具的时候,发现了一个拼图功能,然后这里用opencv实现了类似效果。

实现原理

具体代码

#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv/cv.h>
#include <math.h>
 
using namespace cv;
 
#define pic_num 4
 
Mat src, imageROI[pic_num];
Mat srcROI[4];
int width=0, height=0;
int src2_width, src2_height;
char pic_name[pic_num][20];
char bg[20] = "src/w.jpg";
int picaddr[pic_num][4] = {{2, 49, 2, 49}, {51, 98, 2, 24}, {51, 98, 26, 49}, {2, 98, 51, 98}};
 
void MyResize(Mat& mat1, Mat& mat2, int width, int height){
	IplImage pI_1 = mat1, pI_2;
 
	mat2 = cv::Mat(height, width, CV_8UC3, 1);
	pI_2 = mat2;
 
	cvResize(&pI_1, &pI_2, 1);
}
 
void init(char* argv[]){
	int i, j;
 
	memcpy(pic_name[0],argv[1],sizeof(argv[1]));
	memcpy(pic_name[1],argv[2],sizeof(argv[2]));
	memcpy(pic_name[2],argv[3],sizeof(argv[3]));
	memcpy(pic_name[3],argv[4],sizeof(argv[4]));
	src=imread(bg,1);
	width =  src.cols;
	height = src.rows;
	for(i=0; i< pic_num; i++){
		for(j=0; j<4; j++){
			if(j<2){
				picaddr[i][j] = picaddr[i][j] * width / 100;
			}else{
				picaddr[i][j] = picaddr[i][j] * height / 100;
			}
		}
		srcROI[i] = imread(pic_name[i], 1);
	}
}
 
void roiadd(void){
	int i;
	Mat tmp;
	for(i=0; i< pic_num; i++){
		imageROI[i] = src(cv::Rect(picaddr[i][0], picaddr[i][2], picaddr[i][1] - picaddr[i][0], picaddr[i][3] - picaddr[i][2]));
		MyResize(srcROI[i], tmp, picaddr[i][1] - picaddr[i][0], picaddr[i][3] - picaddr[i][2]);
		addWeighted(imageROI[i], 0, tmp, 1, 0.0, imageROI[i]);
	}
	imshow("src", src);
}
 
int main(int agrc, char* argv[]){
	char c;
	int i;
 
	init(argv);
	roiadd();
	waitKey(0);
	return 0;
}

代码讲解[编辑 | 编辑源代码]

  1、在init函数中,打开了背景图片到src中,接着根据背景图片的width和height,计算出来将要进行拼图的4张图片位置,保存到picaddr中。
然后打开了要进行拼图的4张图片到srcROI中。
void init(char* argv[]){
	int i, j;
 
	memcpy(pic_name[0],argv[1],sizeof(argv[1]));
	memcpy(pic_name[1],argv[2],sizeof(argv[2]));
	memcpy(pic_name[2],argv[3],sizeof(argv[3]));
	memcpy(pic_name[3],argv[4],sizeof(argv[4]));
	src=imread(bg,1);
	width =  src.cols;
	height = src.rows;
	for(i=0; i< pic_num; i++){
		for(j=0; j<4; j++){
			if(j<2){
				picaddr[i][j] = picaddr[i][j] * width / 100;
			}else{
				picaddr[i][j] = picaddr[i][j] * height / 100;
			}
		}
		srcROI[i] = imread(pic_name[i], 1);
	}
}
  2、在roiadd函数中,首先使用imageROI方式,根据picaddr,获得要在背景图中拼图的具体位置,然后将准备拼入的图片srcROI,根据picaddr计算出来的
width和height,进行缩放。最后addWeighted以1的权重将缩放后图片混合到imageROI对应的位置。最后用imshow显示出来。
void roiadd(void){
	int i;
	Mat tmp;
	for(i=0; i< pic_num; i++){
		imageROI[i] = src(cv::Rect(picaddr[i][0], picaddr[i][2], picaddr[i][1] - picaddr[i][0], picaddr[i][3] - picaddr[i][2]));
		MyResize(srcROI[i], tmp, picaddr[i][1] - picaddr[i][0], picaddr[i][3] - picaddr[i][2]);
		addWeighted(imageROI[i], 0, tmp, 1, 0.0, imageROI[i]);
	}
	imshow("src", src);
}

效果演示[编辑 | 编辑源代码]

  对应的效果演示如下:
                                  
时间: 2024-12-07 05:22:40

opencv实现拼图功能的相关文章

类似美图秀秀的自由拼图功能是怎么实现的?

============问题描述============ 重写imageview..但不晓得为何我重写后只能显示一张图片,其余的还是不显示? ============解决方案1============ 不同格子的形式可以定义一个VIEW,最后把整个组合成一个IMAGE ============解决方案2============ 其实全部功能都能在同一个View里完成,用一个ArrayList记录所有的图片及其相关信息(例如位置,旋转角度等,写一个队列去记录即可),onTouch事件每次Actio

OpenCV C++常用功能介绍

显示图片 IplImage* img = cvLoadImage("-/temp.jpeg", 1); //create a window to display the image cvNamedWindow("picture", 1); //show the image in the window cvShowImage("picture", img); //wait for the user to hit a key cvWaitKey(0)

OpenCV For Java环境搭建与功能演示

OpenCV概述 OpenCV做为功能强大的计算机视觉开源框架,包含了500多个算法实现,而且还在不断增加,其最新版本已经更新到3.2.其SDK支持Android与Java平台开发,对于常见的图像处理需求几乎都可以满足,理应成为广大Java与Android程序员的首先的图像处理框架.Java中使用OpenCV的配置及其简单,可以毫不客气的说几乎是零配置都可以. 一:配置 配置引入OpenCV相关jar包,首先要下载OpenCV的自解压版本,下载地址: http://opencv.org/open

创建一个C++制作的包含Opencv功能的dll,供C#程序使用

目的:朋友用C#编写了一个软件,先需要一个功能:获取某图片指定位置的颜色. 实现该目的的方法有很多,即为了朋友能够很便捷解决该问题,也为了有助于扩充自己技术广度,所以决定采用标题中的方法来完成. 没有C++编程经验,也没有制作C++版Opencv语法经验,也没有制作dll的经验,整个流程牵涉比较多的技术环节,每个环节需要一个一个测试通过,才能进行后续设计. 由于网上太多零散信息,没有很好的参考资料,大多只能靠自己实践测试,所以从开始,到跨机各种环境测试,整整花了1天半. 现在问题全部解决了,回头

[转] matlab调用opencv函数的配置

原文地址百度账户 aleasa123 1.  首先保证vs2010能正确调用opencv函数, 2.  Matlab中选择编译器,操作如下: 打开matlab2012,输入mex –setup,出现如下提示: Welcome to mex -setup. This utility will help you set up a default compiler. For a list of supported compilers, see http://www.mathworks.com/supp

OpenCV 3 最新模块一次看个够

OpenCV 3 的改动在哪? C 风格的API很快将会消失,完全被C++的API替代,代码更加简洁.不易出错.读者如果想借助opencv最新的功能,记得清理代码中的C风格API. C++ API 将更加简洁. 所有的算法都将继承自 cv::Algorithm 接口. 大型的模块将拆分为小模块,模块将在后面继续讲解. OpenCV 3 有这么多文件夹,从何入手? 3rdparty/,包含第三方的库,比如视频解码用的 ffmpeg,jpg.png.tiff等图片的开源解码库. apps/,包含进行

opencv 处女作

显示一幅图:主要是运用功能:imread namedWindow imshowimread:从字面意思我们就可以看懂,用来读取图片的:namedWindow:显然,我们也可以看到这是用来命名窗口名称的:imshow:这个自然就是来显示窗口的,窗口内的当然就是要显示的图片了. 代码来自OpenCV Tutorials 这个文件很好用的,推荐~代码仅供参考: #include<cv.h>   //cv.h OpenCV的主要功能头文件,务必要:#include<highgui.h> /

OpenCV基础篇之读取显示图片

程序及分析 /* * FileName : read.cpp * Author : xiahouzuoxin @163.com * Version : v1.0 * Date : Tue 13 May 2014 07:34:25 PM CST * Brief : * * Copyright (C) MICL,USTB */ #include <cv.h> #include <highgui.h> using namespace cv; using namespace std; in

模仿美图秀秀拼图应用ios源码

模仿美图秀秀拼图应用源码,这个是模仿美图秀秀拼图应用源码,模拟美图秀秀拼图功能,支持图片自由拖动,添加边框,以及不规则图形的切割,也可以说是十分不错的拼图功能实现. <ignore_js_op> <ignore_js_op> <ignore_js_op> 详细说明:http://ios.662p.com/thread-2010-1-1.html