Files @ ffa9f7f12374
Branch filter:

Location: OneEye/exp/hough.py

Laman
experimenting with own Hough transform
import os
import sys
import math
from datetime import datetime
import logging as log

import numpy as np
import cv2 as cv

from annotations import DataFile,computeBoundingBox


class HoughTransform:
	def __init__(self,img):
		(h,w)=img.shape[:2]
		diagLen=np.sqrt(h**2+w**2)
		self._center=(w//2,h//2)
		self._acc=np.zeros((360,int(diagLen//2)+1),dtype=np.int32)

		self.update(img)

	def extract(self):
		maxVal=self._acc.max()
		arr=np.expand_dims(np.uint8(255*self._acc//maxVal),axis=2)
		img=np.concatenate((arr,arr,arr),axis=2)
		log.debug(sorted(list(findPeaks(self._acc)),key=lambda rc: self._acc[rc],reverse=True)[:2*19])
		show(img,"Hough transform accumulator")

	def update(self,img,weight=1):
		start=datetime.now().timestamp()
		for (r,row) in enumerate(img):
			for (c,pix) in enumerate(row):
				if pix==0: continue
				for alphaDeg in range(0,360):
					d=self._computeDist(c,r,alphaDeg)
					if d>=0: self._acc[(alphaDeg,d)]+=weight
		log.debug("Hough updated in %s s",round(datetime.now().timestamp()-start,3))

	def _computeDist(self,x,y,alphaDeg):
		alphaRad=alphaDeg*math.pi/180
		(x0,y0)=self._center
		(dx,dy)=(x-x0,y-y0)
		d=dx*math.cos(alphaRad)+dy*math.sin(alphaRad)
		return int(d)


def findPeaks(arr2d): # naive implementation
	(h,w)=arr2d.shape
	neighbours=[(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
	for r in range(h):
		for c in range(w):
			if all(r+dr<0 or r+dr>=h or c+dc<0 or c+dc>=w or arr2d[r,c]>arr2d[r+dr,c+dc] or (i<4 and arr2d[r,c]>=arr2d[r+dr,c+dc]) for (i,(dr,dc)) in enumerate(neighbours)):
				yield (r,c)


def show(img,filename="x"):
	cv.imshow(filename,img)
	cv.waitKey(0)
	cv.destroyAllWindows()


def filterVert(edges):
	kernel = np.array([[1,0,1],[1,0,1],[1,0,1]],np.uint8)
	edges = cv.erode(edges,kernel)
	kernel=np.array([[0,1,0],[0,1,0],[0,1,0]],np.uint8)
	edges=cv.dilate(edges,kernel)
	return edges

def filterHor(edges):
	kernel = np.array([[1,1,1],[0,0,0],[1,1,1]],np.uint8)
	edges = cv.erode(edges,kernel)
	kernel=np.array([[0,0,0],[1,1,1],[0,0,0]],np.uint8)
	edges=cv.dilate(edges,kernel)
	return edges

def filterDiag(edges):
	kernel = np.array([[0,0,1],[1,0,0],[0,1,0]],np.uint8)
	edges1 = cv.erode(edges,kernel)
	kernel=np.array([[1,0,0],[0,1,0],[0,0,1]],np.uint8)
	edges1=cv.dilate(edges1,kernel)

	kernel = np.array([[0,1,0],[1,0,0],[0,0,1]],np.uint8)
	edges2 = cv.erode(edges,kernel)
	kernel=np.array([[0,0,1],[0,1,0],[1,0,0]],np.uint8)
	edges2=cv.dilate(edges2,kernel)

	return edges1+edges2

def prepareEdgeImg(img):
	gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY)
	show(gray,"greyscale image")
	edges=cv.Canny(gray,70,130)
	show(edges,"Canny edge detector")
	edges=filterHor(edges)+filterVert(edges)+filterDiag(edges)
	show(edges,"kernel filtered edges")
	return edges

def houghLines(bwImg):
	colorImg=cv.cvtColor(bwImg,cv.COLOR_GRAY2BGR)
	lines = cv.HoughLinesP(bwImg,1,np.pi/180,10,minLineLength=10,maxLineGap=40)
	if lines is None: lines=[]
	for line in lines:
		x1,y1,x2,y2 = line[0]
		cv.line(colorImg,(x1,y1),(x2,y2),(0,255,0),1)

	show(colorImg)


if __name__=="__main__":
	i=sys.argv[1]
	annotations=DataFile("/home/laman/Projekty/python/oneEye/images/annotations.json.gz")
	filename="{0}.jpg".format(i)
	img=cv.imread(os.path.join("/home/laman/Projekty/python/oneEye/images/",filename))
	(x1,y1,x2,y2)=computeBoundingBox(annotations[filename][0])
	img=img[y1:y2, x1:x2, :]
	# blurred=cv.GaussianBlur(img,(5,5),0)
	# small=cv.resize(img,None,fx=0.5,fy=0.5,interpolation=cv.INTER_AREA)
	small=img
	clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
	gray=cv.cvtColor(small,cv.COLOR_BGR2GRAY)
	# gray=clahe.apply(gray)
	show(gray)
	edges=cv.Canny(gray,70,130)
	show(edges)
	edges=filterHor(edges)+filterVert(edges)+filterDiag(edges)
	show(edges)


	# kernel = np.ones((2,2),np.uint8)
	# edges = cv.morphologyEx(edges, cv.MORPH_DILATE, kernel)
	# show(edges)
	# edges=cv.morphologyEx(edges,cv.MORPH_ERODE,kernel)
	# show(edges)
	colorEdges=cv.cvtColor(edges,cv.COLOR_GRAY2BGR)

	# houghLines(edges)
	h=HoughTransform(edges)
	h.extract()