首页 >> 大全

使用OPENCV3图像对齐

2023-12-27 大全 31 作者:考证青年

图1. 左:一幅来自- 的图片(未对齐);右:对齐后图像

1. 左边的图像是一个具有历史意义的照片的集合称为-集。图像是由使用一个早期的彩色摄像机拍摄。因为相机的机械性质,图像的颜色通道未对齐。右边的图像通过进行对齐后的图像。

可以从这里的下载部分中的所有示例中的所有示例代码。

在这篇文章中,我们将开始一个有趣的彩色摄影的历史。这篇文章是致力于彩色摄影的早期先驱,使我们能够捕捉和存储我们的记忆中的颜色。

2. 一个简短的彩色照片发展过程

由 和 拍摄的首张3灰度图像

由James Clerk 在1855年提出,我们可以用滤光片(红,绿,蓝)进行滤光后拍摄,然后再将这三个图片结合起来。在1861年,英国摄影师利用这个方法拍摄了第一张彩色图像。他获取了图片的三个灰度图,然后进行了叠加。但是,这个方法存在一个问题,因为当时可用的感光材料对蓝光敏感,但对绿光不敏感,对红光几乎不敏感。虽然它的实践是革命性的,但这种方法是不实际的。

到了20世纪初,感光材料的敏感度已经大大提高,并在前十年有几种相机已经可用于彩色摄影。在这些相机,最流行的彩色相机,由Lumière兄弟发明。

最具有竞争性的相机系统是由Adolf 设计,并由 制造,被称之为 Dr. ’s -。其中意为三色。同时这个相机有一个长的玻璃板,可以同时放下三色滤光片。

利用这个相机,-在长达十年的时间里拍摄了俄罗斯近10000张图片,幸运的,这些图片保留了下来。从这些黑白图像生成一个彩色图像是不平凡的(如图3所示)。 相机是一个机械装置,这三个图片的跨度超过2-6秒。因此,三频道经常失准,简单地堆积起来导致了一个很不理想,结果如图1所示。

运动模块

在一个典型的图像对齐问题,一个场景我们有两个图像,他们运动模型都是相关的。不同的图像对准算法的目的是估计这些运动模型的参数,使用不同的参数和假设。一旦这些参数是已知的,就可以直接从一幅图像变换到另一个

让我们快速看看这些运动模型看起来像什么。

():第一图像可以平移(x,y)所获得的第二图像。只有两个参数X和Y,我们需要估计。

():第一幅图像旋转和移动版本。所以有三个参数X,Y和角度。你会注意到在图4中,当一个正方形进行欧氏变换,大小不改变,平行线保持平行,并且在变换后的直角保持不变。

():仿射变换是一个组合的旋转,平移(移位),规模,和剪切。这个变换有六个参数。当一个正方形进行仿射变换时,平行线保持平行,但在直角相交的线不再保持正交。

单应性():所有上述二维变换变换。他们没有考虑到3D效果。单应变换另一方面可以考虑一些3D效果(但不是全部)。这个变换有8个参数。当一方转化使用单应能改变任何四边形。

在的仿射变换,储存在一个2 x 3大小的矩阵。平移和欧氏变换是仿射变换的特殊情况。在平移过程中,旋转、尺度和剪切参数为零,而在欧氏变换中的尺度和剪切参数都为零。因此,移动和欧氏变换也存储在一个2×3矩阵。一旦这个矩阵估计(我们将在下一节中看到),可以对图像进行功能。

单应性,存储在一个3×3矩阵。一旦单应估计,图像可以被纳入对齐使用。

使用增强的相关系数图像配准(ECC)最大化

ECC的图像对准算法中引入了 3是基于2008篇题为参量图像对齐使用增强的相关系数最大化的 D. 和 Z. 。他们建议使用一种新的相似性度量称为增强型相关系数(ECC)的运动模型的参数估计。使用他们的方法有两个优点。

不同于像素强度差异的传统的相似性度量,ECC是光度失真的对比度和亮度不变。

虽然目标函数是参数的非线性函数,但他们发展的迭代格式来求解优化问题是线性的。换言之,他们采取了一个问题,看起来在计算复杂的表面上,并找到一个简单的方法来解决它迭代。

在中使用

在中我们使用有以下步骤:

读取图像。

_opencv实现图像配准_opencv图像比对匹配

将它们转换为灰度图。

选择一个你想估计的模型。

分配空间()存储运动模型。

定义一个终止准则,告诉该算法什么时候停止。

估计使用运动矩阵。

将经矩阵应用到图像中的一个与其他图像对齐。

// Read the images to be aligned
Mat im1 = imread("images/image1.jpg");
Mat im2 = imread("images/image2.jpg");// Convert images to gray scale;
Mat im1_gray, im2_gray;
cvtColor(im1, im1_gray, CV_BGR2GRAY);
cvtColor(im2, im2_gray, CV_BGR2GRAY);// Define the motion model
const int warp_mode = MOTION_EUCLIDEAN;// Set a 2x3 or 3x3 warp matrix depending on the motion model.
Mat warp_matrix;// Initialize the matrix to identity
if ( warp_mode == MOTION_HOMOGRAPHY )warp_matrix = Mat::eye(3, 3, CV_32F);
elsewarp_matrix = Mat::eye(2, 3, CV_32F);// Specify the number of iterations.
int number_of_iterations = 5000;// Specify the threshold of the increment
// in the correlation coefficient between two iterations
double termination_eps = 1e-10;// Define termination criteria
TermCriteria criteria (TermCriteria::COUNT+TermCriteria::EPS, number_of_iterations, termination_eps);// Run the ECC algorithm. The results are stored in warp_matrix.
findTransformECC(im1_gray,im2_gray,warp_matrix,warp_mode,criteria);// Storage for warped image.
Mat im2_aligned;if (warp_mode != MOTION_HOMOGRAPHY)// Use warpAffine for Translation, Euclidean and AffinewarpAffine(im2, im2_aligned, warp_matrix, im1.size(), INTER_LINEAR + WARP_INVERSE_MAP);
else// Use warpPerspective for HomographywarpPerspective (im2, im2_aligned, warp_matrix, im1.size(),INTER_LINEAR + WARP_INVERSE_MAP);// Show final result
imshow("Image 1", im1);
imshow("Image 2", im2);
imshow("Image 2 Aligned", im2_aligned);
waitKey(0);

彩色图的重建

上面的影像也在-采集部分。左边是未对齐的RGB通道的图像,右边是调整后的图像。这张照片还显示,在第二十世纪初的照片板是敏感的,捕捉到的颜色光谱很广。鲜艳的红色,蓝色和绿色。

在前面的章节中的代码可以用来解决一个图像配准问题。然而,如果你用它来重建上述形象,你会感到非常失望。在现实世界中的计算机视觉是艰难的。

问题是,如果在一个图像中的红色,绿色和蓝色通道是不强烈相关。例如,检查出蓝色礼服的埃米尔图3穿。在三个渠道看起来有很大的不同。然而,即使强度是不同的,在三个通道中的东西是相似的,因为一个人的眼睛可以很容易地告诉它,它是相同的场景。

事实证明,在梯度域的图像的三个通道的更强烈的相关性。这并不奇怪,因为即使在三个通道中的强度可能是不同的,由对象和颜色边界所产生的边缘地图是一致的。

using namespace cv;
using namespace std;Mat GetGradient(Mat src_gray)
{Mat grad_x, grad_y;Mat abs_grad_x, abs_grad_y;int scale = 1;int delta = 0;int ddepth = CV_32FC1; ;// Calculate the x and y gradients using Sobel operatorSobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );convertScaleAbs( grad_x, abs_grad_x );Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );convertScaleAbs( grad_y, abs_grad_y );// Combine the two gradientsMat grad;addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );return grad; 

using namespace cv;
using namespace std;// Read 8-bit color image.
// This is an image in which the three channels are
// concatenated vertically.
Mat im =  imread("images/emir.jpg", IMREAD_GRAYSCALE);// Find the width and height of the color image
Size sz = im.size();
int height = sz.height / 3;
int width = sz.width; // Extract the three channels from the gray scale image
vectorchannels;
channels.push_back(im( Rect(0, 0,         width, height)));
channels.push_back(im( Rect(0, height,    width, height)));
channels.push_back(im( Rect(0, 2*height,  width, height))); // Merge the three channels into one color image
Mat im_color;
merge(channels,im_color);// Set space for aligned image.
vector aligned_channels;
aligned_channels.push_back(Mat(height, width, CV_8UC1));
aligned_channels.push_back(Mat(height, width, CV_8UC1));// The blue and green channels will be aligned to the red channel.
// So copy the red channel
aligned_channels.push_back(channels[2].clone());// Define motion model
const int warp_mode = MOTION_AFFINE;// Set space for warp matrix.
Mat warp_matrix;// Set the warp matrix to identity.
if ( warp_mode == MOTION_HOMOGRAPHY )warp_matrix = Mat::eye(3, 3, CV_32F);
elsewarp_matrix = Mat::eye(2, 3, CV_32F);// Set the stopping criteria for the algorithm.
int number_of_iterations = 5000;
double termination_eps = 1e-10;TermCriteria criteria(TermCriteria::COUNT+TermCriteria::EPS,number_of_iterations, termination_eps);// Warp the blue and green channels to the red channel
for ( int i = 0; i < 2; i++)
{double cc = findTransformECC (GetGradient(channels[2]),GetGradient(channels[i]),warp_matrix,warp_mode,criteria);if (warp_mode == MOTION_HOMOGRAPHY)// Use Perspective warp when the transformation is a HomographywarpPerspective (channels[i], aligned_channels[i], warp_matrix, aligned_channels[0].size(), INTER_LINEAR + WARP_INVERSE_MAP);else// Use Affine warp when the transformation is not a HomographywarpAffine(channels[i], aligned_channels[i], warp_matrix, aligned_channels[0].size(), INTER_LINEAR + WARP_INVERSE_MAP);} // Merge the three channels
Mat im_aligned;
merge(aligned_channels, im_aligned);// Show final output
imshow("Color Image", im_color);
imshow("Aligned Image", im_aligned);
waitKey(0);

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了