I have a formula for suitability which I have created and I need to count how many pixels are in each class.

For example - Suitability class 0 has 12545 pixels - Suitability class 1 has 386 pixels - Suitability class 2 has 1145 pixels - Suitability class 3 has 518 pixels

Is there a python code for this????

By the way my program is set up because I am creating a tool(Beginning Stages). No Numpy allowed!

import arcpy
from arcpy import env
from arcpy.sa import *

arcpy.env.overwriteOutput = True

# Workspace location
env.workspace = arcpy.GetParametersAsText(0)

# DEM raster dataset
DEM = arcpy.GetParametersAsText(1)

# Land Use raster dataset
landUse = arcpy.GetParametersAsText(2)

#Floating point values of suitability weights
weight_1 = arcpy.GetParametersAsText(3)
weight_2 = arcpy.GetParametersAsText(4)
if ((weight_1 + weight_2 > 1.0),(weight_1 + weight_2 < 1)):
arcpy.AddMessage("Error! Weights limits not appropriate!")

# The output feature class name
outputFC = arcpy.GetParameterAsText(5)

# Get Slope of DEM raster
arcpy.sa.Slope(DEM, Slope_DEM,"DEGREE", "1")
arcpy.AddMessage("Slope Raster Created!")

# Reclassify Slope
reclass_slp = RemapRange([[0,3,3],[3,6,2],[6,90,1]])
reclass_slope = Reclassify(Slope_DEM, "VALUE", reclass_slp)
arcpy.AddMessage("Slope Raster Reclassified!")

# Get Aspect of DEM raster
outAspect = arcpy.sa.Aspect(DEM)
outAspect.save = (workspace)
arcpy.AddMessage("Aspect Raster Created!")

# Reclassify Aspect
reclass_aspt = RemapRange([[-1,0,3],[0,45,1],[45,135,2],[135,225,3],[225,315,2],[315,360,1]])
reclass_slope = Reclassify(Aspect_DEM, "VALUE", reclass_aspt)
reclass_aspt.save = (workspace)                          
arcpy.AddMessage("Aspect Raster Reclassified!")

# Reclassify Land Use Raster
reclass_land = arcpy.sa.Con(landUse,1, "Value == 18,21,73" )
reclass_land.save = (workspace) 
arcpy.AddMessage("Land Use Raster Reclassified!")

# Calculate Best Site and create resulting shapefile raster with interger values between 0 and 3
bestSite = (int((weight_1 * reclass_slp) + (weight_2 * reclass_aspt))* reclass_land)
arcpy.AddMessage("Suitability Raster Created!")
  • Convert to polygon, no line simplification. Area/cellize is your answer – FelixIP Feb 9 '17 at 3:41

You should already have the pixel count in your integer raster attribute table. If not, run Build Raster Attribute Table tool.

enter image description here

Then, it's just a matter of reading the table with an arcpy.da.SearchCursor.

my_raster = 'raster.tif'
my_dict = {row[0]:row[1] for row in arcpy.da.SearchCursor(my_raster,['Value','Count'])}
print my_dict

{0: 6518422.0, 1: 2182076.0, 2: 2495061.0, 3: 3982945.0}
| improve this answer | |
  • When attempting to build the raster attribute table, I get the error message "only single band integer raster is a valid input". The output raster from my raster calculator does not provide an attribute table. – A_Worthy Feb 8 '17 at 21:41
  • 1
    See @Damijan's answer here for converting multiband to singleband raster: gis.stackexchange.com/questions/91403/…. Which raster in your example are you trying to summarize? – phloem Feb 8 '17 at 21:45
  • arcpy.gp.RasterCalculator_sa("(weight_1 * \"%reclassify_sp%\" + weight_2 * \"%reclassify_at%\") * \"%reclass_land%\"", outputFC) – A_Worthy Feb 8 '17 at 21:47
  • 1
    That looks like you're trying to output a feature class. Raster Calculator outputs a raster. And what are the '%' for? That looks like model builder syntax. – phloem Feb 8 '17 at 21:51
  • I did use model builder. The result should be a raster with an attribute table i can view and get the count of. I'm just now sure where I went wrong. – A_Worthy Feb 8 '17 at 21:55

An easy way for an integer raster would be to convert it into a numpy array.

Here an arcpy approach.

import numpy, arcpy
raster_numpy_array = arcpy.RasterToNumPyArray("raster.tif")

# where 1 is your value
cnt_value_1 = numpy.count_nonzero(raster_numpy_array==1) 

Here a non arcpy approach with TIFF file:

from scipy import misc
from PIL import Image
Image.MAX_IMAGE_PIXELS = 1000000000   # to allow big tif
raster_numpy_array = scipy.misc.imread('raster.tif')

# where 1 is your value
cnt_value_1 = numpy.count_nonzero(raster_numpy_array==1) 

If you have a float integer, convert you array to a integer (8 ,16 bits.) with Copy Raster (Data Management).

| improve this answer | |
  • not allowed to use numpy – A_Worthy Feb 8 '17 at 21:42
  • 1
    @A_Worthy If you are not allowed to use NumPy then that should be mentioned in your question. – PolyGeo Feb 8 '17 at 21:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.