基于模板的图像拼接,用拼接原图后拼接热力图

import glob
import time
import numpy as np
import matplotlib.pyplot as plt
import cv2
import os
import threading

def stitch(index, images, outResult, outResult1, images_output):
    result = images[0]  # 将第一张图像作为初始结果
    number = len(images)
    result1 = images_output[index*number]  # 将第一张图像作为初始结果
    for i in range(1, len(images)):  # 从第二张图像开始遍历

        imageLeft = result
        imageRight = images[i]

        imageLeft1 = result1
        imageRight1 = images_output[index*number + i]

        if imageLeft is None or imageRight is None:
            print("NOTICE: No images")
        else:
            ImageLeft_gray = cv2.cvtColor(imageLeft, cv2.COLOR_BGR2GRAY)
            ImageRight_gray = cv2.cvtColor(imageRight, cv2.COLOR_BGR2GRAY)

            # 获取图像长宽
            height_Left, width_left = ImageLeft_gray.shape[:2]
            height_Right, width_Right = ImageRight_gray.shape[:2]
            beishu = height_Left / 5120
            height = int(1000 * beishu)

            # 模板区域
            left_width_begin = int(width_left - int(2000 * beishu))
            left_height_begin = height
            template_left = imageLeft[int(left_height_begin):int(2 * height_Left / 3),
                            int(left_width_begin): int(width_left - int(100 * beishu))]

            # 右边匹配区域
            match_right = imageRight[0:height_Right, 0: int(2 * width_Right / 3)]

            # 执行模板匹配,采用的匹配方式cv2.TM_CCOEFF_NORMED
            matchResult = cv2.matchTemplate(match_right, template_left, cv2.TM_CCOEFF_NORMED)
            # 归一化处理
            cv2.normalize(matchResult, matchResult, 0, 1, cv2.NORM_MINMAX, -1)
            # 寻找矩阵(一维数组当做向量,用Mat定义)中的最大值和最小值的匹配结果及其位置
            min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(matchResult)

            # 设置最终图片大小
            dstStitch = np.zeros((height_Left, width_Right + left_width_begin - max_loc[0], 3), imageLeft.dtype)
            dstStitch1 = np.zeros((height_Left, width_Right + left_width_begin - max_loc[0], 3), imageLeft1.dtype)
            height_dst, width_dst = dstStitch.shape[:2]

            # copy left image
            dstStitch[0:height_Left, 0:width_left] = imageLeft.copy()

            dstStitch1[0:height_Left, 0:width_left] = imageLeft.copy()

            # 匹配右图的高要能和目标区域一样
            matchRight_H = height_Right - max_loc[1] + left_height_begin

            if height_dst == matchRight_H:
                matchRight = imageRight[int(max_loc[1] - left_height_begin): int(height_Right),
                             int(max_loc[0]):int(width_Right)]
                matchRight = matchRight[:, int(1000 * beishu):]

                matchRight1 = imageRight1[int(max_loc[1] - left_height_begin): int(height_Right),
                             int(max_loc[0]):int(width_Right)]
                matchRight1 = matchRight1[:, int(1000 * beishu):]

            elif height_dst < matchRight_H:
                dst_y_start = (left_height_begin - max_loc[1])
                # 定义平移矩阵
                M = np.float32([[1, 0, 0], [0, 1, dst_y_start]])  # 向上平移 dst_y_start个像素
                # 应用平移矩阵
                rows, cols, _ = imageRight.shape
                matchRight = cv2.warpAffine(imageRight, M, (cols, rows))
                matchRight = matchRight[0: height_Right, max_loc[0]:width_Right]
                matchRight = matchRight[:, int(1000 * beishu):]

                matchRight1 = cv2.warpAffine(imageRight1, M, (cols, rows))
                matchRight1 = matchRight1[0: height_Right, max_loc[0]:width_Right]
                matchRight1 = matchRight1[:, int(1000 * beishu):]
            else:
                dst_y_start = (left_height_begin - max_loc[1])
                # 定义平移矩阵
                M = np.float32([[1, 0, 0], [0, 1, dst_y_start]])  # 向下平移 dst_y_start个像素
                # 应用平移矩阵
                rows, cols, _ = imageRight.shape
                matchRight = cv2.warpAffine(imageRight, M, (cols, rows))
                matchRight = matchRight[0: height_Right, max_loc[0]:width_Right]
                matchRight = matchRight[:, int(1000 * beishu):]

                matchRight1 = cv2.warpAffine(imageRight1, M, (cols, rows))
                matchRight1 = matchRight1[0: height_Right, max_loc[0]:width_Right]
                matchRight1 = matchRight1[:, int(1000 * beishu):]

            drawRightRect = imageRight.copy()
            drawRightRect1 = imageRight1.copy()

            h, w = template_left.shape[:2]
            cv2.rectangle(drawRightRect, (max_loc[0], max_loc[1]), (max_loc[0] + w, max_loc[1] + h), (0, 0, 255), 1)
            cv2.rectangle(drawRightRect1, (max_loc[0], max_loc[1]), (max_loc[0] + w, max_loc[1] + h), (0, 0, 255), 1)

            height_mr, width_mr = matchRight.shape[:2]
            dstStitch[0:height_dst,
            left_width_begin + int(1000 * beishu):width_mr + int(1000 * beishu) + left_width_begin] = matchRight.copy()

            dstStitch1[0:height_dst,
            left_width_begin + int(1000 * beishu):width_mr + int(1000 * beishu) + left_width_begin] = matchRight1.copy()
            result = dstStitch
            result1 = dstStitch1
        # file_name = f'E:/camera/pailei/{i}.jpg'  # 使用f-string创建不同的文件名
        # plt.imsave(file_name, cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
    result = cv2.rotate(result, cv2.ROTATE_90_COUNTERCLOCKWISE)
    result1 = cv2.rotate(result1, cv2.ROTATE_90_COUNTERCLOCKWISE)

    outResult.update({str(index): result})
    outResult1.update({str(index): result1})

def stitch_start(input, output , number):
    if "\\" in input[0]:
        input = sorted(input, key=lambda x: int(x.split("\\")[-1][:-4]))
    else:
        input = sorted(input, key=lambda x: int(x.split("/")[-1][:-4]))

    if "\\" in output[0]:
        output = sorted(output, key=lambda x: int(x.split("\\")[-1][:-4]))
    else:
        output = sorted(output, key=lambda x: int(x.split("/")[-1][:-4]))

    images_output = []
    for filename1 in output:

        image = cv2.imread(filename1)  # 使用OpenCV库读取图像文件

        images_output.append(image)  # 将图像添加到列表中



    images = []  # 用来存储读取的图像
    for filename in input:

        image = cv2.imread(filename)  # 使用OpenCV库读取图像文件
        images.append(image)  # 将图像添加到列表中
    beishu = images[1].shape[0] / 5120


    imgs = {}
    row_imgs = []
    size = len(images)//number
    for i in range(size):
        for j in range(number):
            row_imgs.append(images[i*number+j])
        imgs.update({str(i): row_imgs})
        row_imgs = []
    # images2 = []  # 用来存储读取的图像

    row_stitch_img = {}
    row_stitch_img1 = {}
    thread_list = []
    for i in range(size):
        images = imgs[str(i)]

        th = threading.Thread(target = stitch, args=(i, images, row_stitch_img, row_stitch_img1,images_output,))
        thread_list.append(th)
        th.start()


    for th in  thread_list:
        th.join()

        # result = stitch(images,)
        # images2.append(result)


    if len(row_stitch_img) != 0 :
        result = row_stitch_img[str(0)]  # 将第一张图像作为初始结果
        result1 = row_stitch_img1[str(0)]  # 将第一张图像作为初始结果
    n = 0
    if len(row_stitch_img) != 0:
        for i in range(1, len(row_stitch_img)):  # 从第二张图像开始遍历
            imageLeft = result
            imageRight = row_stitch_img[str(i)]

            imageLeft1 = result1
            imageRight1 = row_stitch_img1[str(i)]

            # 获取图像长宽
            height_Left, width_left = imageLeft.shape[:2]
            height_Right, width_Right = imageRight.shape[:2]
            # min_width = min(width_left,width_Right)
            min_height = min(height_Left,height_Right)

            # 裁剪图像
            imageLeft = imageLeft[:min_height, :]
            imageRight = imageRight[:min_height, :]
            # # 将第二张图调整为和第一张图一样的高度
            # imageRight = cv2.resize(imageRight, (imageRight.shape[1], height),interpolation=cv2.INTER_LINEAR)

            # if i==2:
            #     break
            if imageLeft is None or imageRight is None:
                print("NOTICE: No images")
            else:
                ImageLeft_gray = cv2.cvtColor(imageLeft, cv2.COLOR_BGR2GRAY)
                ImageRight_gray = cv2.cvtColor(imageRight, cv2.COLOR_BGR2GRAY)

                # cv2.imshow("gray", ImageLeft_gray)
                # cv2.waitKey()

                # 获取图像长宽
                height_Left, width_left = ImageLeft_gray.shape[:2]
                height_Right, width_Right = ImageRight_gray.shape[:2]
                height = int(1000 * beishu)

                # 模板区域
                left_width_begin = int(width_left - int(2000 * beishu))
                left_height_begin = height
                template_left = imageLeft[int(left_height_begin):int(height_Left-int(1000*beishu)),
                                int(left_width_begin): int(width_left - int(200 * beishu))]
                # drawLeftRect = imageLeft.copy()
                # cv2.rectangle(drawLeftRect, (left_width_begin, left_height_begin), (width_left, int(4 * height_Left / 5)),
                #               (0, 0, 255),
                #               1)

                # cv2.imshow("template_left", drawLeftRect)
                # cv2.waitKey()
                # plt.imsave('Left_rect.jpg', cv2.cvtColor(drawLeftRect, cv2.COLOR_BGR2RGB))

                # 右边匹配区域
                match_right = imageRight[0:height_Right, 0: int(1* width_Right / 2)]
                # cv2.imshow("match_right", match_right)
                # cv2.waitKey()

                # 执行模板匹配,采用的匹配方式cv2.TM_CCOEFF_NORMED
                matchResult = cv2.matchTemplate(match_right, template_left, cv2.TM_CCOEFF_NORMED)
                # cv2.imwrite('2.jpg', matchResult)
                # 归一化处理
                cv2.normalize(matchResult, matchResult, 0, 1, cv2.NORM_MINMAX, -1)
                # 寻找矩阵(一维数组当做向量,用Mat定义)中的最大值和最小值的匹配结果及其位置
                min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(matchResult)
                # print(max_loc)
                # cv2.rectangle(imageRight, (max_loc[0], max_loc[1]), (width_left-left_width_begin + max_loc[0],  max_loc[1] + int(height_Left / 2)), (0, 0, 255),
                #               1)
                # plt.imsave('Right_rect.jpg', cv2.cvtColor(imageRight, cv2.COLOR_BGR2RGB))

                # 设置最终图片大小
                dstStitch = np.zeros((height_Left, width_Right + left_width_begin - max_loc[0], 3), imageLeft.dtype)
                dstStitch1 = np.zeros((height_Left, width_Right + left_width_begin - max_loc[0], 3), imageLeft1.dtype)
                height_dst, width_dst = dstStitch.shape[:2]

                # copy left image
                dstStitch[0:height_Left, 0:width_left] = imageLeft.copy()

                dstStitch1[0:height_Left, 0:width_left] = imageLeft.copy()

                # 匹配右图的高要能和目标区域一样
                matchRight_H = height_Right - max_loc[1] + left_height_begin

                if height_dst == matchRight_H:
                    matchRight = imageRight[int(max_loc[1] - left_height_begin): int(height_Right),
                                 int(max_loc[0]):int(width_Right)]
                    matchRight = matchRight[:, int(1000 * beishu):]

                    matchRight1 = imageRight1[int(max_loc[1] - left_height_begin): int(height_Right),
                                  int(max_loc[0]):int(width_Right)]
                    matchRight1 = matchRight1[:, int(1000 * beishu):]

                elif height_dst < matchRight_H:
                    dst_y_start = (left_height_begin - max_loc[1])
                    # 定义平移矩阵
                    M = np.float32([[1, 0, 0], [0, 1, dst_y_start]])  # 向上平移 dst_y_start个像素
                    # 应用平移矩阵
                    rows, cols, _ = imageRight.shape
                    matchRight = cv2.warpAffine(imageRight, M, (cols, rows))
                    matchRight = matchRight[0: height_Right, max_loc[0]:width_Right]
                    matchRight = matchRight[:, int(1000 * beishu):]

                    matchRight1 = cv2.warpAffine(imageRight1, M, (cols, rows))
                    matchRight1 = matchRight1[0: height_Right, max_loc[0]:width_Right]
                    matchRight1 = matchRight1[:, int(1000 * beishu):]
                else:
                    dst_y_start = (left_height_begin - max_loc[1])
                    # 定义平移矩阵
                    M = np.float32([[1, 0, 0], [0, 1, dst_y_start]])  # 向下平移 dst_y_start个像素
                    # 应用平移矩阵
                    rows, cols, _ = imageRight.shape
                    matchRight = cv2.warpAffine(imageRight, M, (cols, rows))
                    matchRight = matchRight[0: height_Right, max_loc[0]:width_Right]
                    matchRight = matchRight[:, int(1000 * beishu):]

                    matchRight1 = cv2.warpAffine(imageRight1, M, (cols, rows))
                    matchRight1 = matchRight1[0: height_Right, max_loc[0]:width_Right]
                    matchRight1 = matchRight1[:, int(1000 * beishu):]

                drawRightRect = imageRight.copy()
                drawRightRect1 = imageRight1.copy()

                h, w = template_left.shape[:2]
                cv2.rectangle(drawRightRect, (max_loc[0], max_loc[1]), (max_loc[0] + w, max_loc[1] + h), (0, 0, 255), 1)
                cv2.rectangle(drawRightRect1, (max_loc[0], max_loc[1]), (max_loc[0] + w, max_loc[1] + h), (0, 0, 255),
                              1)

                height_mr, width_mr = matchRight.shape[:2]
                dstStitch[0:height_dst,
                left_width_begin + int(1000 * beishu):width_mr + int(
                    1000 * beishu) + left_width_begin] = matchRight.copy()

                dstStitch1[0:height_dst,
                left_width_begin + int(1000 * beishu):width_mr + int(
                    1000 * beishu) + left_width_begin] = matchRight1.copy()
                result = dstStitch
                result1 = dstStitch1
        # file_name = f'E:/camera/pailei/{i}.jpg'  # 使用f-string创建不同的文件名
        # plt.imsave(file_name, cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
    if len(row_stitch_img) != 0:
        # file_name = f"{i}.jpg"
        dstStitch = cv2.rotate(dstStitch, cv2.ROTATE_90_CLOCKWISE)
        dstStitch1 = cv2.rotate(dstStitch1, cv2.ROTATE_90_CLOCKWISE)
        # # 进行水平镜像翻转
        # dstStitch = cv2.flip(dstStitch, 1)
        # dstStitch = cv2.flip(dstStitch, 0)

    if len(row_stitch_img) == 1:
        dstStitch = row_stitch_img[str(0)]
        dstStitch1 = row_stitch_img1[str(0)]
        # # 进行水平镜像翻转
        # dstStitch = cv2.flip(dstStitch, 1)
        # dstStitch = cv2.flip(dstStitch, 0)

    if len(row_stitch_img) == 1:
        dstStitch = row_stitch_img[str(0)]
        dstStitch = cv2.rotate(dstStitch, cv2.ROTATE_90_CLOCKWISE)

        dstStitch1 = row_stitch_img1[str(0)]
        dstStitch1 = cv2.rotate(dstStitch1, cv2.ROTATE_90_CLOCKWISE)
        # # 进行水平镜像翻转
        # dstStitch = cv2.flip(dstStitch, 1)
        # dstStitch = cv2.flip(dstStitch, 0)

    save_path = './/results//stitch//stitch.jpg'
    cv2.imwrite(save_path, dstStitch)
    cv2.imwrite("result.jpg",dstStitch)
    cv2.imwrite("result1.jpg",dstStitch1)

    return 1, os.path.abspath(save_path)


if __name__ == "__main__":
    input = glob.glob(r"A1A2A3_V1/UP/*.jpg")
    images_output = glob.glob(r"A1A2A3_V1/UP/*.jpg")
    stitch_start(input, images_output, 4)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值