diff --git a/exp/hough.py b/exp/hough.py --- a/exp/hough.py +++ b/exp/hough.py @@ -34,6 +34,10 @@ class LineBag: class HoughTransform: + """Find line sequences with Hough transform. + + Uses usual image coordinates on input and output, with [0,0] in the upper left corner and [height-1,width-1] in the lower right. + However, internally it uses the usual cartesian coordinates, centered at the image center. [-w/2,-h/2] in the upper left and [w/2,h/2] in the lower right.""" def __init__(self,img): self._angleBandwidth=30 # degrees @@ -58,10 +62,8 @@ class HoughTransform: keys=self._readLineKeys(alpha,beta) for k in peaks: (alphaDeg,d)=keys[k] - alphaRad=alphaDeg*math.pi/180 - baseLine=Line(alphaRad,0) - dd=baseLine.distanceTo(EPoint(*self._center)) # to shift d from the center to 0,0 - res.append(Line(alphaRad, dd+d-self._diagLen//2)) + line=Line(alphaDeg*math.pi/180,d-self._diagLen//2) + res.append(self._transformOutput(line)) i+=1 self.show(img) @@ -77,17 +79,21 @@ class HoughTransform: self._acc[(alphaDeg,d)]+=weight log.debug("Hough updated in %s s",round(datetime.now().timestamp()-start,3)) + def show(self,img=None): + if img is None: img=self._createImg() + show(img,"Hough transform accumulator") + def _computeDist(self,x,y,alphaDeg): alphaRad=alphaDeg*math.pi/180 (x0,y0)=self._center - (dx,dy)=(x-x0,y-y0) + (dx,dy)=(x-x0,y0-y) d=dx*math.cos(alphaRad)+dy*math.sin(alphaRad) return round(d) def _detectLines(self): bag=LineBag() - for alpha in range(0,180,2): - for beta in range(max(alpha-60,0),alpha+60,2): + for alpha in range(0,180+60,2): + for beta in range(max(alpha-60,0),min(alpha+60,180+60),2): accLine=[self._acc[key] for key in self._readLineKeys(alpha,beta)] (peaks,props)=scipy.signal.find_peaks(accLine,prominence=0) (prominences,peaks)=zip(*sorted(zip(props["prominences"],peaks),reverse=True)[:19]) @@ -99,16 +105,19 @@ class HoughTransform: res=[] for i in range(n+1): k=round((alpha*(n-i)+beta*i)/n) - if k<0 or k>=180: + if k>=180: k=k%180 - i=n+1-i + i=n-i res.append((k,i)) return res - def show(self,img=None): - if img is None: img=self._createImg() - - show(img,"Hough transform accumulator") + def _transformOutput(self,line): + (x,y)=self._center + basis=EPoint(-x,y) + shiftedLine=line.shiftBasis(basis) + reflectedLine=Line(math.pi*2-shiftedLine.alpha,shiftedLine.d) + log.debug("%s -> %s",line,reflectedLine) + return reflectedLine def _createImg(self): maxVal=self._acc.max()