Identificação de Figuras Geométricas usando Morfologia

Dada a imagem

nosso problema é determinar os seguintes itens:

  • (a) Qual a fração de pixels da imagem são brancos?
  • (b) Quantos objetos estão na imagem?
  • (c) A imagem contém quantos buracos?
  • (d) Quantos objetos possuem um ou mais buracos?
  • (e) Quantos objetos quadrados estão presentes na imagem?
  • (f) Identifique os objetos quadrados que possuem buracos.
  • (g) Identifique os objetos circulares que não possuem buracos.

Para resolvermos este problema, necessitaremos das seguintes bibliotecas de processamento de imagens: PyMorph e SciPy.

As funções utilizadas são declaradas no início do arquivo:

from numpy import logical_xor as xor
from numpy import array
from scipy.misc.pilutil import imsave, imread
from pymorph import binary
from pymorph import blob
from pymorph import close_holes
from pymorph import label

Considerando que a imagem em questão se chama ‘blocks1.png’, abrimos esta imagem e garantimos uma representação binária para os demais processamentos:

f = imread('blocks1.png', flatten=True)
binaryImage = binary(f)

Agora resolvemos os itens

(a) Qual a fração de pixels da imagem são brancos?

(N, M) = binaryImage.shape
totalOfPixels = N * M
whitePixels = (binaryImage > 0).sum()
blackPixels = (binaryImage == 0).sum()
whitePixelsFraction = (float(whitePixels) / float(totalOfPixels)) * 100.0
blackPixelsFraction = (float(blackPixels) / float(totalOfPixels)) * 100.0
output = "(a) The image contains %d white pixels (%0.2f%%) "
output += "and %d black (%0.2f%%)"
print "Answers: "
print output % (whitePixels, whitePixelsFraction, \
                blackPixels, blackPixelsFraction)

(b) Quantos objetos estão na imagem?

binaryWithoutHoles = close_holes(binaryImage)
labeledWithoutHoles = label(binaryWithoutHoles)
objectsWithoutHolesArea = blob(labeledWithoutHoles, 'area', output='data')
objectsWithoutHolesArea = array(objectsWithoutHolesArea)
recognizedObjects = objectsWithoutHolesArea.shape[0]
print "(b) The image have %d objects" % recognizedObjects

(c) A imagem contém quantos buracos?

diff = xor(binaryImage, binaryWithoutHoles)
labeledHoles = label(diff)
holesCentroids = blob(labeledHoles, 'centroid', output='data')
holesCentroids = array(holesCentroids)
numberOfDetectedHoles = holesCentroids.shape[0]
print "(c) The image have %d holes" % numberOfDetectedHoles

(d) Quantos objetos possuem um ou mais buracos?

labeledWithHoles = label(binaryImage)
objectsWithHolesArea = blob(labeledWithHoles, 'area', output='data')
objectsWithHolesArea = array(objectsWithHolesArea)
totalOfObjectsWithHoles = 0
for i in xrange(recognizedObjects):
    if objectsWithoutHolesArea[i] != objectsWithHolesArea[i]:
        totalOfObjectsWithHoles += 1
print "(d) %d objects have one or more holes" % totalOfObjectsWithHoles

(e) Quantos objetos quadrados estão presentes na imagem?

numberOfSquares = 0
objectsWithoutHolesBB = blob(labeledWithoutHoles, \
                             'boundingbox', output='data')
for i in xrange(recognizedObjects):
    (x1, y1, x2, y2) = objectsWithoutHolesBB[i]
    incorporatesRegionArea = (x1 - x2) * (y1 - y2)
    onlyObjectArea = objectsWithoutHolesArea[i]
    if incorporatesRegionArea == onlyObjectArea:
        numberOfSquares += 1
print "(e) The image contains %d squares" % numberOfSquares

(f) Identifique os objetos quadrados que possuem buracos.

perforatedSquares = 0
for i in xrange(recognizedObjects):
    (x1, y1, x2, y2) = objectsWithoutHolesBB[i]
    incorporatesRegionArea = (x1 - x2) * (y1 - y2)
    onlyObjectWithoutHoleArea = objectsWithoutHolesArea[i]
    onlyObjectWithHoleArea = objectsWithHolesArea[i]
    if incorporatesRegionArea == onlyObjectWithoutHoleArea and \
       onlyObjectWithoutHoleArea != onlyObjectWithHoleArea:
        perforatedSquares += 1
print "(f) %d squares are perfored" % perforatedSquares

(g) Identifique os objetos circulares que não possuem buracos.

notPerforedCircles = 0
for i in xrange(recognizedObjects):
    (x1, y1, x2, y2) = objectsWithoutHolesBB[i]
    incorporatesRegionArea = (x1 - x2) * (y1 - y2)
    onlyObjectWithoutHoleArea = objectsWithoutHolesArea[i]
    onlyObjectWithHoleArea = objectsWithHolesArea[i]
    if incorporatesRegionArea != onlyObjectWithoutHoleArea and \
       onlyObjectWithoutHoleArea == onlyObjectWithHoleArea:
        notPerforedCircles += 1
print "(f) %d circles have no holes" % notPerforedCircles