我试图在ArcMap中将一个4band(RGB&nr红外线)光栅图像转换成numPy数组。一旦成功转换成numpy数组,我想计算图像上没有数据的像素数。当这些数据在通道1中被标记为“绿色”或“无”时,它们被标记为“蓝色”或“无”。我要找到他们。在
以下是我目前所掌握的情况:
import numpy
import os
myDir = "C:\\Temp\\temp"
# myFile = "4_pixel_test.tif"
myFile = "4band.tif"
# import 4band (R,G,B & nr Infrared) image
fName = os.path.join(myDir, myFile)
head, tail = os.path.split(fName)
# Convert Raster to Array, Default using LowerLeft as Origin
rasArray = arcpy.RasterToNumPyArray(fName)
# find out the number of bands in the image
nbands = rasArray.shape[0] # int
# print nbands (int)
blackCount = 0 # count the black pixels per image
th = 0 # Threhold value
# print rasArray
r, g, b, a = rasArray # not working
rCheck = numpy.any(r <= th)
gCheck = numpy.any(g <= th)
bCheck = numpy.any(b <= th)
aCheck = numpy.any(a == 0)
print rCheck
print gCheck
print bCheck
print aCheck
# show the results
if rCheck:
print ("Black pixel (red): %s" % (tail))
elif gCheck:
print ("Black pixel (green): %s" % (tail))
elif bCheck:
print ("Black pixel (blue): %s" % (tail))
else:
print ("%s okay" % (tail))
if aCheck:
print ("Transparent pixel: %s" % (tail))
^{pr2}$Runtime error Traceback (most recent call last): File "", line 14, in File "c:\program files (x86)\arcgis\desktop10.2\arcpy\arcpy__init__.py", line 1814, in RasterToNumPyArray return _RasterToNumPyArray(*args, **kwargs) RuntimeError: ERROR 999998: Unexpected Error.
我能够将光栅图像从代码here更改为numPY数组。在
不确定numPY数组是如何存储的,但当遍历它时,数据会从y轴开始打印出来,并向下(逐列)处理图像,而不是x(逐行)。在
我需要切换这个,这样我就可以从左上角到右下角逐像素地读取数据(RGBA)。不过,我对纽比的了解还不够。在
我认为这个错误可能是由于tiff的大小引起的:它在2.5MB时工作正常,但在4GB时却会出现问题。:(
你好像在问
np.nditer
。在除非需要低级控制,否则不希望使用
nditer
。然而,你几乎永远不需要这种程度的控制。最好不要使用nditer
,除非您确切知道为什么需要它。在你得到的是一个三维纽比阵列。您当前正在迭代数组中的每个元素。相反,您只需要迭代数组的前两个维度(宽度和高度)。在
迭代三维数组
作为一个快速的示例,您可以在没有ArcMap的情况下重现所看到的内容:
(简要说明:我在这里使用
arcpy
的形状约定nbands x nrows x ncolumns
。看到nrows x ncolumns x nbands
也是很常见的。在这种情况下,后面部分中的索引表达式将不同于)同样,
^{pr2}$nditer
不是您想要的,因此如果您确实想这样做(数组中的每个值而不是每个r、g、b像素),那么这样做的可读性会更高:在这种情况下,两者是相同的。在
迭代像素
不过,如果继续下去,您需要遍历每个像素。在这种情况下,你可以做一些类似的事情:
在本例中,我们暂时将10x10x3阵列视为100x3阵列。因为默认情况下numpy数组迭代第一个轴,所以它将迭代每个r,g,b元素。在
如果您愿意,也可以直接使用索引,但速度会慢一些:
矢量化,不要遍历
numpy
数组不过,一般来说,像这样逐个元素遍历数组元素并不是使用
numpy
的有效方法。在你提到你正在尝试检测何时波段被消除和/或设置为一个常量值。在
有三件事你可能是指:1)只有一个波段,2)某些波段的数据被设置为0(或其他值),3)图像是灰度级的,但存储为RGB。在
您可以通过查看numpy数组来检查频带数:
或者直接使用
arcpy
:这处理了第一种情况,但是,看起来你在试图检测什么时候乐队没有信息,而不是他们是否在那里。在
如果您总是希望至少有红色、绿色和蓝色(有时是alpha,有时不是),那么最简单的方法是将这些波段展开,这有点类似于:
这样的话,如果有α带,我们就忽略它,如果它不存在,那就不重要了。同样,假设数据的形状是nbands x nrows x ncolumns(而不是nrows x ncolumns x nbands)。在
下一步,如果我们想检查一个波段中的所有像素值是否为零,请不要迭代。相反,使用numpy布尔比较。它们的速度将大大提高(100倍):
但是,我猜你最想检测的是一个存储为RGB的灰度图像。在这种情况下,每个像素的红、绿、蓝值将相等,但像素不会全部相同。您可以通过以下操作进行检查:
一般来说,您并不想迭代numpy数组中的每个像素。请改用矢量化表达式。在
假设您已经知道图像大小(nxm),并且您的1d numpy数组是A,那么这就可以了。在
示例:假设您的图像数组是
^{pr2}$但你被赋予 A=数组([1,3,5,2,4,6]) 你想要的输出是
相关问题 更多 >
编程相关推荐