OpenCV-图像拼接(横向拼接&纵向拼接)
Posted 翟天保Steven
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenCV-图像拼接(横向拼接&纵向拼接)相关的知识,希望对你有一定的参考价值。
功能函数
// 图像拼接
cv::Mat ImageSplicing(vector<cv::Mat> images,int type)
{
if (type != 0 && type != 1)
type = 0;
int num = images.size();
int newrow = 0;
int newcol = 0;
cv::Mat result;
// 横向拼接
if (type == 0)
{
int minrow = 10000;
for (int i = 0; i < num; ++i)
{
if (minrow > images[i].rows)
minrow = images[i].rows;
}
newrow = minrow;
for (int i = 0; i < num; ++i)
{
int tcol = images[i].cols*minrow / images[i].rows;
int trow = newrow;
cv::resize(images[i], images[i], cv::Size(tcol, trow));
newcol += images[i].cols;
if (images[i].type() != images[0].type())
images[i].convertTo(images[i], images[0].type());
}
result = cv::Mat(newrow, newcol, images[0].type(), cv::Scalar(255, 255, 255));
cv::Range rangerow, rangecol;
int start = 0;
for (int i = 0; i < num; ++i)
{
rangerow = cv::Range((newrow - images[i].rows) / 2, (newrow - images[i].rows) / 2 + images[i].rows);
rangecol = cv::Range(start, start + images[i].cols);
images[i].copyTo(result(rangerow, rangecol));
start += images[i].cols;
}
}
// 纵向拼接
else if (type == 1) {
int mincol = 10000;
for (int i = 0; i < num; ++i)
{
if (mincol > images[i].cols)
mincol = images[i].cols;
}
newcol = mincol;
for (int i = 0; i < num; ++i)
{
int trow = images[i].rows*mincol / images[i].cols;
int tcol = newcol;
cv::resize(images[i], images[i], cv::Size(tcol, trow));
newrow += images[i].rows;
if (images[i].type() != images[0].type())
images[i].convertTo(images[i], images[0].type());
}
result = cv::Mat(newrow, newcol, images[0].type(), cv::Scalar(255, 255, 255));
cv::Range rangerow, rangecol;
int start = 0;
for (int i = 0; i < num; ++i)
{
rangecol= cv::Range((newcol - images[i].cols) / 2, (newcol - images[i].cols) / 2 + images[i].cols);
rangerow = cv::Range(start, start + images[i].rows);
images[i].copyTo(result(rangerow, rangecol));
start += images[i].rows;
}
}
return result;
}
测试代码
#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
cv::Mat ImageSplicing(vector<cv::Mat> images, int type);
int main()
{
cv::Mat src1 = imread("1.jpg");
cv::Mat src2 = imread("2.jpg");
cv::Mat src3 = imread("3.jpg");
cv::Mat src4 = imread("4.jpg");
vector<cv::Mat> images;
images.push_back(src1);
images.push_back(src2);
images.push_back(src3);
images.push_back(src4);
// 0为横向
cv::Mat result1 = ImageSplicing(images, 0);
// 1为纵向
cv::Mat result2 = ImageSplicing(images, 1);
imwrite("result1.jpg",result1);
imwrite("result2.jpg",result2);
return 0;
}
// 图像拼接
cv::Mat ImageSplicing(vector<cv::Mat> images,int type)
{
if (type != 0 && type != 1)
type = 0;
int num = images.size();
int newrow = 0;
int newcol = 0;
cv::Mat result;
// 横向拼接
if (type == 0)
{
int minrow = 10000;
for (int i = 0; i < num; ++i)
{
if (minrow > images[i].rows)
minrow = images[i].rows;
}
newrow = minrow;
for (int i = 0; i < num; ++i)
{
int tcol = images[i].cols*minrow / images[i].rows;
int trow = newrow;
cv::resize(images[i], images[i], cv::Size(tcol, trow));
newcol += images[i].cols;
if (images[i].type() != images[0].type())
images[i].convertTo(images[i], images[0].type());
}
result = cv::Mat(newrow, newcol, images[0].type(), cv::Scalar(255, 255, 255));
cv::Range rangerow, rangecol;
int start = 0;
for (int i = 0; i < num; ++i)
{
rangerow = cv::Range((newrow - images[i].rows) / 2, (newrow - images[i].rows) / 2 + images[i].rows);
rangecol = cv::Range(start, start + images[i].cols);
images[i].copyTo(result(rangerow, rangecol));
start += images[i].cols;
}
}
// 纵向拼接
else if (type == 1) {
int mincol = 10000;
for (int i = 0; i < num; ++i)
{
if (mincol > images[i].cols)
mincol = images[i].cols;
}
newcol = mincol;
for (int i = 0; i < num; ++i)
{
int trow = images[i].rows*mincol / images[i].cols;
int tcol = newcol;
cv::resize(images[i], images[i], cv::Size(tcol, trow));
newrow += images[i].rows;
if (images[i].type() != images[0].type())
images[i].convertTo(images[i], images[0].type());
}
result = cv::Mat(newrow, newcol, images[0].type(), cv::Scalar(255, 255, 255));
cv::Range rangerow, rangecol;
int start = 0;
for (int i = 0; i < num; ++i)
{
rangecol= cv::Range((newcol - images[i].cols) / 2, (newcol - images[i].cols) / 2 + images[i].cols);
rangerow = cv::Range(start, start + images[i].rows);
images[i].copyTo(result(rangerow, rangecol));
start += images[i].rows;
}
}
return result;
}
测试效果
本文提供的图像拼接函数,可以实现如“长图拼接王”这类小程序的类似功能,大家可以将该函数封装在软件中自由使用~
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!
以上是关于OpenCV-图像拼接(横向拼接&纵向拼接)的主要内容,如果未能解决你的问题,请参考以下文章
OpenCV 例程 300篇255.OpenCV 实现图像拼接