9

I have a n:2 Matrix with points(x,y) found from dots in a rectangular calibration pattern. I like to sort these points row by row. I have sorted these points with lexsort but the distortion from the camera is too big so that y-coordinates will be overlap.

imageloading...
blobs=imageprocessing....
coordinates=np.array([blob.centroid() for blob in blobs])
nd=np.lexsort((coordinates[:,0],coordinates[:,1]))
coordinates=coordinates[ind]

enter image description here

Is there a way to sort this with help of a delaunay pattern going a long the rows?

import matplotlib.tri as tri 
x=coordinates[:,0] y=coordinates[:,1]
triang = tri.Triangulation(x, y)

enter image description here

Hooked
  • 84,485
  • 43
  • 192
  • 261
  • Can you count on the x-coordinates not overlapping? You could invert your sorting order and then transpose the resulting matrix. That would make life much, much easier. The Delaunay triangulation may be more robust to small overlaps, but if the distortion is too large, it will also break down the rectangular pattern. – Jaime Dec 18 '12 at 17:04
  • Why would you want to sort them? The point of calibrating is that you can 'just' put a large number of point in the algorithms. After calibrating, you can restore the image and the points will be exactly on lines. – Rob Audenaerde Dec 20 '12 at 08:14

1 Answers1

2

Using triangulation is indeed interesting, and can be used for you application:

import numpy as np
import matplotlib.tri as tri
import matplotlib.pyplot as plt
import random

# create fake data
x,y = np.meshgrid(np.arange(10), np.arange(10))
x = x.flatten()
y = y.flatten()
coordinates = np.column_stack([x,y])+0.04 * np.random.rand(len(x), 2)
np.random.shuffle(coordinates)
x=coordinates[:,0]
y=coordinates[:,1]

# perform triangulation
triang=tri.Triangulation(x,y)
f = plt.figure(0)
ax = plt.axes()
tri.triplot(ax,triang)

# find horizontal edges
f = plt.figure(1)
e_start = coordinates[triang.edges[:,0]]
e_end = coordinates[triang.edges[:,1]]
e_diff = e_end - e_start
e_x = e_diff[:,0]
e_y = e_diff[:,1]

e_len = np.sqrt(e_x**2+e_y**2)
alpha = 180*np.arcsin(e_y/e_len)/np.pi

hist, bins, patches = plt.hist(alpha, bins=20)

# in the histogram, we find that the 'horizontal' lines
# have an alpha < 10.

ind_horizontal = (-10<alpha) & (alpha < 10)
edges_horizontal = triang.edges[ind_horizontal]
plt.show()

As a result, you get the horizontal edges in edges_horizontal, which is an 2d array [[p_{0},p_{1}], ..., [p_{n}, p_{n+1}]], in which p_i are indices into the coordinates array.

Hansemann
  • 952
  • 5
  • 6