Как использовать многополосный блендер в opencv

Я хочу смешать два изображения, используя многоканальное смешение но мне не понятен входной параметр этой функции:

void detail::Blender::prepare(const std::vector<Point>& corners, const std::vector<Size>& sizes)

В моем случае я просто ввожу два искаженных изображения с черным зазором и полностью белыми масками (извините, я не могу добавить картинки...)

И я установил два угла (0.0,0.0), потому что деформированные изображения были зарегистрированы.

но мой результат недостаточно хорош. с очевидным швом в результате

может кто-нибудь сказать мне, почему? Как я могу решить эту проблему?


person user4864665    schedule 05.05.2015    source источник
comment
Без реального примера вам трудно помочь.   -  person Adi Shavit    schedule 05.05.2015


Ответы (1)


Я не уверен, что вы имеете в виду, когда говорите «мой результат недостаточно хорош». Лучше смотреть на этот результат, но я попробую угадать. Моя основная часть кода, которая делает панораму, выглядит так:

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, а затем зациклите: деформируйте изображение, сделайте маску после деформированного изображения и загрузите блендер. В конце включите этот блендер и все. Я столкнулся с двумя проблемами, которые плохо повлияли на мой результат. Может быть, у вас есть один из них или оба.

Первый — тип. У моих изображений был CV_16SC3, и после смешивания вам нужно преобразовать смешанный тип изображения в unsigned. Как это

  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 ясна.

person RomanS    schedule 22.12.2015