使用opencv在c ++中进行简单拼接 [英] Simple stitching in c++ using opencv

查看:189
本文介绍了使用opencv在c ++中进行简单拼接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将简单的拼接代码程序从python转移到c ++。我是初学者,我找不到c ++的这个功能。 python代码在这里:

  import cv2 
import numpy as np

def find_overlap_start (left_img,right_img):
断言left_img.shape == right_img.shape
height,width = left_img.shape [:2]
haystack = left_img
needle = right_img [: ,0:width / 2]
res = cv2.matchTemplate(haystack,needle,cv2.TM_CCORR_NORMED)
min_val,max_val,min_loc,max_loc = cv2.minMaxLoc(res)
return max_loc [ 0]

def find_overlaps(图片):
overlap_starts = []
for i in range(len(images) - 1):
overlap_starts.append(find_overlap_start (images [i],images [i + 1]))
#最后一张图片使用整个
overlap_starts.append(images [-1] .shape [1])$ ​​b $ b return overlap_starts

#简单针迹,无混合,右手切片覆盖左手切片
def stitch_images(images,overlap_starts):
height,width = images [0] .shape [ :2]
total_width = sum(o verlap_starts)
result = np.zeros((height,total_width),np.uint8)
current_column = 0
for i,以enumerate开头(overlap_starts):
result [: ,current_column:current_column + width] = images [i]
current_column + = start

返回结果

images = [cv2.imread(slice_%d。 png%i,0)for i in range(4)]

overlap_starts = find_overlaps(images)

cv2.imwrite(slices_out.png,stitch_images(images) ,overlap_starts))

到目前为止我转移了第一个函数,但我不知道它是不是好的,也不知道下一步怎么回事。这是c ++代码的开头:

  #include< iostream> 
#include< fstream>
#includeopencv2 / highgui / highgui.hpp
#include< opencv2 / stitching.hpp>
using namespace std;
使用命名空间cv;
//全局变量。
int height;
int width;

//创建找到重叠开始点的函数。
点find_overlap_start(Mat left_img,Mat right_img)
{
if(left_img.size()== right_img.size())
{
//获取行左图像的列。
height = left_img.rows;
width = left_img.cols;

//将左图复制到新变量。
Mat haystack = left_img;

//创建变量niddle =裁剪右图像。
roi.width =(left_img.size()。width)/ 2;
roi.height = left_img.size()。height;
Mat needle = right_img(roi);

//应用模板匹配并将结果存储在res中。
matchTemplate(haystack,needle,res,TM_CCORR_NORMED);
minMaxLoc(res,& minval,& maxval,& minloc,& maxloc);

return maxloc;
}
}

//创建图像开始重叠的点矢量。
vector< Point> find_overlaps(vector< Mat> images)
{
//创建重叠坐标向量。
vector< Point> overlap_starts;

//循环所有图像并获得顶部左侧的点,其中imgages ovelap。
for(int i = 0; i!= images.size() - 1; i ++)
{
//查找两个图像之间的重叠开始。
点重叠= find_overlap_start(images [i],images [i + 1]);
overlap_starts.push_back(重叠);
}

//最后一张图片全部使用:
不知道怎么做...

return overlap_starts;
}


//然后主要功能
int main(int argc,char * argv [])
{
Mat img1 = imread(image1.bmp,CV_LOAD_IMAGE_GRAYSCALE);
Mat img2 = imread(image2.bmp,CV_LOAD_IMAGE_GRAYSCALE);

点max_loc = find_overlap_start(img1,img2);

waitKey(0);
返回0;
}

我想将所有python程序转移到c ++。如果有人可以评论一些Python代码,我也会很高兴,因为我现在还不知道它是如何工作的......

解决方案

解决我自己的问题



由于没有答案我已经找到了使用<$ c进行简单图像拼接的c ++代码$ c> matchTemplate()功能。我想与您分享我的结果,以便您可以发表评论,添加一些内容或当然可以使用它。使用



结果给出了这样的信息:




I want to transfer simple stitching code program from python to c++. I am beginner and I cannot find this function for c++. The python code is here:

import cv2
import numpy as np

def find_overlap_start(left_img, right_img):
    assert left_img.shape == right_img.shape
    height, width = left_img.shape[:2]       
    haystack = left_img
    needle = right_img[:,0:width/2]   
    res = cv2.matchTemplate(haystack, needle, cv2.TM_CCORR_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    return max_loc[0]

def find_overlaps(images):
    overlap_starts = []
    for i in range(len(images) - 1):
        overlap_starts.append(find_overlap_start(images[i], images[i+1]))
    # And the last image is used whole
    overlap_starts.append(images[-1].shape[1])
    return overlap_starts

# Simple stitch, no blending, right hand slice overlays left hand slice
def stitch_images(images, overlap_starts):
    height, width = images[0].shape[:2]
    total_width = sum(overlap_starts)
    result = np.zeros((height, total_width), np.uint8)
    current_column = 0
    for i,start in enumerate(overlap_starts):
        result[:,current_column:current_column+width] = images[i]
        current_column += start

    return result

images = [cv2.imread("slice_%d.png" % i, 0) for i in range(4)]

overlap_starts = find_overlaps(images)

cv2.imwrite("slices_out.png", stitch_images(images, overlap_starts))

Soo far I transfered the first function, but I don't know if it is ok and also don't know how to go next. Here is beginning of the c++ code:

#include <iostream>
#include <fstream>
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/stitching.hpp>
using namespace std;
using namespace cv;
// Global variables.
int height;
int width;

// Create function that finds point where overlap starts.
Point find_overlap_start(Mat left_img, Mat right_img)
{
    if (left_img.size() == right_img.size())
    {
        // Get rows columns of left image.
        height = left_img.rows;
        width = left_img.cols;

        // Copy left image to new variable.
        Mat haystack = left_img;

        // Create variable niddle = cropped right image.    
        roi.width = (left_img.size().width) / 2;
        roi.height = left_img.size().height;
        Mat needle = right_img(roi);

        // Apply template matching and store result in res.
        matchTemplate(haystack, needle, res, TM_CCORR_NORMED);
        minMaxLoc(res, &minval, &maxval, &minloc, &maxloc);

        return maxloc;
    }
}

// Create vector of points where images start to overlap.
vector<Point> find_overlaps(vector<Mat> images)
{
    // Create vector of overlaps coordinates.
    vector<Point> overlap_starts;

    // Loop trought all images and get top-left points where imgages   ovelap.
    for (int i = 0; i != images.size() - 1; i++) 
    {
        // Find overlap start between two images.
        Point overlap = find_overlap_start(images[i], images[i + 1]);
        overlap_starts.push_back(overlap);
    }

    // And the last image is used whole: 
       Don't know how to do that...

    return overlap_starts;
}


// And then the main fucntion
int main(int argc, char* argv[])
{
    Mat img1 = imread("image1.bmp", CV_LOAD_IMAGE_GRAYSCALE);
    Mat img2 = imread("image2.bmp", CV_LOAD_IMAGE_GRAYSCALE);

    Point max_loc = find_overlap_start(img1, img2);

    waitKey(0);
    return 0;
}

I want to transfer all python program to c++. I would be also happy if someone can comment a bit Python code, since I don't exactly now how it works...

解决方案

WORKING ANSWER OF MY OWN QUESTION

Since there was no answer I already figured out the c++ code for simple image stitching using matchTemplate() function. I want to share my result with you so you can comment, add some stuff or of course use it. The code is transfered from python using this reference.

The code is here:

#include <iostream>
#include <fstream>
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/stitching.hpp>

using namespace std;
using namespace cv;

// Global variables.
int height;
int width;
double minval, maxval;
Point minloc, maxloc;
Rect roi;
Mat res;

// Create function that finds point where overlap between two images starts. 
// Images "left_img" and "right_img" are passed in by find_overlaps function.
Point find_overlap_start(Mat left_img, Mat right_img)
{
    // Check if the sizes of images are the same.
    if (left_img.size() == right_img.size())
    {
        // Get rows columns of left image.
        height = left_img.rows;
        width = left_img.cols;

        // Copy left image to new variable.
        Mat haystack = left_img;

        // Create matrix "neddle" to be used as our "template". 
        roi.width = (left_img.size().width) / 2;
        roi.height = left_img.size().height;
        Mat needle = right_img(roi);

        // Apply template matching and store result in res.
        matchTemplate(haystack, needle, res, TM_CCORR_NORMED);
        minMaxLoc(res, &minval, &maxval, &minloc, &maxloc);

        // Return top-left coordinate where the matching starts.
        return maxloc;
    }
}

// Create vector of points where images start to overlap.
vector<Point> find_overlaps(vector<Mat> images)
{
    // Create vector of overlaps coordinates.
    vector<Point> overlap_starts;

    for (int i = 0; i != images.size() - 1; i++) 
    {
        // Find overlap start between two images.
        Point overlap = find_overlap_start(images[i], images[i + 1]);

        // Add overlap point to vector of points.
        overlap_starts.push_back(overlap);
    }

    // Return vector of "overlaping points" (top-left).
    return overlap_starts;
}

// Simple stitch, no blending, right hand slice overlays left hand slice.
Mat stitch_images(vector<Mat> images, vector<Point> overlap_starts)
{

    // Define variable to store width of the composite image.
    int total_width = 0;

    // Loop trought vector of overlaped points and calculate total_width.
    for (int i = 0; i < images.size() - 1; i++)
    {

        // overlap_starts[i, 0].x -> x coordinates of Point in overlap_starts vector.
        total_width += overlap_starts[i, 0].x;

    }

    // Now add width of image to the total width.
    int img_width = images[0].cols;
    total_width = total_width + img_width;

    // Create matrix that is of the size ( height, total_width -> depends on the number of images).
    Mat result = Mat::zeros(Size(total_width, height), CV_8UC1);

    // Put images next to each other on the result matrix.
    int current_column = 0;
    for (int i = 0; i < images.size(); i++)
    {
        // Where to copy current image?
        images[i].copyTo(result.rowRange(0,400).colRange(current_column,( current_column+600 ) ));

        // The next image should be moved right for:
        current_column += overlap_starts[i, 0].x;
    }

    // Display composite image.
    namedWindow("result", WINDOW_AUTOSIZE);
    imshow("result", result);

    return result;
}


int main(int argc, char* argv[])
{
    // Load images from HD.
    Mat img1 = imread("pos1.bmp", CV_LOAD_IMAGE_GRAYSCALE);
    Mat img2 = imread("pos2.bmp", CV_LOAD_IMAGE_GRAYSCALE);
    Mat img3 = imread("pos3.bmp", CV_LOAD_IMAGE_GRAYSCALE);
    Mat img4 = imread("pos4.bmp", CV_LOAD_IMAGE_GRAYSCALE);
    Mat img5 = imread("pos5.bmp", CV_LOAD_IMAGE_GRAYSCALE);
    Mat img6 = imread("pos6.bmp", CV_LOAD_IMAGE_GRAYSCALE);
    Mat img7 = imread("pos7.bmp", CV_LOAD_IMAGE_GRAYSCALE);

    // Create vector of images.
    vector<Mat> various_images;
    various_images.push_back(img1);
    various_images.push_back(img2);
    various_images.push_back(img3);
    various_images.push_back(img4);
    various_images.push_back(img5);
    various_images.push_back(img6);
    various_images.push_back(img7);

    // Display loaded images if you want.
    namedWindow("img1", WINDOW_AUTOSIZE);
    imshow("img1", img1);
    namedWindow("img2", WINDOW_AUTOSIZE);
    imshow("img2", img2);
    namedWindow("img3", WINDOW_AUTOSIZE);
    imshow("img3", img3);
    namedWindow("img4", WINDOW_AUTOSIZE);
    imshow("img4", img4);
    namedWindow("img5", WINDOW_AUTOSIZE);
    imshow("img5", img5);
    namedWindow("img6", WINDOW_AUTOSIZE);
    imshow("img6", img6);
    namedWindow("img6", WINDOW_AUTOSIZE);
    imshow("img6", img6);

    // Call function find_overlaps ( find top-left points of overlaping).
    vector<Point> overlap_starts = find_overlaps(various_images);

    // Call stitch_function and stitch images together.
    stitch_images(various_images, overlap_starts);

    waitKey(0);
    return 0;
}

The code could be used for quicker stitching of images that look like this:

And the result give us this:

这篇关于使用opencv在c ++中进行简单拼接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆