【ChatGPT+Python】Landsat卫星图像黑边去云及旋转校正

news2024/11/30 10:29:54

引言

下图是一张Landsat图像的示例(右图)。我们可以明显地看到四周的黑边和倾斜的角度。这是由于卫星传感器成像导致的。一般情况下,我们是不需要去除黑边和选择的,因为这样做之后投影信息和位置信息就不正确了。但对于做深度学习图像处理任务的同学来说,可能不需要考虑此类约束。因此,出于节省存储和内存的考虑,借助ChatGPT直接帮助我们生成了黑边去云及旋转校正的Python代码,最终效果如左图。

在这里插入图片描述

代码

Prompt: 现有一RGB彩色图像,图像内仅有一个旋转的矩形物体,其周围的像素值全是0,要求裁剪出其中的矩形物体,并将其旋转校正,注意矩形物体的边界也可能有值为0的像素,输出结果保存为彩色图像。使用Python实现。

  • 安装依赖
pip install opencv-python numpy
  • 算法流程
  1. 读取图像
  2. 转换为灰度图像,然后通过阈值化操作将所有非零像素转换为白色(255),所有零像素保持为黑色(0)。
  3. 使用OpenCV的findContours方法找到最大的轮廓,这应该是你的矩形物体。
  4. 使用minAreaRect获取轮廓的最小外接矩形(包括旋转角度)。
  5. 通过旋转原始图像将矩形校正。
  6. 裁剪并保存结果图像。
  • 黑边去除及旋转校正的代码如下:
import cv2
import numpy as np

# 1. 读取图像
img = cv2.imread('input.jpg')

# 2. 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 3. 找到最大的轮廓
_, thresh = cv2.threshold(gray, 1, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contour = max(contours, key=cv2.contourArea)

# 4. 获取最小外接矩形
rect = cv2.minAreaRect(contour)
box = cv2.boxPoints(rect)
box = np.int0(box)

# 5. 旋转原始图像以校正矩形
width = int(rect[1][0])
height = int(rect[1][1])
src_pts = box.astype("float32")
dst_pts = np.array([[0, height-1],
                    [0, 0],
                    [width-1, 0],
                    [width-1, height-1]], dtype="float32")
M = cv2.getPerspectiveTransform(src_pts, dst_pts)
warped = cv2.warpPerspective(img, M, (width, height))

# 6. 显示中间过程(用于可解释性研究)
cv2.drawContours(img, [box], 0, (0, 0, 255), 2)
cv2.imshow('edge', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 7. 裁剪并保存结果图像
output = warped[0:height, 0:width]
cv2.imwrite('output.jpg', output)

以上代码首先读取图像,并通过二值化将图像分割成背景和物体。然后找到物体的外接矩形,使用仿射变换将物体旋转到水平位置,最后对旋转后的图像进行裁剪。

但请注意,对于非常复杂或噪声很大的图像,这种方法可能不适用。你可能需要对图像进行更多的预处理,比如滤波、形态学操作等等。

实验

表1:边缘(轮廓)检测方法采用不同函数的对比结果

在这里插入图片描述

拓展

上述代码不仅对于Landsat卫星图像有效,对于普通的图像(周围是黑色填充,内接一个矩形物体)也同样有效。下面给出一个演示结果。

在这里插入图片描述

此外,上述代码中寻找最大轮廓除使用 cv2.findContours() 函数外,也可以使用如下方式替代,只不过代码的执行时间会变长,但是鲁棒性会更好,即抗噪声等干扰的能力强。

import cv2
import numpy as np

# 1. 读取图像
img = cv2.imread('input.jpg')

# 2. 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 3. 找到最大的轮廓
# 使用Canny边缘检测算法检测图像中的边缘
edges = cv2.Canny(gray, 50, 150, apertureSize=3)

# 使用霍夫变换检测图像中的直线
lines = cv2.HoughLines(edges, 1, np.pi/180, 200)

# 获取检测到的直线中最长的一条
longest_line = None
max_length = 0

for line in lines:
    for rho, theta in line:
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a*rho
        y0 = b*rho
        x1 = int(x0 + 1000*(-b))
        y1 = int(y0 + 1000*(a))
        x2 = int(x0 - 1000*(-b))
        y2 = int(y0 - 1000*(a))
        length = np.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))
        if length > max_length:
            max_length = length
            longest_line = line

# 获取直线的端点坐标
for rho, theta in longest_line:
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a*rho
    y0 = b*rho
    x1 = int(x0 + 1000*(-b))
    y1 = int(y0 + 1000*(a))
    x2 = int(x0 - 1000*(-b))
    y2 = int(y0 - 1000*(a))

# 计算直线的角度
angle = np.arctan2(y2-y1, x2-x1) * 180 / np.pi

# 4. 获取最小外接矩形
h, w = img.shape[:2]
rect = cv2.minAreaRect(np.array([(x, y) for x in range(w) for y in range(h) if edges[y, x] > 0]))
box = cv2.boxPoints(rect)
box = np.int0(box)

# 5. 旋转原始图像以校正矩形
width = int(rect[1][0])
height = int(rect[1][1])
src_pts = box.astype("float32")
dst_pts = np.array([[0, height-1],
                    [0, 0],
                    [width-1, 0],
                    [width-1, height-1]], dtype="float32")
M = cv2.getPerspectiveTransform(src_pts, dst_pts)
warped = cv2.warpPerspective(img, M, (width, height))

# 6. 显示中间过程(用于可解释性研究)
cv2.drawContours(img, [box], 0, (0, 0, 255), 2)
cv2.imshow('edge', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 7. 裁剪并保存结果图像
output = warped[0:height, 0:width]
cv2.imwrite('output.jpg', output)

注意

Landsat的遥感影像四个角有黑色区域,这是正常的。表明那个黑色区的地方没有数据,在实际应用中也不需要去掉四个角的黑色区域。一般我们使用shp矢量量面来对遥感影像进行剪裁,提取出我们所需要研究或者显示的区域就可以啦。但是如果你真的想去掉黑色区域的话,你可以使用重分类,把黑色的区域变成白色,这样和背景就一致了,在发布服务的时候设为白色透明就可以了。还一个问题,Landsat8遥感影像是具有准确的投影坐标系的。倾斜是因为在卫星扫描的时候就是这个样子,拿到的影像是由准确的地理坐标的,不能够把它给旋转正了。旋转正了的话,它的投影信息和位置信息就不正确了,如果感觉不好看,可以直接剪裁出来正方形,或者把相邻的影像进行拼接,然后再剪裁。

参考

https://www.zhihu.com/question/497775240/answer/2216988184

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/625861.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

React 基本介绍

目录 1、React是什么 2、React 三大颠覆性的特点 2.1 组件 2.2 JSX 2.3 Virtual DOM 3、Flux 架构(redux) 3.1 Flux 3.2 redux 4、打包工具(webpack) 4.1 webpack与RequireJS、browserify 4.2 模块规范 4.3 非 JavaSc…

二叉树的数学性质、最大堆的实现

每层个数的通式 第一层: 2 0 第二层: 2 1 第三层: 2 2 第四层: 2 3 每层个数的通式 2 n − 1 个, n 为层数 \begin{aligned} 第一层:2^0 \\ 第二层:2^1 \\ 第三层:2^2 \\ 第四层&…

linux历史记录简易审计系统

1、有时候我们需要对线上用户的操作进行记录,可以进行追踪,出现问题追究责任,但是linux自带的history并不会实时的记录(仅仅在内存中,当用户正常退出(exit logout )时才会记录到history文件里),并且还有1000行的限制可以删除的; 为了保证让用户的操作进行实时记录&…

chatgpt赋能python:Python入门:如何下载NumPy库

Python入门:如何下载NumPy库 如果你是Python初学者或是有开发经验的工程师,你可能会涉及到使用NumPy库。NumPy是Python中一个非常重要的科学计算库,它提供了高效的多维数组数据结构和数学函数,被许多人用于数据分析、机器学习、科…

Verilog基础:task和function的使用(二)

相关文章 Verilog基础:表达式位宽的确定(位宽拓展) Verilog基础:表达式符号的确定 Verilog基础:数据类型 Verilog基础:位宽拓展和有符号数运算的联系 Verilog基础:case、casex、ca…

CSS的学习1

使用css的目的是让网页具有美观一致的页面。 语法 CSS规则由两个主要的部分构成:选择器以及一条或多条声明(样式) 选择器:h3 声明:{color:red;font-size:30px;} 选择器通常是需要改变的HTML元素; 每条…

六一儿童节-王者连连看

庆祝六一 用java实现的连连看练手小游戏 王者连连看 🤣 游戏介绍😜 核心😮‍💨总结: 🤣 游戏介绍 王者连连看游戏的目标是通过消除相同的图案来得分并进入更高级别的挑战。   游戏分为四个难度   可以自…

cpp: Visitor Pattern

/*****************************************************************//*** \file Gold.h* \brief 访问者模式 Visitor Pattern C 14 行为模式* 2023年6月8日 涂聚文 Geovin Du Visual Studio 2022 edit.文章来源《C新经典设计模式》 王健伟编著 清华大学出版社* \author…

记录:VS2019+OpenCV4.7.0编译

一、准备 OpenCV官网提供了动态库的安装包,但是只有64位,而且没看到编译参数,如果需要32位或者静态链接还是得自己编译。 CMake:https://cmake.org/download/ Visual Studio:https://visualstudio.microsoft.com/zh…

计算机组成原理——中央处理器

文章目录 **一 CPU的功能和基本结构****1 CPU的功能****2 [基本结构](http://t.csdn.cn/bpCt3)****2.1 运算器****2.2 控制器** **二 指令执行过程****1 指令周期****2 指令周期的数据流****2.1 取指周期****2.2 间址周期****2.3 执行周期****2.4 中断周期** **3 指令的执行方案…

chatgpt赋能python:如何下载Python中的jieba包

如何下载Python中的jieba包 随着Python的普及,很多程序员选择使用Python作为自己的主力编程语言。对于自然语言处理方面的任务,jieba是Python中一个非常优秀的分词工具。那么,如何下载和使用Python中的jieba包呢?本篇文章将为您详…

【MySQL数据库 | 第十四篇】多表查询案例

目录 前言: 引入背景: 练习: 前言: 在第十三篇我们已经详细的介绍了多表查询的类别以及每一个类别的语法:【MySQL数据库 | 第十三篇】多表查询,今天我们将通过案例来巩固我们对多表查询语法的熟悉度。 引入…

JavaSE笔记(二)重制版

面向过程篇 前面我们已经认识了Java语言的相关特性,并且已经成功配置好了开发环境,从这节课开始,我们就可以正式进入到Java语言的学习当中了。Java语言是一门面向对象的语言,但是在面向对象之前,我们还得先学会如何面…

【IMX6ULL驱动开发学习】05.IMX6ULL驱动开发_编写第一个hello驱动【熬夜肝】

经过以下四个步骤,终于可以开始驱动开发了 01.安装交叉编译环境【附下载地址】 02.IMX6ULL烧写Linux系统 03.设置IMX6ULL开发板与虚拟机在同一网段 04.IMX6ULL开发板与虚拟机互传文件 目录 一、获取内核、编译内核 二、创建vscode工作区,添加内核目录…

《计算机组成原理》期末考试手写笔记——模块五: 并行主存系统(交叉存储器+顺序存储器“带宽”的计算方法)

目录 (一)知识点总结 (二)经典考试例题 1.设主存储器容量为256字,字长为32位,模块数m4,分别用顺序方式和交叉方式进行组织。主存储器的存储周期T200ns,数据总线宽度为32位&#x…

EMQ X(2):EMQ X服务端环境搭建与配置

1 安装 EMQ X 目前支持的操作系统: Centos6Centos7OpenSUSE tumbleweedDebian 8Debian 9Debian 10Ubuntu 14.04Ubuntu 16.04Ubuntu 18.04macOS 10.13macOS 10.14macOS 10.15Windows Server 2019 产品部署建议 Linux 服务器,不推荐 Windows 服务器。 安装的方式有…

【Linux】HTTP协议

目录 🚀前言🚃HTTP协议 🚄1、URL网址🚅2、URL的编码和解码🚇3、HTTP协议格式🚈4、HTTP请求🚉4.1、 HTTP GET和POST方法🚋4.2、HTTP状态码🚊4.3、HTTP常见Header &#x1…

redis架构设计: redis-server的启动(硬核分析)

怎么在windows上用clion搭建redis的源码阅读环境 请看我的上一篇文章 redis启动之后都干了什么呢? 我们知道,redis的服务端对应的源码位置是server.c main函数是程序启动的入口 ,下面我来一行一行的分析server.c的源码 1、定义时间函数变量 struct …

chatgpt赋能python:Python多种输出格式详解

Python多种输出格式详解 对于Python程序员来说,输出是非常重要的。无论是在开发阶段还是在生产环境中,输出都是我们调试程序和确认程序运行是否正常的重要手段。Python标准库提供了丰富的输出格式,本文介绍了几种常见的输出格式及其使用方法…

因为写不出拖拽移动效果,我恶补了一下Dom中的各种距离

目录 背景 JS Dom各种距离释义 第一个发现 window.devicePixelRatio 的存在 document.body、document.documentElement和window.screen的宽高区别 scrollWidth, scrollLeft, clientWidth关系 元素自身和父级元素的scrollWidth和scrollLeft关系? offsetWidth和clientWid…