关于C#:使用OpenCV的warpAffine做图像配准

use warpAffine of OpenCV to do image registration

我正在尝试使用 ORB 功能进行图像配准。
我在使用 warpAffine 时遇到了问题。编译器告诉无法将参数 \\'1\\' 从 cv::Mat * 转换为 cv::InputArray。
这是我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#pragma once

// Standard C++ I/O library.
#include <iostream>
#include <string>
#include <iomanip>
#include <vector>


// OpenCV library.
#include <cv.h>
#include <highgui.h>

// OpenCV feature library.
#include <opencv2/opencv.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <nonfree/features2d.hpp>




// main().
int main(int argv, char ** argc)
{
    cv::Mat im_ref, im_cmp;

    std::string  str_ref, str_cmp;

    // Read reference image.
    //std::cout<<"Input reference image filename:";
    //std::cin>>str_ref;
    std::cout<<"-> Reading images."<<std::endl;
    str_ref ="F:\\\\CPPs\\\\ImageRegistration\\\\OpenCVTest\\\\206.png";

    im_ref = cv::imread(str_ref);
    cv::imshow("Reference image", im_ref);

    // Read testing image.
    //std::cout<<"Input testing image filename:";
    //std::cin>>str_cmp;
    str_cmp ="F:\\\\CPPs\\\\ImageRegistration\\\\OpenCVTest\\\\227.png";

    im_cmp = cv::imread(str_cmp);
    cv::imshow("Testing image", im_cmp);

    std::cout<<"Press any key to continue."<<std::endl;
    cvWaitKey(0);



    // Feature detection.
    std::cout<<"-> Feature detection."<<std::endl;
    std::vector <cv::KeyPoint> key_ref, key_cmp;           // Vectors for features extracted from reference and testing images.
    cv::Mat  des_ref, des_cmp;                             // Descriptors for features of 2 images.

    cv::ORB orb1;                                          // An ORB object.

    orb1(im_ref, cv::Mat(), key_ref, des_ref);             // Feature extraction.
    orb1(im_cmp, cv::Mat(), key_cmp, des_cmp);  


    // Show keypoints.
    std::cout<<"-> Show keypoints."<<std::endl;
    cv::Mat drawkey_ref, drawkey_cmp;                              // Output image for keypoint drawing.
    cv::drawKeypoints(im_ref, key_ref, drawkey_ref);               // Generate image for keypoint drawing.
    cv::imshow("Keypoints of reference", drawkey_ref);
    cv::drawKeypoints(im_cmp, key_cmp, drawkey_cmp);
    cv::imshow("Keypoints of test", drawkey_cmp);

    cvWaitKey(0);


    // Matching.
    std::cout<<"-> Matching."<<std::endl;
    cv::FlannBasedMatcher matcher1(new cv::flann::LshIndexParams(20,10,2));
    std::vector<cv::DMatch> matches1;
    matcher1.match(des_ref, des_cmp, matches1);            // Match two sets of features.

    double max_dist = 0;
    double min_dist = 100;

    // Find out the minimum and maximum of all distance.
    for( int i = 0; i < des_ref.rows; i++ )
    {
        double dist = matches1[i].distance;
        if( dist < min_dist ) min_dist = dist;
        if( dist > max_dist ) max_dist = dist;
    }

    cvWaitKey(0);


    // Eliminate relatively bad points.
    std::cout<<"-> Bad points elimination"<<std::endl;
    std::vector<cv::KeyPoint> kgood_ref, kgood_cmp;
    std::vector<cv::DMatch> goodMatch;
    for (int i=0; i<matches1.size(); i++)
    {
        if(matches1[i].distance < 2*min_dist)      // Keep points that are less than 2 times of the minimum distance.
        {
            goodMatch.push_back(matches1[i]);
            kgood_ref.push_back(key_ref[i]);
            kgood_cmp.push_back(key_cmp[i]);
        }  // end if
    } // end for
    cvWaitKey(0);


    // Calculate affine transform matrix.
    std::cout<<"-> Calculating affine transformation."<<std::endl;
    std::vector<cv::Point2f>   frm1_feature, frm2_feature;
    const int p_size = goodMatch.size();
    // * tmpP = new tmpPoint[p_size];
    cv::Point2f tmpP;


    for(int i=0; i<goodMatch.size(); i++)
    {
        tmpP.x = kgood_ref[i].pt.x;
        tmpP.y = kgood_ref[i].pt.y;
        frm1_feature.push_back(tmpP);

        tmpP.x = kgood_cmp[i].pt.x;
        tmpP.y = kgood_cmp[i].pt.y;
        frm2_feature.push_back(tmpP);
    }
    cv::Mat  affine_mat = cv::estimateRigidTransform(frm1_feature, frm2_feature, true);
    cv::Mat im_transformed;

    // Output results.
    cv::warpAffine(&im_cmp, &im_transformed, affine_mat, CV_INTER_LINEAR|CV_WARP_FILL_OUTLIERS); // error comes from here.
    cv::imshow("Transformed image", im_transformed);

    cvWaitKey(0);

    return 0;
}

在使用 Evgeniy 给出的答案之前,我已经得到了结果。
我使用的变换是

1
//cv::warpAffine( im_cmp, im_transformed, affine_mat, cv::Size(im_cmp.cols, im_cmp.rows) );

转换后的结果很奇怪enter

最后,我想在这里得到一个类似示例的结果(在不同位置拍摄的两张图像,它们最终对齐)
enter


您正在给出一个指针,但 wrapAffine 接受对 cv::Mat 的引用。
您可以像这样更改代码:

1
cv::warpAffine(im_cmp, im_transformed, affine_mat, cv::Size(), CV_INTER_LINEAR|CV_WARP_FILL_OUTLIERS);

只需删除 '