Files @ 9433c7ab2989
Branch filter:

Location: OneEye/exp/polar_hough.py - annotation

Laman
combined lines and stones Hough transform, ignoring stones convexity
import itertools
import math
import logging as log

import numpy as np
import scipy.signal

from geometry import angleDiff


class PolarHough:
	# http://www.cis.pku.edu.cn/vision/vpdetection/LiPYZ10isvc.pdf
	def __init__(self,anglePrecision,lengthPrecision):
		self._anglePrecision=anglePrecision
		self._lengthPrecision=lengthPrecision
		self._maxLength=4096
		n=math.ceil(2*math.pi/anglePrecision)
		self._acc=[[] for i in range(n)]

	def put(self,item):
		k=int(item[0]//self._anglePrecision)
		self._acc[k].append(item)

	def extract(self,count,trueVs):
		vanishingPoints=[]
		angles=self._extractAngles(count,tuple(v[0] for v in trueVs))
		angles=[alpha for (alpha,prominence) in angles]
		bins=self._mapAngles(angles)
		for (alpha,bin) in zip(angles,bins):
			(length,sampleCount)=self._extractLength([dist for (beta,dist) in bin])
			vanishingPoints.append((alpha,length))
		return vanishingPoints

	def _extractAngles(self,k,trueAngles):
		lens=np.array([0]+list(map(len,self._acc))+[0])
		marked=np.copy(lens[1:-1])
		for alpha in trueAngles:
			key=int(alpha/self._anglePrecision)
			marked[key]=-marked[key]-1
		log.debug(marked)
		(peakKeys,info)=scipy.signal.find_peaks(lens,prominence=0)
		res=sorted(zip(info["prominences"],peakKeys),reverse=True)[:k]
		res=[((key-1)*self._anglePrecision,prominence) for (prominence,key) in res]
		log.debug("(angle, prominence): %s ... %s",res,[alpha/self._anglePrecision for (alpha,_) in res])
		return res

	def _mapAngles(self,angles):
		res=[[] for alpha in angles]
		for (i,bin) in enumerate(self._acc):
			beta=i*self._anglePrecision
			key=min(zip(map(lambda alpha: angleDiff(alpha, beta), angles), itertools.count()))[1]
			res[key].extend(bin)
		return res

	def _extractLength(self,arr):
		acc=np.zeros(self._maxLength+1,dtype=np.int32)
		for dist in arr:
			dist=min(dist,self._maxLength)
			acc[int(dist//self._lengthPrecision)]+=1
		res=acc.argmax()
		log.debug("(length, count): %s",(res*self._lengthPrecision,acc[res]))
		return (res*self._lengthPrecision,acc[res])