前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【图像配准】Canny边缘检测+模板配准红外可见光双路数据

【图像配准】Canny边缘检测+模板配准红外可见光双路数据

作者头像
zstar
发布2023-10-25 15:13:37
4020
发布2023-10-25 15:13:37
举报
文章被收录于专栏:往期博文往期博文

研究目的

最近在做无人机遥感红外和可见光双路数据配准,由于红外相机视野范围较小,因此配准的目的主要是在可见光的视野范围内,裁剪出红外图像对应的部分,同时,保持可见光的高分辨率不变。

本文思路

本文尝试使用Canny边缘检测提取红外和可见光的边缘特征,然后使用模板匹配的方式去进行配准。由于红外图像和可见光图像的分辨率并不相同,因此需要对可见光不断进行下采样,以接近红外图像的分辨率。

总体看来,使用传统方法做跨模态配准效果有限,主要是由于红外图像特征较少,不过在光照充足和建筑特征明显的情况下,有一定效果,后续会采用基于深度学习的配准方法,相关图片由于项目原因不对外公布,这里对代码进行归档。

实验代码

代码语言:javascript
复制
import numpy as np
import argparse
import cv2
import os

if __name__ == '__main__':
    ap = argparse.ArgumentParser()
    ap.add_argument("-i", "--image", required=False, default=r"lr/Infrared.jpg", help="红外图像路径")
    ap.add_argument("-v", "--visualize", required=False, default=r"rgb/Zoom.jpg", help="可见光图像路径")
    ap.add_argument("-o", "--output", required=False, default=r"output", help="输出文件夹路径")
    args = vars(ap.parse_args())

    # 读取红外图像/灰度化/边缘检测
    template = cv2.imread(args["image"])
    template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
    template = cv2.Canny(template, 50, 200)
    (tH, tW) = template.shape[:2]

    # 读取可见光图像
    image = cv2.imread(args["visualize"])
    # image = cv2.resize(image, (tW, tH))
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    found = None

    for scale in np.linspace(0.2, 1.0, 20)[::-1]:
        # 多尺度缩小可见光图像
        resized = cv2.resize(gray, (int(gray.shape[1] * scale), int(gray.shape[0] * scale)))
        r = gray.shape[1] / float(resized.shape[1])

        # 若缩小的尺度小于红外图像尺寸,跳出循环
        if resized.shape[0] < tH or resized.shape[1] < tW:
            break

        # 对缩小之后的图像进行边缘检测
        edged = cv2.Canny(resized, 50, 200)
        '''
        cv2.matchTemplate  模板匹配
        :param 检测图像 模板 模板匹配方法
        :returns 相似度结果矩阵:(宽: image.shape[1]-template.shape[1]+1; 高:image.shape[0]-template.shape[0]+1)
        '''
        result = cv2.matchTemplate(edged, template, cv2.TM_CCOEFF)
        # print("edged_shape:{}".format(edged.shape))  # (3888, 5184)
        # print("template_shape:{}".format(template.shape))  # (512, 640)
        # print("result_shape:{}".format(result.shape))  # (3377, 4545)

        # 查找模板中最大相似度值和位置
        _, maxVal, _, maxLoc = cv2.minMaxLoc(result)

        # 可选:查看匹配图范围
        # clone = np.dstack([edged, edged, edged])
        # clone = edged
        # cv2.rectangle(clone, (maxLoc[0], maxLoc[1]), (maxLoc[0] + tW, maxLoc[1] + tH), (0, 0, 255), 2)
        # cv2.imwrite(os.path.join(args["output"], "Visualize", "visualize.jpg"), clone)

        # 若在裁剪区域找到相似度更高的匹配点,更新found
        if found is None or maxVal > found[0]:
            found = (maxVal, maxLoc, r)

    # 得到匹配度最高的矩阵框坐标
    _, maxLoc, r = found
    (startX, startY) = (int(maxLoc[0] * r), int(maxLoc[1] * r))
    (endX, endY) = (int((maxLoc[0] + tW) * r), int((maxLoc[1] + tH) * r))

    # cv2.rectangle(image, (startX, startY), (endX, endY), (0, 0, 255), 2)
    crop_img = image[startY:endY, startX:endX]
    # cv2.imshow("Image", image)
    # cv2.imshow("Crop Image", crop_img)
    # cv2.waitKey(0)


    thermal_image = cv2.imread(args["image"], cv2.IMREAD_COLOR)
    # cropping out the matched part of the thermal image
    crop_img = cv2.resize(crop_img, (thermal_image.shape[1], thermal_image.shape[0]))

    # 创建输出文件夹存储裁剪后的可见光影像
    if not os.path.exists(os.path.join(args["output"], "process")):
        os.mkdir(os.path.join(args["output"], "process"))
    # 保存图片
    cv2.imwrite(os.path.join(args["output"], "process", os.path.basename(args["visualize"])), crop_img)

    # 创建对比图像
    final = np.concatenate((crop_img, thermal_image), axis=1)
    if not os.path.exists(os.path.join(args["output"], "results")):
        os.mkdir(os.path.join(args["output"], "results"))
    cv2.imwrite(os.path.join(args["output"], "results", os.path.basename(args["visualize"])), final)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 研究目的
  • 本文思路
  • 实验代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档