0


opencv应用——以图拼图

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家:点击跳转

一,准备图片

可以先手动分一分,有的是关键信息在中间,有的是在上面,主要就是这两种。

然后用程序先截出正方形的图片:

int main()
{
    for (int i = 1; i <= 10; i++) {
        Mat img = imread("D:/pic2/img (" + to_string(i) + ").jpg",0);
        int p = min(img.rows, img.cols);
        Mat img2 = img(Rect((img.cols - p) / 2, (img.rows - p) / 2, p, p));
        imwrite("D:/pic2/a" + to_string(i) + ".jpg",img2);
    }
    return 0;
}

截上面的:

int main()
{
    for (int i = 1; i <= 15; i++) {
        Mat img = imread("D:/pic2/img (" + to_string(i) + ").jpg",0);
        int p = min(img.rows, img.cols);
        Mat img2 = img(Rect(0, 0, p, p));
        imwrite("D:/pic2/a" + to_string(i) + ".jpg",img2);
    }
    return 0;
}

二,拼图

我们先把所有小图调整到统一的大小,然后按照亮度排序。

对于目标图像,按照分块,也分别统计亮度排序。

再根据排序结果进行匹配,把小图往对应位置填充就行了。

图片除了要做亮度匹配之外,在最后拼到大图上之前,还要做亮度调整,把整体亮度调到和分块亮度相同。

struct Nodes
{
    int t;
    int id;
    bool operator<(Nodes a) const
    {
        if (t == a.t)return id < a.id;
        return t < a.t;
    }
};

int imageSum(Mat img)
{
    int s = 0;
    for (int i = 0; i < img.rows; i++)for (int j = 0; j < img.cols; j++)
        s += img.at<uchar>(i, j);
    return s;
}

int main()
{
    const int N = 9;
    const int NUM = N * N;
    const int SIZE = N * 2000;
    const int PIX = 100;
    const int R1 = SIZE / PIX;
    const int R = R1 / N * R1 / N;
    Mat imgs[NUM];
    for (int i = 1; i <= NUM; i++) {
        imgs[i - 1] = imread("D:/pic2/img (" + to_string(i) + ").jpg", 0);
        resize(imgs[i - 1], imgs[i - 1], Size(PIX, PIX));
    }
    Mat img = imread("D:/pic2/img (74).jpg", 0);
    resize(img, img, Size(SIZE, SIZE));
    Nodes node[NUM * R];
    Nodes node2[NUM * R];
    for (int i = 0; i < NUM * R; i++) {
        node[i].t = imageSum(imgs[i % NUM]);
        node[i].id = i % NUM;
        node2[i].t = imageSum(img(Rect(i % R1 * PIX, i / R1 * PIX, PIX, PIX)));
        node2[i].id = i;
    }
    sort(node, node + NUM * R);
    sort(node2, node2 + NUM * R);
    for (int i = 0; i < NUM * R; i++)
    {
        Mat image;
        imgs[node[i].id % NUM].copyTo(image);
        image *= 1.0 * node2[i].t / node[i].t;
        image.copyTo(img(Rect(node2[i].id % R1 * PIX, node2[i].id / R1 * PIX, PIX, PIX)));
    }
    //imshow("img", img);
    imwrite("D:/pic2/ans.png", img);
    cv::waitKey(0);
    return 0;
}

拼接结果:

(头部)放大效果:

(眼睛)放大效果:

三,优化思路

1,当前所用图片较少,如果图片多一点,效果会好一点。

2,因为图片少,每个图片都被用到多次。当前是每个图片被使用的次数相同,这一点可以优化一下,自适应的选择每个图片被使用的次数,效果应该会更好。

3,要想搞成彩色的,主要问题在于图片的匹配问题。灰度图像只需要按照亮度排序即可匹配,改成彩色图像相当于从一维变成三维。

标签: 算法

本文转载自: https://blog.csdn.net/nameofcsdn/article/details/124357818
版权归原作者 csuzhucong 所有, 如有侵权,请联系我们删除。

“opencv应用&mdash;&mdash;以图拼图”的评论:

还没有评论