关于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

我想要做的是最终得到一个参考图像和这个转换图像的合并图像。这实际上是我的第一步。这是使用warpAffine()的转换参数的问题吗?

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

enter

相关讨论
  • 在您更新问题后 - 它与原来的不同。发布使 affine_mat 和 calss wrapAffine 的代码。澄清你的问题
  • 谢谢叶夫根尼。结果是一样的。
  • stackoverflow.com/questions/29169605/…
  • 了不起!谢谢叶夫根尼。

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

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

只需删除 '

相关讨论
  • 我以前试过这个,但参数 4 不能从"int" 转换为"cv::Size" 。

以上是关于C#:使用OpenCV的warpAffine做图像配准的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>