Opencv 图像配准与聚焦叠加
背景: 我正在寻找使用智能手机为焦点堆叠应用程序对齐图像。图像链接: 堆栈中的第一个:,堆栈中的最后一个:,最终堆栈图像: 即,图像名义上相同,但包含:Opencv 图像配准与聚焦叠加,opencv,throughput,Opencv,Throughput,背景: 我正在寻找使用智能手机为焦点堆叠应用程序对齐图像。图像链接: 堆栈中的第一个:,堆栈中的最后一个:,最终堆栈图像: 即,图像名义上相同,但包含: 当焦平面在图像之间移动时焦点的系统性变化 放大率略有变化(焦点变化时智能手机的功能!) 相机由于随机振动而轻微移动 图像需要对齐,焦点堆叠应用程序才能工作 迄今为止的进展情况: 我使用OpenCV的findTransformeC()来获得对齐。经过一些实验后,它工作得很好,例如,看看哪一个对改进扭曲矩阵的初始化有用: 在像素级对齐的图像 处理8
int scale = 1;
int scaleSmall = 4;
float scaleDiff = scaleSmall / scale;
for (i = 0; i< numImages; i++) {
file = dir + image + to_string(i) + ".jpg";
col[i] = imread(file);
resize(col[i], z[i], Size(col[i].cols/scale, col[i].rows/scale));
cvtColor(z[i], zg[i], CV_BGR2GRAY);
resize(zg[i], zgSmall[i], Size(col[i].cols / scaleSmall, col[i].rows / scaleSmall));
}
// Set a 2x3 or 3x3 warp matrix depending on the motion model.
// See https://www.learnopencv.com/image-alignment-ecc-in-opencv-c-python/
// Define the motion model
const int warp_mode = MOTION_HOMOGRAPHY;
// Initialize the matrix to identity
if (warp_mode == MOTION_HOMOGRAPHY) {
warp_init = Mat::eye(3, 3, CV_32F);
warp_matrix = Mat::eye(3, 3, CV_32F);
warp_matrix_prev = Mat::eye(3, 3, CV_32F);
scaleTX = (Mat_<float>(3, 3) << 1, 1, scaleDiff, 1, 1, scaleDiff, 1 / scaleDiff, 1 / scaleDiff, 1);
}
else {
warp_init = Mat::eye(2, 3, CV_32F);
scaleTX = Mat::eye(2, 3, CV_32F);
warp_matrix = Mat::eye(2, 3, CV_32F);
warp_matrix_prev = Mat::eye(2, 3, CV_32F);
scaleTX = (Mat_<float>(2, 3) << 1, 1, scaleDiff, 1, 1, scaleDiff);
}
// 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-8;
// Define termination criteria
TermCriteria criteria(TermCriteria::COUNT + TermCriteria::EPS, number_of_iterations, termination_eps);
for (i = 1; i < numImages; i++) {
// Check images right size
if (zg[0].rows < 10 || zg[1].rows < 10)
return;
// Run the ECC algorithm at start to get an initial guess. The results are stored in warp_matrix.
if (i == 1) {
findTransformECC(zgSmall[0], zgSmall[i], warp_init, warp_mode, criteria );
// See https://stackoverflow.com/questions/45997891/cv2-motion-euclidean-for-the-warp-mode-in-ecc-image-alignment-method
warp_matrix = warp_init * scaleTX;
}
// Warp Matrix from previous iteration is used as initialisation
findTransformECC(zg[0], zg[i], warp_matrix, warp_mode, criteria);
if (warp_mode != MOTION_HOMOGRAPHY) {
warpAffine(zg[i], ag[i], warp_matrix, zg[i].size(), INTER_LINEAR + WARP_INVERSE_MAP);
warpAffine(z[i], acol[i], warp_matrix, zg[i].size(), INTER_LINEAR + WARP_INVERSE_MAP);
}
else {
// Use warpPerspective for Homography
warpPerspective(z[i], acol[i], warp_matrix, z[i].size(), INTER_LINEAR + WARP_INVERSE_MAP);
warpPerspective(zg[i], ag[i], warp_matrix, zg[i].size(), INTER_LINEAR + WARP_INVERSE_MAP);
}
}
}
int-scale=1;
int scaleSmall=4;
float scaleDiff=缩放缩放缩放/缩放;
对于(i=0;i scaleTX=(Mat_u3,3)至少可以做3个改进:
5000次迭代可能是不必要的。尝试将其限制为500次。此外,将图像转换到渐变域可能会有所帮助。请参阅此函数中的GetGradient
函数
您可以假设透视效果可以忽略不计,因此可以将扭曲_模式
更改为运动_仿射
,以将自由度限制在8到6之间
您还可以尝试另一种更快的方法,即基于相位相关(频域)的方法。按照标准方法,它仅估计图像之间的平移,但您可以将图像传输到对数极坐标空间以获得平移、旋转和缩放不变性。这实现了第三种方法
您可以发布示例图像吗?您使用什么设置来对齐图像?也请发布代码。请参阅图像链接和插入的代码相位相关方法非常快,但我正在努力获得足够的精度。有什么想法吗?是否适合将图像与失焦和稍微失准的等效图像进行比较?