예제 #1
0
def pSLID(img, thresh=150):
	"""find all lines using different settings"""
	print(utils.call("pSLID(img)"))
	segments = []; i = 0
	for key, arr in enumerate(NC_SLID_CLAHE):
		tmp = slid_clahe(img, limit=arr[0], grid=arr[1], iters=arr[2])
		__segments = list(slid_detector(slid_canny(tmp), thresh))
		segments += __segments; i += 1
		print("FILTER: {} {} : {}".format(i, arr, len(__segments)))
		debug.image(slid_canny(tmp)).lines(__segments).save("pslid_F%d" % i)
	return segments
예제 #2
0
def slid_clahe(img, limit=2, grid=(3,3), iters=5):
	"""repair using CLAHE algorithm (adaptive histogram equalization)"""
	img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
	for i in range(iters):
		img = cv2.createCLAHE(clipLimit=limit, \
				tileGridSize=grid).apply(img)
	debug.image(img).save("slid_clahe_@1")
	if limit != 0:
		kernel = np.ones((10, 10), np.uint8)
		img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
		debug.image(img).save("slid_clahe_@2")
	return img
예제 #3
0
def llr_pad(four_points, img):
	#print(utils.call("llr_pad(four_points)"))
	pco = pyclipper.PyclipperOffset()
	pco.AddPath(four_points, pyclipper.JT_MITER, pyclipper.ET_CLOSEDPOLYGON)
	
	padded = pco.Execute(60)[0]
	debug.image(img) \
		.points(four_points, color=(0,0,255)) \
		.points(padded, color=(0,255,0)) \
		.lines([[four_points[0], four_points[1]], [four_points[1], four_points[2]], \
		        [four_points[2], four_points[3]], [four_points[3], four_points[0]]], \
				color=(255,255,255)) \
		.lines([[padded[0], padded[1]], [padded[1], padded[2]], \
		        [padded[2], padded[3]], [padded[3], padded[0]]], \
				color=(255,255,255)) \
	.save("llr_final_pad")

	return pco.Execute(60)[0] # 60,70/75 is best (with buffer/for debug purpose)
예제 #4
0
def LAPS(img, lines, size=10):
    #print(utils.call("LAPS(img, lines)"))

    __points, points = laps_intersections(lines), []
    debug.image(img).points(__points, size=3).save("laps_in_queue")

    for pt in __points:
        # pixels are in integers
        pt = list(map(int, pt))

        # size of our analysis area
        lx1 = max(0, int(pt[0] - size - 1))
        lx2 = max(0, int(pt[0] + size))
        ly1 = max(0, int(pt[1] - size))
        ly2 = max(0, int(pt[1] + size + 1))

        # cropping for detector
        dimg = img[ly1:ly2, lx1:lx2]
        dimg_shape = np.shape(dimg)

        # not valid
        if dimg_shape[0] <= 0 or dimg_shape[1] <= 0: continue

        # use neural network
        re_laps = laps_detector(dimg)
        if not re_laps[0]: continue

        # add if okay
        if pt[0] < 0 or pt[1] < 0: continue
        points += [pt]
    points = laps_cluster(points)

    debug.image(img).points(points, size=5, \
     color=debug.color()).save("laps_good_points")

    return points
예제 #5
0
def SLID(img, segments):
	# FIXME: zrobic 2 rodzaje haszowania (katy + pasy [blad - delta])
	print(utils.call("SLID(img, segments)"))
	
	global all_points; all_points = []
	pregroup, group, hashmap, raw_lines = [[], []], {}, {}, []

	__cache = {}
	def __dis(a, b):
		idx = hash("__dis" + str(a) + str(b))
		if idx in __cache: return __cache[idx]
		__cache[idx] = np.linalg.norm(na(a)-na(b))
		return __cache[idx]

	X = {}
	def __fi(x):
		if x not in X: X[x] = 0;
		if (X[x] == x or X[x] == 0): X[x] = x
		else:                        X[x] = __fi(X[x])
		return X[x]
	def __un(a, b):
		ia, ib = __fi(a), __fi(b)
		X[ia] = ib; group[ib] |= group[ia]
		#group[ia] = set()
		#group[ia] = set()

	# shortest path // height
	nln = lambda l1, x, dx: \
		np.linalg.norm(np.cross(na(l1[1])-na(l1[0]),
								na(l1[0])-na(   x)))/dx

	def __similar(l1, l2):
		da, db = __dis(l1[0], l1[1]), __dis(l2[0], l2[1])
		# if da > db: l1, l2, da, db = l2, l1, db, da

		d1a, d2a = nln(l1, l2[0], da), nln(l1, l2[1], da)
		d1b, d2b = nln(l2, l1[0], db), nln(l2, l1[1], db)
	
		ds = 0.25 * (d1a + d1b + d2a + d2b) + 0.00001
		#print(da, db, abs(da-db))
		#print(int(da/ds), int(db/ds), "|", int(abs(da-db)), int(da+db),
		#		int(da+db)/(int(abs(da-db))+0.00001))
		alfa = 0.0625 * (da + db) #15
		# FIXME: roznica???
		#if d1 + d2 == 0: d1 += 0.00001 # [FIXME]: divide by 0
		t1 = (da/ds > alfa and db/ds > alfa)
		if not t1: return False # [FIXME]: dist???
		return True

	def __generate(a, b, n):
		points = []; t = 1/n
		for i in range(n):
			x = a[0] + (b[0]-a[0]) * (i * t)
			y = a[1] + (b[1]-a[1]) * (i * t)
			points += [[int(x), int(y)]]
		return points

	def __analyze(group):
		global all_points
		points = []
		for idx in group:
			points += __generate(*hashmap[idx], 10)
		_, radius = cv2.minEnclosingCircle(na(points)); w = radius * (math.pi/2)
		vx, vy, cx, cy = cv2.fitLine(na(points), cv2.DIST_L2, 0, 0.01, 0.01)
		# debug.color()
		all_points += points
		return [[int(cx-vx*w), int(cy-vy*w)], [int(cx+vx*w), int(cy+vy*w)]]

	for l in segments:
		h = hash(str(l))
		t1 = l[0][0] - l[1][0]
		t2 = l[0][1] - l[1][1]
		hashmap[h] = l; group[h] = set([h]); X[h] = h
		if abs(t1) < abs(t2): pregroup[0].append(l)
		else:                 pregroup[1].append(l)

	debug.image(img.shape) \
		.lines(pregroup[0], color=debug.color()) \
		.lines(pregroup[1], color=debug.color()) \
	.save("slid_pre_groups")

	for lines in pregroup:
		for i in range(len(lines)):
			l1 = lines[i]; h1 = hash(str(l1))
			#print(h1, __fi(h1))
			if (X[h1] != h1): continue
			#if (__fi(h1) != h1): continue
			for j in range(i+1, len(lines)):
				l2 = lines[j]; h2 = hash(str(l2))
				#if (__fi(h2) != h2): continue
				if (X[h2] != h2): continue
				#if (len(group[h2])==0): continue
				if not __similar(l1, l2): continue
				__un(h1, h2) # union & find
				# break # FIXME

	__d = debug.image(img.shape)
	for i in group:
		#if (__fi(i) != i): continue
		if (X[i] != i): continue
		#if len(group[i]) == 0: continue
		ls = [hashmap[h] for h in group[i]]
		__d.lines(ls, color=debug.color())
	__d.save("slid_all_groups")

	for i in group:
		#if (__fi(i) != i): continue
		if (X[i] != i): continue
		#if len(group[i]) == 0: continue
		#if (__fi(i) != i): continue
		raw_lines += [__analyze(group[i])]
	debug.image(img.shape).lines(raw_lines).save("slid_final")

	debug.image(img.shape)\
		.points(all_points, color=(0,255,0), size=2)\
	.lines(raw_lines).save("slid_final2")

	return raw_lines
예제 #6
0
def LLR(img, points, lines):
	#print(utils.call("LLR(img, points, lines)"))
	old = points

	# --- otoczka
	def __convex_approx(points, alfa=0.01):
		hull = scipy.spatial.ConvexHull(na(points)).vertices
		cnt = na([points[pt] for pt in hull])
		approx = cv2.approxPolyDP(cnt,alfa*\
				 cv2.arcLength(cnt,True),True)
		return llr_normalize(itertools.chain(*approx))
	# ---

	# --- geometria
	__cache = {}
	def __dis(a, b):
		idx = hash("__dis" + str(a) + str(b))
		if idx in __cache: return __cache[idx]
		__cache[idx] = np.linalg.norm(na(a)-na(b))
		return __cache[idx]

	nln = lambda l1, x, dx: \
		np.linalg.norm(np.cross(na(l1[1])-na(l1[0]),
								na(l1[0])-na(   x)))/dx
	# ---

	pregroup = [[], []]                   # podzial na 2 grupy (dla ramki)
	S = {}                                # ranking ramek // wraz z wynikiem

	points = llr_correctness(llr_normalize(points), img.shape) # popraw punkty

	# --- clustrowanie
	
	__points = {}; points = llr_polysort(points); __max, __points_max = 0, []
	alfa = math.sqrt(cv2.contourArea(na(points))/49)
	X = sklearn.cluster.DBSCAN(eps=alfa*4).fit(points) # **(1.3)
	for i in range(len(points)): __points[i] = []
	for i in range(len(points)):
		if X.labels_[i] != -1: __points[X.labels_[i]] += [points[i]]
	for i in range(len(points)):
		if len(__points[i]) > __max:
			__max = len(__points[i]); __points_max = __points[i]
	if len(__points) > 0 and len(points) > 49/2: points = __points_max
	#print(X.labels_)
	# ---

	# tworzymy zewnetrzny pierscien
	ring = __convex_approx(llr_polysort(points))

	n = len(points); beta = n*(5/100) # beta=n*(100-(skutecznosc LAPS))
	alfa = math.sqrt(cv2.contourArea(na(points))/49) # srednia otoczka siatki

	x = [p[0] for p in points]          # szukamy punktu
	y = [p[1] for p in points]          # centralnego skupiska
	centroid = (sum(x) / len(points), \
			    sum(y) / len(points))

	#print(alfa, beta, centroid)

	#        C (x2, y2)        d=(x_1−x_0)^2+(y_1−y_0)^2, t=d_t/d
	#      B (x1, y1)          (x_2,y_2)=(((1−t)x_0+tx_1),((1−t)y_0+ty_1))
	#    .                    t=(x_0-x_2)/(x_0-x_1)
	#  .
	# A (x0, y0)

	def __v(l):
		y_0, x_0 = l[0][0], l[0][1]
		y_1, x_1 = l[1][0], l[1][1]
		
		x_2 = 0;            t=(x_0-x_2)/(x_0-x_1+0.0001)
		a = [int((1-t)*x_0+t*x_1), int((1-t)*y_0+t*y_1)][::-1]

		x_2 = img.shape[0]; t=(x_0-x_2)/(x_0-x_1+0.0001)
		b = [int((1-t)*x_0+t*x_1), int((1-t)*y_0+t*y_1)][::-1]

		poly1 = llr_polysort([[0,0], [0, img.shape[0]], a, b])
		s1 = llr_polyscore(na(poly1), points, centroid, beta=beta, alfa=alfa/2)
		poly2 = llr_polysort([a, b, \
				[img.shape[1],0], [img.shape[1],img.shape[0]]])
		s2 = llr_polyscore(na(poly2), points, centroid, beta=beta, alfa=alfa/2)
		
		return [a, b], s1, s2

	def __h(l):
		x_0, y_0 = l[0][0], l[0][1]
		x_1, y_1 = l[1][0], l[1][1]
		
		x_2 = 0;            t=(x_0-x_2)/(x_0-x_1+0.0001)
		a = [int((1-t)*x_0+t*x_1), int((1-t)*y_0+t*y_1)]

		x_2 = img.shape[1]; t=(x_0-x_2)/(x_0-x_1+0.0001)
		b = [int((1-t)*x_0+t*x_1), int((1-t)*y_0+t*y_1)]

		poly1 = llr_polysort([[0,0], [img.shape[1], 0], a, b])
		s1 = llr_polyscore(na(poly1), points, centroid, beta=beta, alfa=alfa/2)
		poly2 = llr_polysort([a, b, \
				[0, img.shape[0]], [img.shape[1], img.shape[0]]])
		s2 = llr_polyscore(na(poly2), points, centroid, beta=beta, alfa=alfa/2)

		return [a, b], s1, s2

	for l in lines: # bedziemy wszystkie przegladac
		for p in points: # odrzucamy linie ktore nie pasuja
			# (1) linia przechodzi blisko dobrego punktu
			t1 = nln(l, p, __dis(*l)) < alfa
			# (2) linia przechodzi przez srodek skupiska
			t2 = nln(l, centroid, __dis(*l)) > alfa * 2.5 # 3
			# (3) linia nalezy do pierscienia
			# t3 = True if p in ring else False
			if t1 and t2:
			#if (t1 and t2) or (t1 and t3 and t2): # [1 and 2] or [1 and 3 and 2]
				tx, ty = l[0][0]-l[1][0], l[0][1]-l[1][1]
				if abs(tx) < abs(ty): ll, s1, s2 = __v(l); o = 0
				else:                 ll, s1, s2 = __h(l); o = 1
				if s1 == 0 and s2 == 0: continue
				pregroup[o] += [ll]

	pregroup[0] = llr_unique(pregroup[0])
	pregroup[1] = llr_unique(pregroup[1])

	from laps import laps_intersections
	debug.image(img) \
		.lines(lines, color=(0,0,255)) \
		.points(laps_intersections(lines), color=(255,0,0), size=2) \
	.save("llr_debug_1")

	debug.image(img) \
		.points(laps_intersections(lines), color=(0,0,255), size=2) \
		.points(old, color=(0,255,0)) \
	.save("llr_debug_2")

	debug.image(img) \
		.lines(lines, color=(0,0,255)) \
		.points(points, color=(0,0,255)) \
		.points(ring, color=(0,255,0)) \
		.points([centroid], color=(255,0,0)) \
	.save("llr_debug")
	
	debug.image(img) \
		.lines(pregroup[0], color=(0,0,255)) \
		.lines(pregroup[1], color=(255,0,0)) \
	.save("llr_pregroups")
	
	#print("---------------------")
	for v in itertools.combinations(pregroup[0], 2):            # poziome
		for h in itertools.combinations(pregroup[1], 2):        # pionowe
			poly = laps_intersections([v[0], v[1], h[0], h[1]]) # przeciecia
			poly = llr_correctness(poly, img.shape)             # w obrazku
			if len(poly) != 4: continue                         # jesl. nie ma
			poly = na(llr_polysort(llr_normalize(poly)))        # sortuj
			if not cv2.isContourConvex(poly): continue          # wypukly?
			S[-llr_polyscore(poly, points, centroid, \
				beta=beta, alfa=alfa/2)] = poly                 # dodaj

	S = collections.OrderedDict(sorted(S.items()))              # max
	K = next(iter(S))
	#print("key --", K)
	four_points = llr_normalize(S[K])               # score

	# XXX: pomijanie warst, lub ich wybor? (jesli mamy juz okay)
	# XXX: wycinanie pod sam koniec? (modul wylicznia ile warstw potrzebnych)

	#print("POINTS:", len(points))
	#print("LINES:", len(lines))

	debug.image(img).points(four_points).save("llr_four_points")

	debug.image(img) \
		.points(points, color=(0,255,0)) \
 		.points(four_points, color=(0,0,255)) \
		.points([centroid], color=(255,0,0)) \
		.lines([[four_points[0], four_points[1]], [four_points[1], four_points[2]], \
		        [four_points[2], four_points[3]], [four_points[3], four_points[0]]], \
				color=(255,255,255)) \
	.save("llr_debug_3")

	return four_points