如何根据OpenCV

时间:2017-01-11 15:08:18

标签: c++ opencv image-processing computer-vision image-stitching

我是OpenCV的新手,我已经开始深入研究它了。但我需要一些帮助。

所以我想结合这两张图片:

enter image description here

我希望2个图像沿着它们的边缘匹配(暂时忽略图像的右边部分)

有人可以指出我正确的方向吗?我尝试过使用findTransformECC函数。这是我的实施:

cv::Mat im1 = [imageArray[1] CVMat3];
cv::Mat im2 = [imageArray[0] CVMat3];

// Convert images to gray scale;
cv::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 = cv::MOTION_AFFINE;

// Set a 2x3 or 3x3 warp matrix depending on the motion model.
cv::Mat warp_matrix;

// Initialize the matrix to identity
if ( warp_mode == cv::MOTION_HOMOGRAPHY )
    warp_matrix = cv::Mat::eye(3, 3, CV_32F);
else
    warp_matrix = cv::Mat::eye(2, 3, CV_32F);

// Specify the number of iterations.
int number_of_iterations = 50;

// Specify the threshold of the increment
// in the correlation coefficient between two iterations
double termination_eps = 1e-10;

// Define termination criteria
cv::TermCriteria criteria (cv::TermCriteria::COUNT+cv::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.
cv::Mat im2_aligned;

if (warp_mode != cv::MOTION_HOMOGRAPHY)
    // Use warpAffine for Translation, Euclidean and Affine
    warpAffine(im2, im2_aligned, warp_matrix, im1.size(), cv::INTER_LINEAR + cv::WARP_INVERSE_MAP);
else
    // Use warpPerspective for Homography
    warpPerspective (im2, im2_aligned, warp_matrix, im1.size(),cv::INTER_LINEAR + cv::WARP_INVERSE_MAP);


UIImage* result =  [UIImage imageWithCVMat:im2_aligned];
return result;

我尝试使用termination_epsnumber_of_iterations来增加/减少这些值,但它们并没有真正发挥重大作用。

所以这是结果:

enter image description here

我可以做些什么来改善我的结果?

编辑:我用红色圆圈标记了有问题的边缘。目标是扭曲底部图像并使其与上图中的线条匹配:

enter image description here

我做了一些研究,我担心findTransformECC函数不会给我我想要的结果: - (

要添加的重要内容: 我实际上有一个这些图像“条纹”的数组,在这种情况下,它们看起来类似于这里显示的图像,它们都需要被处理以匹配线。我尝试过试验OpenCV的stitch功能,但结果很糟糕。

编辑:

以下是3个源图像:

1

2

3

结果应该是这样的:

result

我沿着应该匹配的线条转换了每个图像。可以忽略彼此相距太远的线(阴影和图像右侧部分的道路)

2 个答案:

答案 0 :(得分:5)

通过您的图片,它们似乎重叠了。既然你说stitch函数没有得到你想要的结果,那就实现你自己的拼接。我也试图做一些接近这一点的事情。这是一个如何在c ++中实现它的教程:https://ramsrigoutham.com/2012/11/22/panorama-image-stitching-in-opencv/

答案 1 :(得分:3)

你可以在两个图像上使用具有高阈值的Hough算法,然后比较两个图像上的垂直线 - 它们中的大多数应该移位一点,但保持角度。

这是我在其中一张图片上运行此算法所得到的:

Houghlines algorithm on first example

过滤水平线应该很容易(因为它们表示为Vec4i),然后你可以将其余的线对齐在一起。

以下是OpenCV's documentation中使用它的示例。

更新:另一个想法。将线对齐在一起可以使用类似于互相关函数如何工作的概念来完成。如果图片1有10行并且图片2有100行没关系,大多数行对齐的移位(大多数是CCF的最大值)应该非常接近答案虽然这可能需要一些调整 - 例如根据其长度,角度等对每条线赋予重量。计算机视觉永远不会有直接的方式,呵呵:)

更新2:我实际上想知道将顶部图像的底部像素线作为阵列1并将底部图像的顶部像素线作为阵列2并在它们上运行一般CCF,然后使用其最大值作为移位也可以工作...但我认为如果它运作良好将是一种已知的方法。