1

I'm not familiar with opencv, but I need to use the function ‘remap’ to rectify the image. I have an image with 960x1280, and a remap file called ‘remap.bin’ with 9.8MB(is equaled to 960x1280x4x2, which means the two floats in one position(x,y));

Applies a generic geometrical transformation to an image.

C++: void remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())

map1 – The first map of either (x,y) points or just x values having the type CV_16SC2 , CV_32FC1 , or CV_32FC2 . See convertMaps() for details on converting a floating point representation to fixed-point for speed.
map2 – The second map of y values having the type CV_16UC1 , CV_32FC1 , or none (empty map if map1 is (x,y) points), respectively.

According to the explain, I code like this:

int main(int argc, char* argv[]){
    if(argc != 3){
        printf("Please enter one path of image and one path of mapdata!\n");
        return 0;
    }
    std::string image_path = argv[1];
    char* remap_path = argv[2];

    cv::Mat src = cv::imread(image_path); 
    cv::Mat dst;
    dst.create( src.size(), src.type());

    cv::Mat map2;
    map2.create( src.size(), CV_32FC1);
    map2.data = NULL;

    cv::Mat mapXY;
    mapXY.create( src.rows, src.cols, CV_64FC1);

    FILE *fp;
    fp = fopen(remap_path, "rb");
    fread(mapXY.data, sizeof(float), mapXY.cols*mapXY.rows*2, fp);
    fclose(fp);


    imshow("src", src);
    printf("remap!\n");
    cv::remap(src, dst, mapXY, map2, cv::INTER_LINEAR);
    imshow("dst", dst);

    cv::waitKey(0);
    return 0;

But when I run the program I get this error:

OpenCV Error: Assertion failed (((map1.type() == CV_32FC2 || map1.type() == CV_16SC2) && !map2.data) || (map1.type() == CV_32FC1 && map2.type() == CV_32FC1)) in remap, file /home/liliming/opencv-2.4.13/modules/imgproc/src/imgwarp.cpp, line 3262 terminate called after throwing an instance of 'cv::Exception' what(): /home/liliming/opencv-2.4.13/modules/imgproc/src/imgwarp.cpp:3262: error: (-215) ((map1.type() == CV_32FC2 || map1.type() == CV_16SC2) && !map2.data) || (map1.type() == CV_32FC1 && map2.type() == CV_32FC1) in function remap Aborted (core dumped)

I have no idea about it. Could anyone help me? or give some sample codes? Thank you very much!

Jonas
  • 6,915
  • 8
  • 35
  • 53
zac
  • 111
  • 1
  • 9
  • You can see [THIS SO ANSWER](http://stackoverflow.com/questions/10364201/image-transformation-in-opencv) – Jeru Luke Jan 20 '17 at 12:05
  • Thanks, I can use the remap with two parameters( mapX and mapY), but I don't know how to use the remap with one parameter(mapXY). – zac Jan 22 '17 at 02:16

2 Answers2

1

The documentation for OpenCV 3.1 says:

map1    The first map of either (x,y) points or just x values having the type 
CV_16SC2 , CV_32FC1, or CV_32FC2.

The assert says that map1 doesn't have a type of CV_32FC2 This is because you are creating and reading it with a type of CV_64FC1.

You need to convert it to the correct type: array of two dimensions of type CV_32FC2 (two 32-bit floats per element.)

The documentation goes on to say:

See `convertMaps` for details on converting a 
floating point representation to fixed-point for speed.

Documentation can be found here: https://docs.opencv.org/3.1.0/da/d54/group__imgproc__transform.html#gab75ef31ce5cdfb5c44b6da5f3b908ea4

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
Jon Watte
  • 6,579
  • 4
  • 53
  • 63
0

I separate the remap table into two tables remapX, remapY. Like this:

float *data_xy = (float *)malloc(sizeof(float)*960*1280*2);

FILE *fp;
fp = fopen(remap_path, "rb");
fread(data_xy, sizeof(float), 960*1280*2, fp);
fclose(fp);

for(int y=0; y<1280; ++y){
    for(int x=0; x<960; ++x){
        map_x.at<float>(y, x) = data_xy[(y*960+x)*2];
        map_y.at<float>(y, x) = data_xy[(y*960+x)*2+1];
    }
}

And then use the

cv::remap(src, dst, map_x, map_y, cv::INTER_LINEAR);

It works well. But I don't know how to use one parameter map1 to finish remap.

zac
  • 111
  • 1
  • 9