'''Morphology operations on PixelMath images.
S. Tanimoto, Oct. 10, 2010.
The erode operation takes three arguments that are the
window numbers of the images to be used. They should
all exist before the call to erode is made.
The first two are inputs and the third is output.
The structuring element is normally a very small
image (e.g., 3 by 3, or maybe 5 by 7, etc.).
The structuring element is an image whose pixels'
red components are either 1 or 0 (actually 0 or
anything not 1). The green and blue components
are ignored. We assume the origin of the structuring
element is at its center if its dimensions are odd;
otherwise slightly closer to the lower-left corner.
A formula is constructed that considers source pixels
at all displacements specified by the structuring
element and either ANDs or ORs them. AND is for
erosion, and OR is for dilation.
The hit_or_miss operation takes a structuring element
whose pixels' red components are either 1, 0, or other.
Other means don't care. 1 means the source image must be
greater than 0, whereas 0 means the source image must be 0
at the corresponding location. The blue and green
components are ignored, as with the other cases.
'''
def create_morphology_formula(SE_win, dilation=False, hit_or_miss=False):
w = pmGetImageWidth(SE_win)
h = pmGetImageHeight(SE_win)
if dilation: logicOp = "or "
else: logicOp = "and " # erosion
# Consider the origin to be in the middle:
xc = w / 2
yc = h / 2
# Generate the formula
f = "If "
for x in range(w):
for y in range(h):
SE_pixel = pmGetPixel(SE_win, x, y)
if SE_pixel[0]==1:
f += "s1(x+"+str(x-w+xc+1)+",y+"+str(y-h+yc+1)+")>0 "
f += logicOp
if hit_or_miss and SE_pixel[0]==0:
f += "s1(x+"+str(x-w+xc+1)+",y+"+str(y-h+yc+1)+")=0 "
f += logicOp
# Remove last "and " or "or ":
if f[-len(logicOp):]==logicOp: f = f[:-len(logicOp)]
f += "then 255 else 0"
return f
def test():
se = pmNewComputedImage("Structuring Elt.", 2, 3, "1")
f = create_morphology_formula(se)
print f
#test()
def erode(orig_win, SE_win, dest_win):
pmSetSource1(orig_win)
pmSetDestination(dest_win)
pmSetFormula(create_morphology_formula(SE_win))
pmCompute()
def dilate(orig_win, SE_win, dest_win):
pmSetSource1(orig_win)
pmSetDestination(dest_win)
pmSetFormula(create_morphology_formula(SE_win, dilation=True))
pmCompute()
def hit_or_miss(orig_win, SE_win, dest_win):
pmSetSource1(orig_win)
pmSetDestination(dest_win)
pmSetFormula(create_morphology_formula(SE_win, hit_or_miss=True))
pmCompute()
# The following function can be useful for constructing structuring elements.
def array_to_monochrome_pixelmath_image(listOfLists, window_num):
nrows = len(listOfLists)
ncols = len(listOfLists[0])
try:
for x in range(ncols):
for y in range(nrows):
val = listOfLists[y][x]
pmSetPixel(window_num, x, y, val, val, val)
except:
print "Could complete the operation - array_to_monochrome_pixelmath_image."
print "Check the dimensions of your list of lists, and the image."
def test2():
se = pmNewComputedImage("Structuring Elt.", 2, 3, "(x + y) mod 3")
f = create_morphology_formula(se, hit_or_miss=True)
print f
#test2()