如何在pyvips中实现高效的多波段图像bandmax功能?
大型多波段图像中高效定位最大值所在波段的方法
我需要一种高效的方法,在大型多波段图像中找出每个像素最大值对应的波段。
示例输入图像:
band 1 band 2 band 3 [1 2 3] [3 4 5] [0 1 2] [3 2 1] [1 2 3] [1 0 1] [4 5 6] [6 7 5] [0 0 7]
期望的调用方式:
bandFind = A.bandmax()
bandFind的输出结果:
band 1 band 2 band 3 [0 0 0] [1 1 1] [0 0 0] [1 1 0] [0 0 1] [0 0 0] [0 0 0] [1 1 0] [0 0 1]
另外,也可以接受直接返回索引图像,我可以自行转换为上述格式。
我已经用Python写了一个实现函数,但处理大型图像时性能很差:
def pickMax(inImg): imBandSelect = pyvips.Image.black(inImg.width, inImg.height, bands=1) imBandMax = pyvips.Image.black(inImg.width, inImg.height, bands=1) for bandIndex, band in enumerate(inImg.bandsplit()): runningSelect = band > imBandMax imBandMax = runningSelect.ifthenelse(band, imBandMax) imBandSelect = runningSelect.ifthenelse(bandIndex, imBandSelect) bandList = [ (imBandSelect == bi) / 255.0 for bi in range(inImg.bands) ] return bandList[0].bandjoin(bandList[1:])
更新:
感谢@jcupitt的建议,我尝试了基于bandrank的实现版本:
def pickMaxUchar(inImg): short = (inImg.cast(pyvips.enums.BandFormat.USHORT)) << 8 index = pyvips.Image.black(short.width, short.height, bands=1).bandjoin_const([b for b in range(1, inImg.bands)]).cast(pyvips.enums.BandFormat.UCHAR) combo = short | index list = combo.bandsplit() ranked = list[0].bandrank(list[1:], index=inImg.bands-1) rankedindex = (ranked & 255).cast(pyvips.enums.BandFormat.UCHAR) bandList = [ (rankedindex == bi) / 255.0 for bi in range(inImg.bands) ] return bandList[0].bandjoin(bandList[1:])
这个版本假设输入是char类型,但我的原函数处理的是float类型。或许存在无需转换数据的实现方式,但目前这个版本相比我之前的“朴素”实现并没有性能提升,可能没办法进一步加速了。
内容的提问来源于stack exchange,提问作者matth
相关产品推荐
相关产品推荐

