Pattern / Image matching

Reply

Join Date: Jul 2008
Posts: 39
Reputation: tillaart36 is an unknown quantity at this point 
Solved Threads: 0
tillaart36 tillaart36 is offline Offline
Light Poster

Pattern / Image matching

 
0
  #1
Jan 7th, 2009
Hello all,

I've written a piece of code that lets me generate or read a grid where all cells have a value. The grid stands for a simple 2d visualisation of an area where types of housing are to be build. The values of a cell stand for some different housing types. By a floodfill algorithm the program detects 'clusters' of cells with the same value. A cluster of cells hereby stands for 1 building with the type according to the cell value of this cluster.

This is the code so far:
  1. # Create a Python spatial grid.
  2.  
  3. from math import sqrt
  4. import csv
  5.  
  6. class Grid(object):
  7. markcnt = 0
  8. """Grid class with a width, height, length"""
  9. def __init__(self, width, height):
  10. self.grid = []
  11. self.width = width
  12. self.height = height
  13. self.length = width * height
  14. for x in range(self.width):
  15. col = []
  16. for y in range(self.height):
  17. col.append(Cell(x, y, self.grid))
  18. self.grid.append(col)
  19.  
  20. class Area(object):
  21. area = 0
  22.  
  23. def getWidth(self):
  24. return self.width
  25.  
  26. def getHeight(self):
  27. return self.height
  28.  
  29. def getLength(self):
  30. return self.length
  31.  
  32. def __len__(self):
  33. return self.length
  34.  
  35. def setCellValue(self, x, y, i):
  36. self.grid[x][y].value = i
  37.  
  38. def getCellValue(self, x, y):
  39. return self.grid[x][y].value
  40.  
  41. def getCell(self, x, y):
  42. return self.grid[x][y]
  43.  
  44. def __getitem__(self, (x, y)):
  45. return self.grid[x][y]
  46.  
  47. def index(self, value):
  48. return self.grid.index(value)
  49.  
  50. def fillBlock(self, left, right, top, bottom, value):
  51. # You can choose if you want to iterate over a range of left - exclusive right
  52. # or over a range of left - inclusive right. Same goes for top - exclusive bottom
  53. # or top - inclusive bottom
  54. # For now it's exclusive
  55. for x in range(left, right):
  56. for y in range(top, bottom):
  57. self[x, y].value = value
  58.  
  59. """
  60. def floodFill(self, x, y, landUse):
  61. visited = set()
  62. self.rec_floodFill(x, y, landUse, visited)
  63.  
  64. def rec_floodFill(self, x, y, landUse, visited):
  65. if (x < 0 or y < 0 or x >= self.width or y >= self.height):
  66. return
  67.  
  68. cell = self.grid[x][y]
  69. if (x, y) in visited:
  70. return
  71. visited.add((x,y))
  72.  
  73. if (cell.value != landUse):
  74. return
  75.  
  76. print visited
  77. self.rec_floodFill(x-1, y, landUse, visited)
  78. self.rec_floodFill(x+1, y, landUse, visited)
  79. self.rec_floodFill(x, y-1, landUse, visited)
  80. self.rec_floodFill(x, y+1, landUse, visited)
  81. """
  82.  
  83. def firstFreeCell(self):
  84. for y in range(self.height):
  85. for x in range(self.width):
  86. if self.grid[x][y].clusterId == -1:
  87. return self.grid[x][y]
  88. return None
  89.  
  90. def reset(self):
  91. for y in range(self.height):
  92. for x in range(self.width):
  93. self.grid[x][y].clusterId == -1
  94.  
  95. def floodFill(self, x, y, clusterId, landUse):
  96. if (x < 0 or y < 0 or x >= self.width or y >= self.height):
  97. return
  98.  
  99. cell = self.grid[x][y]
  100. area = 0
  101. if (cell.clusterId != -1 or cell.value != landUse):
  102. return
  103.  
  104. cell.setClusterId(clusterId)
  105. area += 1
  106.  
  107. self.floodFill(x-1, y, clusterId, landUse)
  108. self.floodFill(x+1, y, clusterId, landUse)
  109. self.floodFill(x, y-1, clusterId, landUse)
  110. self.floodFill(x, y+1, clusterId, landUse)
  111.  
  112. def analyze(self):
  113. freeCell = self.firstFreeCell()
  114. clusterId = 0
  115. while freeCell != None:
  116. self.floodFill(freeCell.x, freeCell.y, clusterId, freeCell.value)
  117.  
  118. freeCell = self.firstFreeCell()
  119. clusterId += 1
  120.  
  121. def printClusterId(self, clusterId):
  122. for y in range(self.height):
  123. for x in range(self.width):
  124. if self.grid[x][y].clusterId == clusterId:
  125. print 'clusterId:',clusterId,'Cell-coordinates:','(',self.grid[x][y].x,',',self.grid[x][y].y,')'
  126.  
  127.  
  128. """
  129. def printVisited(self, visited):
  130. for y in range(self.height):
  131. for x in range(self.width):
  132. if self.grid[x][y].visited == True:
  133. print self.grid[x][y].value,
  134. print
  135. """
  136.  
  137. def printVisited(self, visited):
  138. for y in range(self.height):
  139. for x in range(self.width):
  140. if self[x, y].visited:
  141. print self[x, y].value,
  142. else:
  143. print "x",
  144. print
  145.  
  146. def printGrid(self):
  147. for y in range(self.height):
  148. for x in range(self.width):
  149. print self[x, y].value,
  150. print
  151.  
  152. def load(cls, filename):
  153. print "Loaded csv file"
  154. loadGrid = []
  155. reader = csv.reader(open(filename), delimiter=';')
  156. for line in reader:
  157. loadGrid.append(line)
  158. width = len(loadGrid[0])
  159. height = len(loadGrid)
  160. grid = Grid(width, height)
  161. for x in range(width):
  162. for y in range(height):
  163. grid.getCell(x, y).value = loadGrid[x][y]
  164. return grid
  165. load = classmethod(load)
  166.  
  167. class Cell(object):
  168. def __init__(self, x, y, grid):
  169. self.x = x
  170. self.y = y
  171. self.grid = grid
  172. self.value = 0
  173. #self.visited = False
  174. self.clusterId = -1
  175.  
  176. def inspect(self):
  177. "#<Cell: value = #(value), x = #(x), y = #(y)>"
  178.  
  179. def getClusterId(self):
  180. return self.clusterId
  181.  
  182. def setClusterId(self, clusterId):
  183. self.clusterId = clusterId
  184.  
  185.  
  186. """
  187. class ParcelClusterAnalyzer(object):
  188. def __init__(self, prevLandUseCount, landUseCount, parcel, prevAreaList, areaList, prevLandUseClusters, landUseClusters, prevClusterBoundingBox, clusterBoundingBox):
  189. self.prevLandUseCount = {}
  190. self.landUseCount= {}
  191. self.parcel = parcel
  192. self.prevAreaList = {}
  193. self.areaList = {}
  194. self.prevLandUseClusters = {}
  195. self.landUseClusters = {}
  196. self.prevClusterBoundingBox = {}
  197. self.clusterBoundingBox = {}
  198.  
  199. class Area(object):
  200. area = 0
  201.  
  202. def ParcelClusterAnalyzer(self):
  203. pass
  204.  
  205. def ParcelClusterAnalyzer(self, parcel):
  206. self.parcel = parcel
  207. """
  208.  
  209. my_grid = Grid(7, 7)
  210. my_grid.printGrid()
  211. print '-'*20
  212.  
  213. my_grid[1, 1].value = 1
  214. my_grid[2, 0].value = 1
  215. my_grid[2, 1].value = 1
  216. my_grid[2, 2].value = 1
  217.  
  218. my_grid[3, 4].value = 2
  219. my_grid[3, 5].value = 2
  220. my_grid[4, 4].value = 2
  221. my_grid[4, 5].value = 2
  222. my_grid[5, 4].value = 2
  223. my_grid[5, 5].value = 2
  224.  
  225. my_grid.printGrid()
  226. print '-'*20
  227.  
  228. my_grid.firstFreeCell()
  229.  
  230. #my_grid.floodFill(x, y, landUse, area, boundingBox)
  231. print my_grid[1, 1].clusterId
  232. print '-'*20
  233.  
  234. my_grid.analyze()
  235. print my_grid[0, 0].clusterId
  236. print my_grid[1, 1].clusterId
  237. print my_grid[2, 0].clusterId
  238. print my_grid[2, 1].clusterId
  239. print my_grid[2, 2].clusterId
  240.  
  241. print my_grid[3, 4].clusterId
  242. print my_grid[3, 5].clusterId
  243. print my_grid[4, 4].clusterId
  244. print my_grid[4, 5].clusterId
  245. print my_grid[5, 4].clusterId
  246. print my_grid[5, 5].clusterId
  247.  
  248. my_grid.printClusterId(1)
  249. my_grid.printClusterId(2)
  250.  
  251.  
  252. """
  253. Uitkomst met beholp van floodFill moet volgende soort informatie geven:
  254.  
  255. class Cluster:
  256. pass
  257.  
  258. cluster = Cluster()
  259. cluster.cells = []
  260. cluster.cells.append(mygrid[2, 0])
  261. cluster.left = 1
  262. cluster.right = 2
  263. cluster.top = 0
  264. cluster.bottom = 2
  265. cluster.area = 4
  266.  
  267. cluster_list = [
  268. cluster
  269. ]
  270. """

The next idea is that I create a library of 2d templates which are simple 2d representations of the floorplans of the 3d models of buildings. What I have to program is an algorithm that compares the 2d form of the cluster with all the available 2d forms of the templates where the housing type is the same. Say I have a cluster representing detached housing with an L-shape like:

1 1 1 1 1
1 1
1 1

I need to find a template from the subset of detached housing from the library where the shape of the template matches this L-shape cluster the most.

I'm wondering what is the best method of doing this kind of matching tasks. I could compare each cell from the cluster with the value of the template on that place and calculate some scoring based on the matching cells. Or I could try and make some edge detection and compare the edge shape of cluster and template. Or I could go for a real image analysis where both cluster and template are visualised as an image of 2 colors (0 and 1 values have different colors) and try and program some kind of image matching algorithm that for each pixel of the template image evaluates the value of the cluster pixel and tries to find a match like this.

I know it's a bit of a long and difficult problem to explain but maybe someone has experience with these kind of problems or algorithms and can share some insight on it. I searched the internet on terms as image analysis, pattern matching, binary image analysis and so on...but mostly I find difficult mathematical papers that seem to go to deep in the problem for what I need for my program.
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the Python Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC