Ask Your Question
0

cv::reg::MapperGradShift produce worse result in the given test code

asked 2018-08-16 08:20:57 -0600

yode gravatar image

Actually, I have read the official documentation here about class Map in opencv to try to use the module reg. And This is my test image:

enter image description here

This is my code:

#include<opencv.hpp>
#include "opencv2/reg/mapshift.hpp"
#include "opencv2/reg/mappergradshift.hpp"
#include "opencv2/reg/mapperpyramid.hpp"

using namespace cv;
using namespace std;
using namespace cv::reg;

Mat highlight1(const Mat src, const Mat t_mask) {
    Mat srcImg = src.clone(), mask = t_mask.clone();
    threshold(mask, mask, 0, 255, THRESH_BINARY_INV + THRESH_OTSU);
    cvtColor(mask, mask, COLOR_GRAY2BGR);
    cvtColor(srcImg, srcImg, COLOR_GRAY2BGR);
    dilate(mask - Scalar(0, 0, 255), mask, Mat(), Point(-1, -1), 1);
    return srcImg - mask;
}

int main() {
    Mat img1 = imread("img.jpg", 0);
    Mat img2;

    // Warp original image
    Vec<double, 2> shift(5., 5.);
    MapShift mapTest(shift);
    mapTest.warp(img1, img2);

    // Register
    Ptr<MapperGradShift> mapper = makePtr<MapperGradShift>();
    MapperPyramid mappPyr(mapper);
    Ptr<Map> mapPtr = mappPyr.calculate(img1, img2);
    MapShift* mapShift = dynamic_cast<MapShift*>(mapPtr.get());

    // Display registration result
    Mat result;
    mapShift->inverseWarp(img2, result);
    Mat registration_before = highlight1(img1, img2);
    Mat registration_after = highlight1(img1, result);
    return 0;
}

But as we see, the registration_after is even worse than registration_before. What's I have missed?

This is registration_before:

This is registration_after:

Why I get a worse result? Is it a bug in this module of OpenCV?

edit retag flag offensive close merge delete

Comments

2

Please update your issue with one line about the root issue and saying that it has been solved.

Eduardo gravatar imageEduardo ( 2018-08-16 19:22:17 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
2

answered 2018-08-16 19:19:44 -0600

Eduardo gravatar image

updated 2018-08-16 19:26:16 -0600

This is what I get:

Registration before:

Registration before

Registration after:

Registration after


Looks like you need to convert the image to float. See the corresponding sample code and unit test.


Full code:

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/reg/mapshift.hpp>
#include <opencv2/reg/mappergradshift.hpp>
#include <opencv2/reg/mapperpyramid.hpp>

using namespace cv;
using namespace std;
using namespace cv::reg;

Mat highlight1(const Mat& src, const Mat& t_mask) {
  Mat srcImg = src.clone(), mask = t_mask.clone();
  threshold(mask, mask, 0, 255, THRESH_BINARY_INV + THRESH_OTSU);
  cvtColor(mask, mask, COLOR_GRAY2BGR);
  cvtColor(srcImg, srcImg, COLOR_GRAY2BGR);
  dilate(mask - Scalar(0, 0, 255), mask, Mat(), Point(-1, -1), 1);
  return srcImg - mask;
}

int main() {
  Mat img1 = imread("RuesS.jpg", IMREAD_GRAYSCALE);
  Mat img1_float;
  img1.convertTo(img1_float, CV_32FC1);
  Mat img2_float, img2;

  // Warp original image
  Vec<double, 2> shift(5., 5.);
  MapShift mapTest(shift);
  mapTest.warp(img1_float, img2_float);
  img2_float.convertTo(img2, CV_8UC1);

  // Register
  Ptr<MapperGradShift> mapper = makePtr<MapperGradShift>();
  MapperPyramid mappPyr(mapper);
  Ptr<Map> mapPtr = mappPyr.calculate(img1_float, img2_float);
  MapShift* mapShift = dynamic_cast<MapShift*>(mapPtr.get());

  // Display registration result
  Mat result_float, result;
  mapShift->inverseWarp(img2_float, result_float);
  result_float.convertTo(result, CV_8UC1);
  Mat registration_before = highlight1(img1, img2);
  Mat registration_after = highlight1(img1, result);

  imshow("registration_before", registration_before);
  imshow("registration_after", registration_after);
  waitKey();
  return 0;
}
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2018-08-16 08:20:57 -0600

Seen: 370 times

Last updated: Aug 16 '18