图像处理中有一种操作是“拼接图像”,直观解释就是“百度地图的街景图”。
最近做东西用到的不是“拼接”,而是“对接”,这个相对简单的多,但是一开始由于水平不够,还是费了不少劲,最后终于搞出来,这里做个备忘。
“对接”的目的是把几张图片平铺开来。
使用的是cv::Mat::copyTo(OutputArray m, InputArray mask) const,OpenCV3.4.0对copyTo()的解释如下:
cv::Mat::copyTo(OutputArray m, InputArray mask) const
/*This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.
Parameters
m Destination matrix. If it does not have a proper size or type before the operation, it is reallocated.
mask Operation mask of the same size as *this. Its non-zero elements indicate which matrix elements need to be copied.
The mask has to be of type CV_8U and can have 1 or multiple channels.*/
基本思路如下:
先构造一个足够大的空的“黑布”,在这个黑布上画好特定的“区域 X”(ROI),然后把要“对接”的图像x填充(copyTo)到对应的区域X上去。
代码如下:
bool procPics(cv::Mat&_m0, cv::Mat&_m1, cv::Mat&_m2, cv::Mat&_m3, cv::Mat&_matDst, int procMode)
{
try
{
//"目"字形对接
if (0 == procMode)
{
_matDst = Mat::zeros(cv::Size(_m0.cols * 4, _m0.rows), _m0.type());
Mat roiImg, mask;
Rect rt0(0, 0, _m0.cols, _m0.rows)
, rt1(_m0.cols, 0, _m1.cols, _m1.rows)
, rt2(_m0.cols * 2, 0, _m2.cols, _m2.rows)
, rt3(_m0.cols * 3, 0, _m3.cols, _m3.rows);
mask = Mat::ones(cv::Size(_m0.cols, _m0.rows), CV_8U);
roiImg = _matDst(rt0);
_m0.copyTo(roiImg, mask);
roiImg = _matDst(rt1);
_m1.copyTo(roiImg, mask);
roiImg = _matDst(rt2);
_m2.copyTo(roiImg, mask);
roiImg = _matDst(rt3);
_m3.copyTo(roiImg, mask);
}
else if (1 == procMode)
{
//"田"字形对接
//do something
}
else
return false;
}
catch (const cv::Exception&)
{
return false;
}
return true;
}
效果图如下: