Standards /

WCPS-Tutorial / Coverage constructor: how to build new coverages on the fly

The coverage constructor allows to create a new coverage on the fly and fill it with values resulting from some expression evaluation.

In the simplest case, this value can be a constant; the following request would generate a 100x100 uniformly grey image:

for c in ( rgb )
return
	encode( coverage greyImage
	        over     px x(0,99),
                         py y(0,99)
	        values   (char) 127,
	        "jpeg" )

Note that you need to indicate some existing collection even if it is not used in the return clause.

This example is not overly exciting, so let's proceed to make use of the coordinates which are available from the over clause. We might even use them directly as result values, for example to create a grey shade:

for c in ( rgb )
return
	encode( coverage greyShade
	        over     px x(0,99), py y(0,99)
	        values   (char) p[0],
	        "jpeg" )

This would result in the image below:

So we can make free use of the coordinates. Among the important applications of this are filter kernels where coverage cells are modified under control of a weighting matrix, which itself can be modeled as a coverage.: For each pixel of the result image its value is determined by combining the resp. pixel from the original image and some neighbourhood of this original pixel. In WCPS we express combination of the cell values by means of a condenser and a matrix that defines the combination pattern through weights.

Example: "Apply filter m to coverage rgb." (part of the complete formula)

for c in ( rgb ),
    m in ( mask )
return
	encode( coverage greyShade
	        over     px imageCrsDomain(c)[x],
                         py imageCrsComain(c)[y]
	        values   condense +
	                 over qx imageCrsDomain(m)[x]
	                      qy in imageCrsDomain(m)[y]
	                 using c[ x(px+qx), y(py+qy) ] * m[ x(qx), y(qy) ],
	        "jpeg" )

Actually the coverage constructor allows to derive coverages with a semantics completely independent from the input data.

Example: "A histogram over panchromatic coverage cottbus, encoded as CSV."

for c in ( cottbus )
return
	encode( coverage histogram
	        over     n histogram(0,255)
	        values   count( c = n ),
	        "csv" )

The result is a 1-D coverage, it is returned as a comma-separated value list. Below original image and histogram (ie, a 1-D coverage) are displayed:

 

The last example relied on 8-bit integer cells. For floating point cell values the request gets more involved as we need to explicitly query each bucket interval, rather than just testing for equality. Hence, we need to retract to a general condenser.

Example: "A histogram over the x windspeed component of 4-D climate data set climateModel, encoded as CSV."

for c in ( climateModel )
return
	encode( coverage histogram
	        over     n histogram(-20,+20)
	        values   condense +
                         over     px x(imageCrsDomain( c, x )),
                                  py y(imageCrsDomain( c, y ))
                         using    c[ x(px), y(py) ]>n-1 and c[ x(px), y(py) ]<=n,
	        "csv" )

The result again is a 1-D coverage over integer values; below is a 3-D slice of a 4-D climate data set together with a histogram derived from this 4-D set:

 

Background information:

  • The coverage initially has only an identifier, a domain with an ImageCRS associated, and its cell values. All other constituents, such as further CRSs or a null value set, are empty.

See manual: coverageConstructorExpr