我想使用multiband blending混合两个图像,但不清楚该函数的输入参数:
void detail::Blender::prepare(const std::vector<Point>& corners, const std::vector<Size>& sizes)
在我的情况下,我只输入了两个扭曲的图像,这些图像有黑色的间隙和带有白色的蒙版。(原谅我无法添加图片...)
并且我设置了两个角(0.0,0.0),因为翘曲的图像已被注册。
但是我的结果还不够好。
有人可以告诉我原因吗?如何解决这个问题?
最佳答案
我不确定当您说“我的成绩不够好”时是什么意思。最好看一下结果,但我会尽力猜测。我编写全景的代码的主要部分如下所示:
void makePanorama(Rect bounding_box, vector<Mat> images, vector<Mat> homographies, vector<vector<Point>> corners) {
detail::MultiBandBlender blender;
blender.prepare(bounding_box);
Mat mask, bigImage, curImage;
for (int i = 0; i < (int)images.size(); ++i) {
warpPerspective(images[i], curImage, homographies[i],
bounding_box.size(), INTER_LINEAR, ORDER_TRANSPARENT);
mask = makeMask(curImage.size(), corners[i], homographies[i]);
blender.feed(curImage.clone(), mask, Point(0, 0));
}
blender.blend(bigImage, mask);
bigImage.convertTo(bigImage, (bigImage.type() / 8) * 8);
imshow("Result", bigImage);
waitKey();
}
因此,准备
blender
,然后循环:扭曲图像,扭曲图像后制作 mask 并喂入搅拌器。最后,打开此搅拌器,仅此而已。我遇到了两个问题,这些问题严重影响了我的成绩。可能是您拥有其中之一,也可能两者都有。首先是类型。我的图像具有CV_16SC3,混合后,您需要将混合后的图像类型转换为
unsigned
one。像这样 bigImage.convertTo(bigImage, (bigImage.type() / 8) * 8);
否则,结果图像将为灰色。
第二个是边界。刚开始,我的函数makeMask用来计算变形图像的非黑色区域。结果,可以在混合图像上看到变形图像的边界。解决方案是使蒙版小于非黑色扭曲图像区域。因此,我的函数
makeMask
看起来像这样:Mat makeMask(Size sz, vector<Point2f> imageCorners, Mat homorgaphy) {
Scalar white(255, 255, 255);
Mat mask = Mat::zeros(sz, CV_8U);
Point2f innerPoint;
vector<Point2f> transformedCorners(4);
perspectiveTransform(imageCorners, transformedCorners, homorgaphy);
// Calculate inner point
for (auto& point : transformedCorners)
innerPoint += point;
innerPoint.x /= 4;
innerPoint.y /= 4;
// Make indent for each corner
vector<Point> corners;
for (int ind = 0; ind < 4; ++ind) {
Point2f direction = innerPoint - transformedCorners[ind];
double normOfDirection = norm(direction);
corners[ind].x += settings.indent * direction.x / normOfDirection;
corners[ind].y += settings.indent * direction.y / normOfDirection;
}
// Draw borders
Point prevPoint = corners[3];
for (auto& point : corners) {
line(mask, prevPoint, point, white);
prevPoint = point;
}
// Fill with white
floodFill(mask, innerPoint, white);
return mask;
}
我从真实代码中提取了这段代码,所以我可能会忘记指定一些内容。但是我希望,如何使用
MultiBandBlender
的想法很明确。