使用opencv

时间:2017-03-20 13:49:52

标签: opencv image-processing visual-studio-2015

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

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))

到目前为止,我转移了第一个功能,但我不知道它是否正常,也不知道下一步该怎么做。这是c ++代码的开头:

#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;
}

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

1 个答案:

答案 0 :(得分:3)

解决我自己的问题

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

代码在这里:

#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;
}

该代码可用于快速拼接如下图像:

enter image description here

结果给了我们这个:

enter image description here