Files
@ 29f28718a69b
Branch filter:
Location: OneEye/exp/ransac.py - annotation
29f28718a69b
1.4 KiB
text/x-python
transitional data processing
6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 6aace8f39e75 | import random
from geometry import Line
class LineBag:
def __init__(self,capacity):
self._capacity=capacity
self._bag=[]
def put(self,item):
# early abort
if self._bag and item>self._bag[-1]: return
(v,p)=item
# mostly filter duplicates
for (i,(vi,pi)) in enumerate(self._bag):
if abs(p.alpha-pi.alpha)<0.02 and abs(p.d-pi.d)<5:
if v<vi: self._bag[i]=item
return
# add new and remove the last
self._bag.append(item)
self._bag.sort()
if len(self._bag)>self._capacity:
self._bag.pop()
def pull(self,count=0):
return self._bag[:count] if count else self._bag[:]
class Ransac:
def __init__(self,points):
self._points=points
def extract(self,count,iterations):
bag=LineBag(count)
for i in range(iterations):
line=self._generateLine()
score=self._scoreLine(line)
bag.put((score+random.random()/1000,line))
return [line for (score,line) in bag.pull()]
def _generateLine(self):
(a,b)=random.sample(self._points,2)
return Line.fromPoints(a,b)
def _scoreLine(self,line):
return sum(min(line.distanceTo(p),5) for p in self._points)
class DiagonalRansac(Ransac):
def __init__(self,points,sideLen):
super().__init__(points)
self._sideLen=sideLen
def _generateLine(self):
n=len(self._points)
m=self._sideLen
ka=random.randrange(0,n)
kb=ka
while ka//m==kb//m or ka%m==kb%m:
kb=random.randrange(0,n)
a=self._points[ka]
b=self._points[kb]
return Line.fromPoints(a,b)
|