大家好,我是小白说遥感,今天我们来聊聊图像处理中的一个实用技巧——直方图匹配(Histogram Matching)。
如果你是遥感、GIS、摄影或AI图像处理的从业者,肯定遇到过图像颜色不一致的问题。比如,多张卫星图像拼接时,颜色偏差会导致整体效果不佳。
这时候,直方图匹配就能派上用场,它可以让目标图像的颜色分布匹配模板图像,实现“匀色”效果。
本文基于一个Python脚本,详细教你如何实现批量处理16位、4波段TIF图像的直方图匹配。脚本使用分块处理,适合大图像,避免内存溢出。
我会一步步解释代码原理、如何运行,以及一些优化建议。无论你是新手还是老鸟,都能学到东西,以后自己复习也方便。
为什么需要直方图匹配?在图像处理中,直方图表示像素值的分布(比如亮度从0到255)。不同图像的直方图可能差异很大,导致颜色不匹配。
直方图匹配的核心是:
计算模板图像和目标图像的累积分布函数(CDF)。
通过映射,让目标图像的CDF匹配模板的CDF,从而调整像素值,实现颜色一致。
优势:
简单高效,尤其适合遥感图像(如卫星DOM)。
支持多波段(RGB+Alpha或多光谱)。
对于16位图 ...
在处理遥感影像和大型地理空间数据时,数据量动辄数十 GB 甚至 TB,传统的处理方式经常会遭遇“内存不足 (Out of Memory, OOM)”的窘境。幸运的是,GDAL(Geospatial Data Abstraction Library)提供了一个强大的解决方案——VRT (Virtual Raster),即虚拟栅格。
VRT 并非一个真正的数据文件,它是一个 XML 格式的描述文件,它告诉 GDAL 如何将多个源文件组合起来,或者如何对一个源文件进行某种变换。它的核心价值在于其“即时计算,按需加载”的特性。
一、什么是 VRT(虚拟栅格)?想象 VRT 就像一张地图索引,它本身不包含像素数据,只记录了:
数据源在哪里(哪个 TIF、JPG、PNG 文件)。
数据源的地理位置(坐标系统、边界)。
如何组合这些数据源(比如拼接、重采样、重投影)。
当 GIS 软件或程序请求 VRT 上的某个小区域数据时,GDAL 才会去读取对应的源文件中的相应像素,大大节省了内存和处理时间。
二、VRT 的核心应用场景VRT 是处理大数据的瑞士军刀。以下是它最常用的几个场景:
大型影 ...
之前写了一篇关于wgs84影像转为cgcs2000的影像的文章:《wgs84影像直接转换为cgcs2000影像》
在里面我写道:诸如遥感数据处理的东西,其实是没有技术含量的,本质上都是调用gdal的东西,你把gdal的各个接口弄明白了就掌握这个数据处理的技能,唯手熟尔。真正有难度的是算法、加速处理速度。我其实很久不做数据数据处理的东西了,因为我有足够的代码积累,我建立了一个代码库,需要哪个模块,我直接搜索。
cscs2000坐标系的EPSG代码计算cscs2000坐标系其实和wgs84一样,分为两种:地理坐标系和投影坐标系。
用大白话来区分地理和投影,是看它们的单位。
单位若是度分秒,就是地理坐标系;单位是米,就是投影坐标系。
除此之外,我们还要获取坐标系的EPSG号码。
这个参数,我们需要填写到gdal的Warp进行重投影。
wgs84地理坐标系的EPSG号码4326,cgcs2000地理坐标系的EPSG号码4490。
如果你是想转换为cgcs2000投影坐标系,还得继续计算。
投影坐标系分为3度带,和6度带。
以3度带为例,不同的带号的计算规则如下:
例如,经度为105°E,计算过 ...
由于家里电脑的硬盘空间实在吃紧,我在清理空间时顺手就把 ArcGIS 卸载了。其实卸载的时候还是犹豫了一下——毕竟陪伴了我这么多年,用得最熟的还是它。但家里主要是做一些个人学习、测试项目,硬盘空间又寸土寸金,只能忍痛割爱。
为什么办公电脑我却一直没动呢?原因很现实:假设哪天同事突然甩给我一个 ArcGIS 的模板或者 MXD 文件让我立刻出图,如果我告诉他“我机器上没 ArcGIS”,那场面会尬到能当场原地升天。办公室毕竟要处理甲方的活儿,一点不能出差错。
那我为什么最终会卸载 ArcGIS?其实主要是因为 QGIS 在不少工作流中已经能替代 ArcGIS 了。更关键的是,我们行业的甲方大部分都跟GOV有关,而GOV单位这几年疯狂推进国产化改造。
国产 Linux 电脑里, ArcGIS软件是不让装的,审计、检测一层层卡着,根本没机会上。而 QGIS 作为开源 GIS,自然而然趁势上位,在国产系统里用得顺风顺水。
说实话,我对 ArcGIS 的熟练度远远超过 QGIS。用 ArcGIS 出图就像用右手写字,而用 QGIS 更像换成左手,总觉得别扭、不顺手。
快捷键、工具逻辑、窗口布局… ...
矢量的属性表转化为excel是不难的,在arcgis的工具有一个叫做:Table To Excel (Conversion)
在这里很快很简单地就可以把矢量文件的属性表导出,保存为excel文件。
用代码实现其实也不难,完整代码如下,我们调用geopandas库。
import geopandas as gpd
def shp2excel(shp_file, excel_file):
gdf = gpd.read_file(shp_file)
df = gdf.drop(columns='geometry')
df.to_excel(excel_file, index=False)
if __name__ == '__main__':
shp2excel("input.shp", "output.xlsx")
有时候因为是geopandas很难打包为exe,所以我们能尽量只用gdal的话,那就尽量只用gdal。
因为geopan
在半年前,我曾想过出一些关于编程、图像处理的视频教程。
在往常附上代码的以文本的形式,那如果要制作视频,那应该怎么制作呢?
我有认真思考过这个问题。
视频的本质就是多帧的图片叠加起来。
大致就是周星驰电影《苏乞儿》里那本武功秘籍,把书快速翻动,里面的小人就打一套功夫。
所以用python制作 一个类似 代码演示的视频,这是一件不难的事情。
写完了之后,我和朋友聊起这件事。
整体流程逻辑(大框架)代码主要分 4 个阶段:
① 初始化环境与加载字体
清空输出目录
找字体 → 成功用之,不成功就换 → 最后用默认
根据 Pygments 配色方案(dracula)获取各种 token 的颜色
② 按字符绘制代码,模拟打字动画核心逻辑:
代码内容 CODE_TO_ANIMATE → 清洗成干净的字符串
for char in clean_code: 每多一个字符,就重新画一张“当前代码”的截图
每生成一帧,文本要
用 PIL 绘制
按 token 上色(和 Python 语法高亮一样)
计算光标位置(像打字机一样挪动)
遇到换行 \n,会停顿一些帧(让动画更自然)
每一帧保 ...
这个现象,正是Python包管理设计中一个巧妙之处。简单来说,这主要归功于一种叫做“控制台脚本入口点”的机制。
当你 pip install xxx 的时候,实际上装了两个东西:
Python 包(库) 你在代码里 import xxx 用的就是它。
可执行脚本(命令行工具) 这类脚本会被 pip 自动丢到你的系统 PATH 里,所以你在终端能直接敲命令运行。
为什么能直接运行?比如你安装:
pip install jupyter
pip install gdal
然后你就能直接跑:
jupyter notebook
gdalinfo xxx.tif
原因是:
这些包的 setup.py / pyproject.toml 里写了 console_scripts
[project.scripts]
jupyter notebook = "jupyter:main"
意思是:安装后自动生成一个叫 jupyter notebook 的命令,执行时调用 jupyter.main()。
pip 会把这些生成的脚本放到:
Windows: Scripts/
Linux / Mac: ~/.l ...
程序员的世界里有一种非常神奇的生物——进度条。
它像是一个努力奔跑的小人,不断告诉你:“我在工作,我没有卡死,你放心。” 然而现实是: 许多进度条,其实根本不知道自己跑到了哪里。
没错,它们是假的。
01. 我遇到过真正的“纯假进度条”有一次我用 Java 调用同事写的 DLL(C++ 写的底层处理模块)。 需求很简单:
“要一个进度条,看着舒服点。”
问题来了——我根本拿不到 C++ 里循环的实时进度。
DLL 是个黑盒子。你只知道它开始了,但不知道它在哪个阶段、完成了多少、是不是卡了、是不是要挂了。
理论上可以让同事加一个回调函数,从 C++ 里主动往 Java 里推进度,但:
同事嫌麻烦
DLL 老代码不敢改
发布周期赶
风险大
所以最终我就只能……假装一切尽在掌控。
于是,Java 里写了一个“陪伴型进度条”:
DLL 开始 → 进度条从 0% 平滑升到 95%
DLL 返回结果 → 进度条从 95% 快速跳到 100%
DLL 卡住 → 条条继续动,程序假装没事
DLL 崩掉 → 用户最后只看到“哎呀,失败了”
进度条根本不知道 DLL 在干嘛,它只是尽到了一 ...
最近写遥感的东西比较少,今天写一写如何将wgs84影像直接转换为cgcs2000影像,我们直接上代码就好了。
说白了这东西没什么技术含量,都是调用gdal写好的接口,以后我们再讨论一下wgs84的tif和cgcs2000的tif本质上有什么区别,这块我后面再好好研究一下。
至于wgs84影像直接转换为cgcs2000影像的代码,我直接放后面。此外,我还想再唠上一唠。
诸如遥感数据处理的东西,其实是没有技术含量的,本质上都是调用gdal的东西,你把gdal的各个接口弄明白了就掌握这个数据处理的技能,唯手熟尔。真正有难度的是算法、加速处理速度。我其实很久不做数据数据处理的东西了,因为我有足够的代码积累,我建立了一个代码库,需要哪个模块,我直接搜索。
当然,这些代码库,随着这两年的公众号的文章更新,早已被我耗尽。不然我去年不可能做到高强度的更新。
我自认为部分的技术文章还是写的有一点水平的,哈哈我这种黄婆卖瓜自卖自夸行为真不要脸。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2025/10/26 21:30
# @Fil ...
在AI项目中,训练好模型只是第一步,下一步是部署到其他的环境中! 但PyTorch模型(.pth)在手机/服务器上跑不动?别急!ONNX格式来救场。
为什么必须转ONNX?3大痛点
问题
后果
ONNX解决
框架依赖
PyTorch跑不动TensorFlow环境
跨框架通用,到处跑!
部署慢
手机/边缘设备卡顿
体积小50%,速度快2倍
不稳定
不同硬件报错
标准化,一次转换到处用
除这三点之外,个人认为,我需要pth模型文件转换为ONNX文件的最大需求是:隐藏神经网络模型的细节,不需要把python源代码交付出去,这样做相当于简单伪装,很多事情都是防君子不防小人。
超简单3步转换法Step 1:准备模型# 加载你的.pth模型
model = YourModel() # 替换成你的模型类
checkpoint = torch.load('your_model.pth')
model.load_state_dict(checkpoint) # 加载权重
model.eval() # 评估模式
Step 2:创建假输入# 根据你的输入尺寸创建(比如 ...




