Changeset - 90d22d070710
[Not reviewed]
default
0 2 0
Laman - 6 years ago 2019-01-14 17:04:05

refactored line reconstruction
2 files changed with 37 insertions and 22 deletions:
0 comments (0 inline, 0 general)
exp/stone_detect.py
Show inline comments
 
@@ -17,10 +17,14 @@ from analyzer.epoint import EPoint
 
random.seed(361)
 

	
 

	
 
class NeighboringPoint(EPoint):
 
	def __init__(self,x,y):
 
		super().__init__(x,y)
 
		self.neighbours=[]
 
class Line():
 
	def __init__(self,a,b):
 
		self.a=a
 
		self.b=b
 
		self.points={a,b}
 

	
 
	def getSortedPoints(self):
 
		return tuple(sorted(self.points))
 

	
 

	
 
def kmeans(img):
 
@@ -81,13 +85,13 @@ def groupLines(points,minCount,tolerance
 
	for (i,a) in enumerate(sample):
 
		for (j,b) in enumerate(sample):
 
			if j<=i: continue
 
			incidentPoints=[a,b]
 
			ab=Line(a,b)
 
			for c in points:
 
				if c is a or c is b: continue
 
				if point2lineDistance(a,b,c)<=tolerance:
 
					incidentPoints.append(c)
 
			if len(incidentPoints)>=minCount:
 
				yield incidentPoints
 
					ab.points.add(c)
 
			if len(ab.points)>=minCount:
 
				yield ab
 

	
 

	
 
if __name__=="__main__":
 
@@ -131,24 +135,25 @@ if __name__=="__main__":
 
	for (p,c) in stoneLocs:
 
		cv.drawMarker(linesImg,(int(p.x),int(p.y)),(255,0,0),cv.MARKER_CROSS)
 

	
 
	lineSet=set()
 
	lineDict=dict()
 
	minCount=min(max(math.sqrt(len(stoneLocs))-2,3),7)
 
	print("min count:",minCount)
 
	for points in groupLines([point for (point,contour) in stoneLocs],minCount,2):
 
		points=tuple(sorted(tuple(p) for p in points))
 
		lineSet.add(points)
 
	for line in groupLines([point for (point,contour) in stoneLocs],minCount,2):
 
		key=line.getSortedPoints()
 
		if key in lineDict: # we already have a line with the same incident points
 
			continue
 
		lineDict[line.getSortedPoints()]=line
 
		obsolete=set()
 
		pointSet=set(points)
 
		for line in lineSet:
 
			lineS=set(line)
 
			if points is line: continue
 
			if pointSet<lineS:
 
				lineSet.remove(points)
 
		for ab in lineDict.values():
 
			if ab is line: continue
 
			if line.points<ab.points: # == impossible
 
				del lineDict[line.getSortedPoints()]
 
				break
 
			if lineS<pointSet:
 
				obsolete.add(line)
 
		lineSet-=obsolete
 
	for line in sorted(lineSet,key=len,reverse=True)[:16]:
 
			if ab.points<line.points:
 
				obsolete.add(ab.getSortedPoints())
 
		for key in obsolete: del lineDict[key]
 

	
 
	for line in sorted(lineDict, key=len, reverse=True)[:16]:
 
		print(len(line),line)
 
		(xa,ya)=line[0]
 
		(xb,yb)=line[-1]
src/analyzer/epoint.py
Show inline comments
 
@@ -69,5 +69,15 @@ class EPoint:
 
		elif key==1: return self.y
 
		raise IndexError(key)
 

	
 
	def __hash__(self):
 
		return hash((self.x,self.y))
 

	
 
	def __lt__(self,a): return self.x<a.x or (self.x==a.x and self.y<a.y)
 
	def __le__(self,a): return self.x<a.x or (self.x==a.x and self.y<=a.y)
 
	def __gt__(self,a): return self.x>a.x or (self.x==a.x and self.y>a.y)
 
	def __ge__(self,a): return self.x>a.x or (self.x==a.x and self.y>=a.y)
 
	def __eq__(self,a): return self.x==a.x and self.y==a.y
 
	def __ne__(self,a): return self.x!=a.x or self.y!=a.y
 

	
 
	def __str__(self): return "({0},{1})".format(round(self.x,3),round(self.y,3))
 
	def __repr__(self): return "EPoint({0},{1})".format(round(self.x,3),round(self.y,3))
0 comments (0 inline, 0 general)