创建透明的山体阴影?


34

通过组合使用gdal,我得到了优雅的透明山体阴影convert。与通常使用的基于灰色的山体阴影相比,这种透明的山体阴影非常酷,因为它们可以放置在地图背景与其他上层(道路,建筑物)之间,以提供3D感觉,无论背景的类型和颜色如何。

怎么运行的

诀窍:从产生的灰度山丘阴影开始gdal hillshade,诀窍是获取灰度通道的值,将每个值求反,然后将结果流到新的不透明度通道中。黑色像素[0,0,0]变为[0,0,0,255](不透明度= 255),灰色像素[120,120,120]降低至[120,120,120,135](不透明度= 135,又称为255-120),白色像素[255,255,255]变为透明[255,255,255,0](不透明度= 0,又称为255-255),依此类推。丘陵的阴影是不透明的和黑色的,平原逐渐变得(白色)透明。从概念上讲,像素的波段方程是这样的:

alpha_value([0])    = 255-0 = 255;   // black pixels get full opacity
alpha_value([Grey]) = 255-Grey;
// grey pixels get 255-GreyValue opacity.
alpha_value([255])  = 255-255 = 0  // white pixels get null opacity !

有关此方法的悠闲视频(由Photoshop设计师解释),请参阅在Photoshop中添加阴影浮雕(16分钟)。

将ETOPO或SRTM派生的基于灰色的山体阴影(gdaldem hillshade crop_xl.tmp.tif shadedrelief.tmp.tif -s 111120 -z 5 -az 315 -alt 60 -compute_edges可在此处下载文件)作为输入...

...如何在此类.tif文件上通过gdal或其他非GIS破坏性方式引用上面的技巧?

请注意,我希望保留GIS属性(地理定位)。

在此处输入图片说明 在此处输入图片说明


1
根据参考数据在tiff中的存储方式,就像重命名与tiff相关的世界文件一样容易。
史蒂夫

@Steve:适用于从栅格(例如SRTM或ETOPO)生成的.tif文件gdaldem hillshade etopo_crop.tif shadedrelief.tmp.tif -s 111120 -z 5 -az 315 -alt 60 -compute_edges
Hugolpz

我想gdal_tranlate用的组合-b -mask -expand 灰色| RGB | RGBA witht一起公式opacity=-(px_grey_value)+255可能是要走的路,但我从来没有碰过的乐队和我'还是相当无能。
Hugolpz 2015年


您是否尝试过gdal_edit.py重写坐标,像元大小和参考系?
radouxju 2015年

Answers:


42

果壳

应该阅读下面每组3张图像,例如“灰色(带)+不透明度(带)=透明结果”。您可以通过关联的github托管的makefile在几分钟之内测试这些过程。我建议使用进程#3,其阈值应介于170(保留强阴影)和220(保留所有阴影)之间。程序3提供最强的阴影并避免变白的效果。根据需要调整结果层的整体不透明度。使用中的等式--calc="<equation>"也可以根据需要进行改进gdal_calc

有关此方法的悠闲视频(由Photoshop设计师解释),请参阅在Photoshop中添加阴影浮雕(16分钟)。

背景

gdaldem hillshade产生一个像素范围为[1-255]的单波段​​灰度文件,也就是从最暗的阴影到最开明的像素。对于平坦区域,px = 221(#DDDDDD)。NoDataValue像素也获得默认的nodatavalue 0,并且输入和输出中最暗的黑色是并且应该是1。没有定义不透明度带,不透明度为100%

gdaldem hillshade input.tif hillshade.tmp.tif -s 111120 -z 5 -az 315 -alt 60 -compute_edges

hillshade.tmp.tif

我们要定义和控制第二个不透明度带!

目标

我们想要一个灰度带 -b 1,那就是山影。在gdal之外,它是一个具有连续范围的灰色带,例如px = [1-255]。我们可以裁剪不相关的区域(#2),或将其变黑为px = 1并依靠不透明带(#3)。

我们需要一个不透明带 -b 2,通常是山体阴影的倒置或相关的功能。我们可以裁剪出不相关的区域(#2)。它必须是连续的不透明度范围,例如px = [1-255],否则就没有优雅感。

gdal_calc可用于对输入文件A,B,C ...中的像素进行数学运算,并检查布尔值(例如)A<220,该布尔值返回1(true)或0(false)。这允许条件演算。如果条件为假,则方程式的相关部分无效。

1.使灰色的山影变透明

以下提供了很好的两波段结果,标准的gdal hillshade灰色和白色区域变得越来越透明:

# hillshade px=A, opacity is its invert: px=255-A
gdal_calc.py -A ./hillshade.tmp.tif  --outfile=./opacity.tif --calc="255-A"
# assigns to relevant bands -b 1 and -b 2
gdalbuildvrt -separate ./final.vrt ./hillshade.tmp.tif ./opacity.tif

hillshade.tmp.tif #1,opacity.tif #1,final.tif

2.通过伪作物(-b 1和-b 2)进行优化

添加-b 1不透明度时,肉眼无法看到(灰度)像素的2/3 -b 2,但是这些像素仍保持各种白色-b 1和低不透明度-b 2值。可以将它们制成全白色透明[255,1]像素,以提供更好的压缩率:

# filter the color band, keep greyness of relevant shadows below limit
gdal_calc.py -A ./hillshade.tmp.tif  --outfile=./color_crop.tmp.tif \
    --calc="255*(A>220) +      A*(A<=220)"
# filter the opacity band, keep opacity of relevant shadows below limit
gdal_calc.py -A ./hillshade.tmp.tif  --outfile=./opacity_crop.tmp.tif \
    --calc="  1*(A>220) +(256-A)*(A<=220)"
# gdalbuildvrt -separate ./final.vrt ./color_crop.tmp.tif ./opacity_crop.tmp.tif
# gdal_translate -co COMPRESS=LZW -co ALPHA=YES ./final.vrt ./final_crop.tif

#2,color.tif(已裁剪) #2,opacity.tif(已裁剪) #2,final_crop.tif

3.进一步-b 1优化(裁剪+变黑)

由于我们-b 2要依靠渐进式不透明度带,因此可以使-b 1像素为白色px = 255通过255*(A>220)或黑色px = 1通过1*(A>220)

gdal_calc.py -A ./hillshade.tmp.tif  --outfile=./color.tmp.tif \
   --calc="255*(A>220) + 1*(A<=220)"
# gdal_calc.py -A ./hillshade.tmp.tif  --outfile=./opacity_crop.tmp.tif \
#  --calc="  1*(A>220) +(256-A)*(A<=220)".
# gdalbuildvrt -separate ./final.vrt ./color.tmp.tif ./opacity_crop.tif
# gdal_translate -co COMPRESS=LZW -co ALPHA=YES ./final.vrt ./final.tif

#3,color.tif #2,opacity.tif(已裁剪) #3,final.tif

此结果显示出更强的阴影

结果

创建透明的山体阴影可以立即消除平原上以前的灰色区域以及相关的不希望但普遍存在的褪色效果。期望的副产品是对最终视觉产品的增强控制。所描述的过程将去除大多数灰色像素和所有白色像素。当彩色背景纯图像被透明至黑色的山影覆盖时,将保留其选择的颜色,只有阴影区域会变暗。下面过程#2(左)和#3(右)的比较。

概述:

流程2(左)和流程3(右)的比较,一般视图。

放大,请注意阴影(前后):

进程2(左)和3(右)的比较,详细信息视图。

进一步优化

白色区域:不妨保留最开明的区域,以增加3D感觉。从字面上看,这将是此当前方法的对称性,但阈值变化较小,然后通过gdal_calc将两个输出合并。平原将是100%透明的,最暗的阴影和最亮的启发区域是不透明的。

平滑:可以预先平滑输入的阴影以得到更好的最终结果,请参阅使用GRASS平滑DEM吗?

复合山体阴影如何创建复合山体阴影)。

撞山丘也很有趣(描述

笔记

  • 平坦区域的阈值gdal hillshade输出为PX = 221(#DDDDDD = [221221221]),标记的平坦区域。而且,山影的px = 221将图像划分为阴影内斜率(A <221)和光照中斜率(A> 221)像素。
  • 一个处理的阈值,在PX = [170-220]为行之有效的好,它使眼睛附近,明显的阴影,这本身勉强站为救援面积的15-35%的100%。
  • 文件大小>压缩:#1,#2,#3中的final.tif未经压缩约为〜1.3MB,压缩后约为0.3-0.16MB,节省了80%!
  • 文件大小>裁剪:从#1的.326KB开始,裁剪颜色和不透明度(#2)达到310kb,变黑的颜色(#3)达到160kb。对文件大小的裁剪效果减少了5〜50%,阈值位于px = 220和我的输入。

2
鼓励+1欢迎。
Hugolpz 2015年

2
教程完成。我的英语可能会坏,请随时提高。
Hugolpz 2015年

3
尽管您确实必须回答自己,但该主题是一篇出色的教程,涉及许多与山体阴影有关的问题。做得好!
克斯顿

您的教程就可以了。做得好。您能否考虑在这里回答我的问题=> ?是否可以为这种带有alpha波段的灰度GeoTIFF创建.ovr?
桑索恩(Sandthorn)

1
您好@sandthorn,尽管我很喜欢它,但我现在不在这个领域了。对于我来说,找到答案的成本可能会比您2018年更高。希望我的观点为您的问题指明正确的方向!
Hugolpz

7

获得更适合与其他图层组合的非灰色画布的相同结果的另一种方法是gdaldem中的“组合”选项。

它执行坡度和山丘阴影,并在一个操作中将两者结合。坡度为0的区域为白色。坡度阴影为90度的坡度区域为黑色,山坡阴影层增加了一些照明。

gdaldem hillshade -combined -compute_edges infile outfile.tif

然后使用多层合成模式将其“覆盖”在其他层上。

标准/组合阴影

标准山体阴影

组合阴影乘以OSM基础层(不透明度约50%) 组合阴影乘以OSM基本层


2

gdal+ convert基于工作流程

有一个gdal+ convert解决方案可以提供良好的视觉效果。该解决方案的问题在于convert会破坏您必须还原的地理信息。它增加了要执行的操作数量。

# Basic crop
gdal_translate -projwin 67 35.92 99 5 ../data/noaa/ETOPO1_Ice_g_geotiff.tif crop_xl.tmp.tif
# Grey-based hillshade
gdaldem hillshade crop_xl.tmp.tif shadedrelief.tmp.tif -s 111120 -z 5 -az 315 -alt 60 -compute_edges
# create a transparent hillshade:
convert shadedrelief.tmp.tif -fuzz 7% -fill "#FFFFFF" -opaque "#DDDDDD"  whited.jpg # makes all grey values white to lighten the filesize
convert whited.jpg -alpha copy -channel alpha -negate +channel trans.png # <=== TRICK HERE.
# Restore georeferencing & reproject            
gdal_translate -a_ullr 67 35.92 99 5 trans.png trans.tmp.gis.tif
gdalwarp -s_srs EPSG:4326 -t_srs ESPG:3857 ./trans.tmp.gis.tif ./trans_reproj.tmp.gis.tif
# Compress from 11MB to 2MB:
gdal_translate -co COMPRESS=LZW -co ALPHA=YES ./trans_reproj.tmp.gis.tif ./trans.gis.tif

有关命令4的说明,请参见:https : //stackoverflow.com/a/23018544/1974961

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.