如何在opencv中使用多频段Blender

use*_*665 1 c++ opencv blending

我想使用多波段混合来混合两个图像,但我不清楚这个函数的输入参数:

void detail::Blender::prepare(const std::vector<Point>& corners, const std::vector<Size>& sizes)
Run Code Online (Sandbox Code Playgroud)

在我的情况下,我只输入两个带有黑色间隙的扭曲图像,并且带有全部白色的面具.(原谅我无法添加图片......)

我设置了两个角(0.0,0.0),因为已经注册了扭曲的图像.

但是我的结果还不够好.结果中有明显的缝隙

谁能告诉我为什么?我怎么能解决这个问题?

Rom*_*anS 5

当你说"我的结果不够好"时,我不确定你是什么意思.观察结果会更好,但我会猜测.我制作全景图的代码的主要部分如下所示:

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();
}
Run Code Online (Sandbox Code Playgroud)

因此,准备blender然后循环:扭曲图像,在扭曲图像和饲料搅拌器后制作面具.最后,打开这个搅拌机就可以了.我遇到了两个问题,严重影响了我的结果.可能是你有一个或两个.

第一种是类型.我的图像有CV_16SC3,混合后你需要将混合图像类型转换成unsigned一个.像这样

  bigImage.convertTo(bigImage, (bigImage.type() / 8) * 8);
Run Code Online (Sandbox Code Playgroud)

如果不是,结果图像将为灰色.

第二是边界.一开始,我的函数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;
}
Run Code Online (Sandbox Code Playgroud)

我从我的真实代码中获取了这些代码,所以我可能忘记指定一些东西.但我希望,如何合作的想法MultiBandBlender是明确的.