Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OpenCV中心单应_C++_Opencv_Image Stitching - Fatal编程技术网

C++ OpenCV中心单应

C++ OpenCV中心单应,c++,opencv,image-stitching,C++,Opencv,Image Stitching,我正在尝试创建一个缝合算法。我已经成功地创建了它与一些调整需要。下面的照片是迄今为止我的缝合程序的示例。我可以为它提供一个无序的图像列表(只要图像在飞行路径上或并排排列,无论它们彼此的方向如何,它都可以工作)。 问题是,如果图像被反转,部分图像无法进入最终产品。以下是实际缝合的代码。假设找到关键点、匹配和单应性正确完成 通过修改这段代码,有没有一种方法可以将第一个图像放在目标空白图像的中心,然后仍然缝合到它。另外,我在stack overflow()上得到了这段代码,我不完全确定它是如何工作的

我正在尝试创建一个缝合算法。我已经成功地创建了它与一些调整需要。下面的照片是迄今为止我的缝合程序的示例。我可以为它提供一个无序的图像列表(只要图像在飞行路径上或并排排列,无论它们彼此的方向如何,它都可以工作)。

问题是,如果图像被反转,部分图像无法进入最终产品。以下是实际缝合的代码。假设找到关键点、匹配和单应性正确完成

通过修改这段代码,有没有一种方法可以将第一个图像放在目标空白图像的中心,然后仍然缝合到它。另外,我在stack overflow()上得到了这段代码,我不完全确定它是如何工作的,如果有人能解释一下,我会很高兴的

提前谢谢你的帮助

Mat stitchMatches(Mat image1,Mat image2, Mat homography){
    Mat result;
    vector<Point2f> fourPoint;
    //-Get the four corners of the first image (master)
    fourPoint.push_back(Point2f (0,0));
    fourPoint.push_back(Point2f (image1.size().width,0));
    fourPoint.push_back(Point2f (0, image1.size().height));
    fourPoint.push_back(Point2f (image1.size().width, image1.size().height));
    Mat destination;
    perspectiveTransform(Mat(fourPoint), destination, homography);

    double min_x, min_y, tam_x, tam_y;
    float min_x1, min_x2, min_y1, min_y2, max_x1, max_x2, max_y1, max_y2;
    min_x1 = min(fourPoint.at(0).x, fourPoint.at(1).x);
    min_x2 = min(fourPoint.at(2).x, fourPoint.at(3).x);
    min_y1 = min(fourPoint.at(0).y, fourPoint.at(1).y);
    min_y2 = min(fourPoint.at(2).y, fourPoint.at(3).y);
    max_x1 = max(fourPoint.at(0).x, fourPoint.at(1).x);
    max_x2 = max(fourPoint.at(2).x, fourPoint.at(3).x);
    max_y1 = max(fourPoint.at(0).y, fourPoint.at(1).y);
    max_y2 = max(fourPoint.at(2).y, fourPoint.at(3).y);
    min_x = min(min_x1, min_x2);
    min_y = min(min_y1, min_y2);
    tam_x = max(max_x1, max_x2);
    tam_y = max(max_y1, max_y2);

    Mat Htr = Mat::eye(3,3,CV_64F);
    if (min_x < 0){
         tam_x = image2.size().width - min_x;
         Htr.at<double>(0,2)= -min_x;
    }
    if (min_y < 0){
        tam_y = image2.size().height - min_y;
        Htr.at<double>(1,2)= -min_y;
    }


    result = Mat(Size(tam_x*2,tam_y*2), CV_32F);
    warpPerspective(image2, result,     Htr, result.size(), INTER_LINEAR, BORDER_CONSTANT,   0);
    warpPerspective(image1, result, (Htr*homography), result.size(), INTER_LINEAR, BORDER_TRANSPARENT,0);
    return result;`
Mat缝合匹配(Mat图像1、Mat图像2、Mat单应){
Mat结果;
矢量四点;
//-获取第一个图像的四个角(主图像)
四点推回(点2f(0,0));
四点。向后推(点2f(image1.size().width,0));
四点。向后推(点2F(0,image1.size().height));
四点。推回(点2F(image1.size().width,image1.size().height));
目的地;
透视变换(Mat(四点)、目标、单应);
双重最小值x,最小值y,最小值x,最小值y;
浮动最小值x1、最小值x2、最小值y1、最小值y2、最大值x1、最大值x2、最大值y1、最大值y2;
min_x1=min(在(0.x)处的四点,在(1.x)处的四点);
min_x2=min(在(2.x)处的四点,在(3.x)处的四点);
min_y1=min(在(0.y)处的四点,在(1.y)处的四点);
min_y2=min(四点在(2.y),四点在(3.y);
max_x1=max(四点在(0.x)处,四点在(1.x)处);
max_x2=max(四点在(2.x)处,四点在(3.x)处);
max_y1=max(四点在(0.y)处,四点在(1.y)处);
max_y2=max(四点在(2.y)处,四点在(3.y)处);
最小值x=最小值(最小值x1,最小值x2);
最小值y=最小值(最小值y1,最小值y2);
tam_x=max(max_x1,max_x2);
tam_y=max(max_y1,max_y2);
Mat Htr=Mat::eye(3,3,CV_64F);
如果(最小值x<0){
tam_x=image2.size().width-min_x;
在(0,2)=-min_x;
}
如果(最小值小于0){
tam_y=image2.size().height-min_y;
在(1,2)处的Htr=最小值;
}
结果=垫(尺寸(tam_x*2,tam_y*2),CV_32F);
warpPerspective(图像2,结果,Htr,结果.size(),内部线性,边界常数,0);
透视图(图像1,结果,(Htr*单应性),结果.size(),内部线性,边界透明,0);
返回结果`

通常很容易将图像居中;您只需创建一个较大的矩阵,用零填充(或任何您想要的颜色),并在中心定义一个与图像大小相同的ROI,然后将其放置其中。但是,通常不能对两个图像执行此操作。问题是,如果图像发生移动或旋转,使其部分超出目标图像边界,则从
warpPerspective
返回的扭曲图像将被切断t这些边界。您需要做的是创建填充图像,插入未扭曲的图像,然后通过向这些像素添加平移来修改变换(在本例中为单应性)

例如,如果居中图像的左上角点位于填充图像中的
(400500)
,则需要将
(400500)
的平移添加到单应性,以便将像素映射到正确的空间,并且只要填充图像足够大,就不会切断任何一个

您将需要创建一个平移单应性,并将其与原始单应性组合以添加平移。例如,假设填充图像中非扭曲图像的定位点位于
(x,y)
。单应翻译由最后两列给出;如果单应翻译为
3x3
矩阵
H
,则(使用常规数学索引)
H(1,3)
x
H(2,3)中的翻译
是您的单应词在
y
中给出的翻译。因此,我们需要创建一个新的标识单应词
H\u t
,并将这些翻译添加到:

      1 0 x
H_t = 0 1 y
      0 0 1
然后,您可以使用原始单应
H
(使用矩阵乘法):
H\u n=H\u t*H
。使用新的单应
H\u n
,我们可以像往常一样使用
warpPerspective
将图像扭曲到这个填充空间,并添加平移,以将其移动到正确的位置


您还可以自动执行此操作,以便根据需要精确填充图像,这样您就不会有多余的填充空间,填充空间只会根据需要拉伸。有关如何计算并将图像扭曲到填充空间的详细说明,请参阅我的答案。

主题外:看起来您一直很开心。不久前查看了此内容在开始另一项工作之前,用无人机检测输油管道泄漏。不知道是否有人建造过。你说的“反向”是什么意思?可能的重复我把它标记为重复。一点也不坏,但我。希望这能帮到你!KjMag-反向我指的是图像导入程序的顺序。我希望它是be无论顺序如何,都能将图像缝合在一起(如果最左边的图像是第一个或最右边的图像是第一个)。感谢您提供的这些很棒的建议和资源。这其中的数学方面对我来说有点重要,但我已经做到了。感谢您的帮助。@C.Radford没问题,这不是太多的数学,只是一点线性代数。即使如此,您所需要知道的就是同音字将您当前的像素通过矩阵mul映射到新的位置应用。
warpPerspective
执行此操作,然后将像素值(颜色)放置在新位置。我基本上建议的是将目标图像放置在一个大的零矩阵的中心,并告诉单应矩阵有多少padd