【数字图像处理|基于OpenCV的图像配准之后的透视变换】??在通过SIFT、SURF或者ORB进行特征点检测,生成了特征点和特征点描述子的vector后,如何进一步的进行对于图像的矫正。这个时候就用到了opencv的另外两个函数findHomography和perspectiveTransform。
??findHomography是用来计算两张图像的单应性矩阵的。opencv的官方文档中有详细的使用说明:
文章图片
??前两个参数分别是通过之前的特征检测找到的特征点,第三个参数为计算单应性矩阵的方法,默认为使用所有的点。第四个参数仅在第三个参数为CV_RANSAC时使用,为最大允许的特征点对间二次投影的误差。
??perspectiveTransform函数为通过单应性矩阵生成校正之后的图像。
文章图片
??前两个参数为原始图像和矫正之后的图像的点的集合。只能为2维或3维的向量。这里的点的集合指的是图像的位置排布,和像素值没有任何关系。第三个参数即为之前求出的单应性矩阵。
??注意:生成的矫正图像为点的集合,即为vector向量,并不是图像,生成的只是原始图像与校正图像的位置对应关系,图像的生成在下面的例子中会说明。
示例:
int main()
{
Mat img_1 = imread("00068.jpg");
Mat img_2 = imread("00069.jpg");
if (!img_1.data || !img_2.data)
{
cout << "error reading images " << endl;
return -1;
}ORB orb;
vector keyPoints_1, keyPoints_2;
Mat descriptors_1, descriptors_2;
orb(img_1, Mat(), keyPoints_1, descriptors_1);
orb(img_2, Mat(), keyPoints_2, descriptors_2);
BruteForceMatcher matcher;
vector matches;
matcher.match(descriptors_1, descriptors_2, matches);
double max_dist = 0;
double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for( int i = 0;
i < descriptors_1.rows;
i++ )
{
double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
printf("-- Max dist : %f \n", max_dist );
printf("-- Min dist : %f \n", min_dist );
//-- Draw only "good" matches (i.e. whose distance is less than 0.6*max_dist )
//-- PS.- radiusMatch can also be used here.
std::vector< DMatch > good_matches;
vector leftPoint,rightPoint;
for( int i = 0;
i < descriptors_1.rows;
i++ )
{
if( matches[i].distance < 0.6*max_dist )
{
good_matches.push_back( matches[i]);
leftPoint.push_back(keyPoints_1[matches[i].queryIdx].pt);
//保存左图像的关键点
rightPoint.push_back(keyPoints_2[matches[i].trainIdx].pt);
//保存右图像的关键点
}
}Mat Homography = findHomography(leftPoint,rightPoint,CV_RANSAC,3);
//生成单应性矩阵
cout< CorrectImg;
//根据单应性矩阵校正之后的点
vector ponits;
//保存图像的所有的点
for(int i=0;
i(i);
for(int j=0;
j= img_1.cols || y >= img_1.rows)
{
count++;
continue;
}
uchar* t = img_trans.ptr(y);
t[x*3]= p[j*3];
t[x*3+1]= p[j*3+1];
t[x*3+2]= p[j*3+2];
count++;
}
}imshow("CorrectImg",img_trans);
waitKey();
return 0;
}
推荐阅读
- 图像处理|Opencv学习笔记 透视变换(perspective transform)
- 数字图像处理|灰度图像--图像分割 阈值处理之OTSU阈值
- 数字图像处理|数字图像处理5(图像金字塔)
- 控制算法|惯性测量单元IMU基础
- opencv图像处理(七)sobel、Laplacian
- Opencv|移动平均的阈值处理 opencv实现
- 数字图像处理|Kirsch边缘检测原理
- 数字图像处理|二值图像--形态学处理4 击中,边界提取,孔洞填充,连通分量提取,凸壳,细化,骨架,形态学重建
- opencv|C++实现最简单的边缘连接(局部处理)