Skip to content

Instantly share code, notes, and snippets.

@sdhegde
Last active January 23, 2020 21:18
Show Gist options
  • Save sdhegde/b44adebc79655094add4e8313fff0a87 to your computer and use it in GitHub Desktop.
Save sdhegde/b44adebc79655094add4e8313fff0a87 to your computer and use it in GitHub Desktop.
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
import glob
import math
import itertools
import random
minlinelength = 350
snaplength = 60
protrusion = 30
gapbetweenlines = 30
snapToBorder = 100
def clean(mess, orientation):
removed = []
added = []
cnt1 = 0
while cnt1 < len(mess):
#print("start-Mess: ", mess)
#print("start-Removed: ", removed)
l = mess[cnt1]
if(l not in removed):
cnt2 = 0
while cnt2 < len(mess):
j = mess[cnt2]
if( (l != j) and (j not in removed)):
if(orientation == "h"):
gap = abs(l[1]-j[1])
#print("gap h: ", gap)
else:
gap = abs(l[0]-j[0])
#print("gap v: ", gap)
if( gap < gapbetweenlines):
length1 = math.sqrt((l[2]-l[0])**2 + (l[3]-l[1])**2)
length2 = math.sqrt((j[2]-j[0])**2 + (j[3]-j[1])**2)
length = max(length1, length2)
if(orientation == "h"):
x0 = min(l[0], j[0])
x1 = max(l[2], j[2])
if(length == length1):
y0 = l[1]
else:
y0 = j[1]
y1 = y0
else:
y0 = max(l[1], j[1])
y1 = min(l[3], j[3])
if(length == length1):
x0 = l[0]
else:
x0 = j[0]
x1 = x0
if([x0,y0,x1,y1] not in mess):
mess.append([x0,y0,x1,y1])
removed.append(l)
removed.append(j)
else:
if([x0,y0,x1,y1] == l):
removed.append(j)
else:
removed.append(l)
'''print("l=", l)
print("j=", j)
print("new=", [x0,y0,x1,y1])'''
break
cnt2 += 1
cnt1 += 1
#print("End-Mess: ", mess)
#print("End-Removed: ", removed)
#mess1 = [i for i in mess if i not in removed]
#print("Removed list: ", removed)
try:
for i in removed:
mess.remove(i)
except ValueError:
pass
#print("After remove: ", mess)
return mess
def drawAllLines(img, linelist, thickness):
for l in linelist:
cv.line(img, (l[0], l[1]), (l[2], l[3]), (0,0,255), thickness)
img_rgb = cv.imread('/home/sdh/Pictures/images/del.png')
img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)
blank_image = np.zeros(shape=img_rgb.shape, dtype=np.uint8)
'''
for i in glob.glob("/home/sdh/Pictures/templates/" + "*.png"):
template = cv.imread(i,0)
w, h = template.shape[::-1]
res = cv.matchTemplate(img_gray,template,cv.TM_CCOEFF_NORMED)
threshold = 0.7
loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):
#cv.rectangle(blank_image, pt, (pt[0] + w, pt[1] + h), (0,0,255), -1)
cv.circle(blank_image, (int(pt[0]+w/2), int(pt[1]+h/2)), 1, (0, 0, 255), -1)
cv.imwrite('op1.png',blank_image)
'''
#resized = imutils.resize(blank_image, width = int(blank_image.shape[1] * 0.25))
#resized = cv.resize(blank_image, (int(blank_image.shape[0]/4), int(blank_image.shape[1]/4)), interpolation = cv.INTER_AREA)
dst = cv.Canny(img_gray, threshold1=50, threshold2=200, apertureSize = 3)
#linesP = cv.HoughLinesP(dst, 1, np.pi/180, 20, None, 20, 12)
linesP = cv.HoughLinesP(dst, rho=1, theta=np.pi/180, threshold=50, minLineLength=20, maxLineGap=12)
newblank_image = np.zeros((img_rgb.shape[0], img_rgb.shape[1], 3), dtype=np.uint8)
vline = []
hline = []
if linesP is not None:
for i in range(0, len(linesP)):
l = linesP[i][0]
angle = np.arctan2(l[1] - l[3], l[0] - l[2])
deg = np.degrees([angle])
length = math.sqrt((l[2]-l[0])**2 + (l[3]-l[1])**2)
if(deg[0] == 90.0 and length > minlinelength):
vline.append(list(l))
#cv.line(newblank_image, (l[0], l[1]), (l[2], l[3]), (0,0,255), 1)
#cv.circle(newblank_image, (l[0],l[1]), 1, (0, 255, 255), 1)
if(deg[0] == 180.0 and length > minlinelength):
hline.append(list(l))
#cv.line(newblank_image, (l[0], l[1]), (l[2], l[3]), (0,0,255), 1)
#cv.circle(newblank_image, (l[0],l[1]), 1, (0, 255, 255), 1)
hline = [list(t) for t in set(tuple(element) for element in hline)]
vline = [list(t) for t in set(tuple(element) for element in vline)]
drawAllLines(blank_image, hline, 2)
drawAllLines(blank_image, vline, 2)
cv.imwrite('op1-uncleaned.png',blank_image)
#print("Uncleaned Hline: ", len(hline))
#print("Uncleaned Vline: ", len(vline))
newblank_image = np.zeros((img_rgb.shape[0], img_rgb.shape[1], 3), dtype=np.uint8)
hline = clean(hline, "h")
vline = clean(vline, "v")
drawAllLines(newblank_image, hline, 2)
drawAllLines(newblank_image, vline, 2)
cv.imwrite('op1-cleaned.png',newblank_image)
#print("Cleaned Hline: ", len(hline), hline)
#print("Cleaned Vline: ", len(vline), vline)
'''def findPinVline(px, py):
ret = []
for v in vline:
if(px == v[0] and v[3]<=py<=v[1]):
ret = v
break
return ret'''
def findPinVline(px, py):
#tmpimg = np.zeros((img_rgb.shape[0], img_rgb.shape[1], 3), dtype=np.uint8)
#print("vline:", vline)
for v in vline:
'''cv.line(tmpimg, (v[0], v[1]), (v[2], v[3]), (255,0,255), 1)
cv.namedWindow("vline", cv.WINDOW_NORMAL)
cv.imshow("vline", tmpimg)
cv.waitKey()'''
if(px == v[0] and v[3]<=py<=v[1]):
return v
def findPinHline(px, py):
#tmpimg = np.zeros((img_rgb.shape[0], img_rgb.shape[1], 3), dtype=np.uint8)
#print("vline:", vline)
for h in hline:
'''cv.line(tmpimg, (v[0], v[1]), (v[2], v[3]), (255,0,255), 1)
cv.namedWindow("vline", cv.WINDOW_NORMAL)
cv.imshow("vline", tmpimg)
cv.waitKey()'''
if(py == h[1] and h[0]<=px<=h[2]):
return h
def updatelines(line, remove, add):
for i in remove:
line = [x for x in line if x != i]
for i in add:
line.append(i)
return line
#tmpimg = np.zeros((img_rgb.shape[0], img_rgb.shape[1], 3), dtype=np.uint8)
'''for l in hline1:
cv.line(tmpimg, (l[0], l[1]), (l[2], l[3]), (0,0,255), 1)
cv.circle(tmpimg, (l[0],l[1]), 1, (0, 255, 255), 10)
cv.circle(tmpimg, (l[2],l[3]), 1, (0, 255, 255), 10)
cv.namedWindow("Source", cv.WINDOW_NORMAL)
cv.imshow("Source", tmpimg)
cv.waitKey()
'''
newblank_image_gray = cv.cvtColor(newblank_image, cv.COLOR_BGR2GRAY)
'''cv.namedWindow("Source1", cv.WINDOW_NORMAL)
cv.imshow("Source1", newblank_image)
cv.waitKey()'''
tmpimg = np.zeros((img_rgb.shape[0], img_rgb.shape[1], 3), dtype=np.uint8)
#Horizontal lines left
newvline = []
removevline = []
newhline = []
removehline = []
for h in hline:
#print("\n\n\nconsidering: ", h)
#flag = False
boundary = max(0, h[0]-snaplength)
for i in range(h[0]-1, boundary, -1):
if(newblank_image_gray[h[1]][i] != 0):
#flag = True
px = i
py = h[1]
'''cv.circle(tmpimg, (px,py), 1, (0, 0, 255), 100)
cv.namedWindow("Source", cv.WINDOW_NORMAL)
cv.imshow("Source", tmpimg)
cv.waitKey()'''
tmpline = findPinVline(px, py)
if(tmpline != None):
removehline.append(h)
newhline.append([px,py,h[2],h[3]])
removevline.append(tmpline)
line1 = [tmpline[0], tmpline[1], px, py]
line2 = [px, py, tmpline[2], tmpline[3]]
for l in [line1, line2]:
length = math.sqrt((l[2]-l[0])**2 + (l[3]-l[1])**2)
if(length > protrusion):
newvline.append(l)
'''print("found: ", tmpline)
print("px,py: ", px,py)
print("newvline:", newvline)
print("removevline: ", removevline )'''
'''tmpimg = np.zeros((img_rgb.shape[0], img_rgb.shape[1], 3), dtype=np.uint8)
cv.line(tmpimg, (h[0], h[1]), (h[2], h[3]), (0,0,255), 3)
cv.line(tmpimg, (line1[0], line1[1]), (line1[2], line1[3]), (0,255,0), 3)
cv.line(tmpimg, (line2[0], line2[1]), (line2[2], line2[3]), (0,255,0), 3)
plt.figure(figsize=(10,10)).add_axes([0, 0, 1, 1])
plt.imshow(tmpimg, cmap='gray')
plt.show()'''
break
#if(flag == False):
# newhline.append(h)
'''print("remove/add info")
print(vline, "--\n", removevline, "--\n", newvline, )
print(removevline, newvline)
#print(removehline, newhline)
print("---")'''
#print("vline: ", vline)
#print("removevline: ", removevline)
#print("newvline before update: ", newvline)
vline = updatelines(vline, removevline, newvline)
hline = updatelines(hline, removehline, newhline)
#print("Vline: ", len(vline), vline)
#Horizontal lines right
newvline = []
removevline = []
newhline = []
removehline = []
for h in hline:
#print("considering: ", h)
#tmpimg = np.zeros((img_rgb.shape[0], img_rgb.shape[1], 3), dtype=np.uint8)
#cv.line(tmpimg, (h[0], h[1]), (h[2], h[3]), (0,255,0), 10)
#flag = False
boundary = min(newblank_image_gray.shape[1], h[2]+snaplength)
for i in range(h[2]+1, boundary):
if(newblank_image_gray[h[1]][i] != 0):
#flag = True
px = i
py = h[1]
#cv.circle(tmpimg, (px,py), 1, (0, 0, 255), 10)
#cv.namedWindow("point", cv.WINDOW_NORMAL)
#cv.imshow("point", tmpimg)
#cv.waitKey()
tmpline = findPinVline(px, py)
if(tmpline != None):
removehline.append(h)
newhline.append([h[0],h[1],px,py])
removevline.append(tmpline)
#print("found: ", tmpline)
#print("newhline:", newhline)
line1 = [tmpline[0], tmpline[1], px, py]
line2 = [px, py, tmpline[2], tmpline[3]]
for l in [line1, line2]:
length = math.sqrt((l[2]-l[0])**2 + (l[3]-l[1])**2)
if(length > protrusion):
newvline.append(l)
break
#if(flag == False):
# newhline.append(h)
#print("remove/add info")
#print(vline, "--\n", removevline, "--\n", newvline, )
#print(removevline, newvline)
#print(removehline, newhline)
#print("---")
vline = updatelines(vline, removevline, newvline)
hline = updatelines(hline, removehline, newhline)
#print("Hline: ", len(hline))
#print("Vline: ", len(vline))
#Vertical lines down
newvline = []
removevline = []
newhline = []
removehline = []
for v in vline:
#print("considering: ", v)
#tmpimg = np.zeros((img_rgb.shape[0], img_rgb.shape[1], 3), dtype=np.uint8)
#cv.line(tmpimg, (v[0], v[1]), (v[2], v[3]), (0,255,0), 1)
#flag = False
boundary = min(newblank_image_gray.shape[0], v[1]+snaplength)
for i in range(v[1]+1, boundary):
if(newblank_image_gray[i][v[0]] != 0):
#flag = True
px = v[0]
py = i
#cv.line(tmpimg, (v[0]-20, v[1]), (v[0]+20, v[1]), (0,255,0), 1)
#cv.line(tmpimg, (px-20, py), (px+20,py), (0,0,255), 1)
#cv.circle(tmpimg, (px,py), 1, (0, 0, 255), 2)
#cv.namedWindow("point", cv.WINDOW_NORMAL)
#cv.imshow("point", tmpimg)
#cv.waitKey()
#cv.imwrite('op-temp.png',tmpimg)
tmpline = findPinHline(px, py)
if(tmpline != None):
removevline.append(v)
newvline.append([px,py,v[2],v[3]])
removehline.append(tmpline)
#print("found: ", tmpline)
line1 = [tmpline[0], tmpline[1], px, py]
line2 = [px, py, tmpline[2], tmpline[3]]
for l in [line1, line2]:
length = math.sqrt((l[2]-l[0])**2 + (l[3]-l[1])**2)
if(length > protrusion):
newhline.append(l)
break
vline = updatelines(vline, removevline, newvline)
hline = updatelines(hline, removehline, newhline)
#print("Hline: ", len(hline))
#print("Vline: ", len(vline), vline)
#Vertical lines up
newvline = []
removevline = []
newhline = []
removehline = []
for v in vline:
#print("\n\nconsidering: ", v)
#tmpimg = np.zeros((img_rgb.shape[0], img_rgb.shape[1], 3), dtype=np.uint8)
#cv.line(tmpimg, (v[0], v[1]), (v[2], v[3]), (0,255,0), 1)
#flag = False
boundary = max(0, v[3]-snaplength)
for i in range(v[3]-1, boundary, -1):
if(newblank_image_gray[i][v[0]] != 0):
#flag = True
px = v[0]
py = i
#cv.line(tmpimg, (v[0]-20, v[1]), (v[0]+20, v[1]), (0,255,0), 1)
#cv.line(tmpimg, (px-20, py), (px+20,py), (0,0,255), 1)
#cv.circle(tmpimg, (px,py), 1, (0, 0, 255), 2)
#cv.namedWindow("point", cv.WINDOW_NORMAL)
#cv.imshow("point", tmpimg)
#cv.waitKey()
#cv.imwrite('op-temp.png',tmpimg)
tmpline = findPinHline(px, py)
if(tmpline != None):
removevline.append(v)
newvline.append([v[0],v[1], px, py])
removehline.append(tmpline)
#print("found: ", tmpline)
#print("removevline: ", removevline)
#print("newvline: ", newvline)
line1 = [tmpline[0], tmpline[1], px, py]
line2 = [px, py, tmpline[2], tmpline[3]]
for l in [line1, line2]:
length = math.sqrt((l[2]-l[0])**2 + (l[3]-l[1])**2)
if(length > protrusion):
newhline.append(l)
break
vline = updatelines(vline, removevline, newvline)
hline = updatelines(hline, removehline, newhline)
#print("Hline: ", len(hline))
#print("Vline: ", len(vline), vline)
'''def drawAllLines1():
for l in newvline:
cv.line(tmpimg, (l[0], l[1]), (l[2], l[3]), (0,0,255), 1)
#cv.circle(tmpimg, (l[0],l[1]), 1, (0, 255, 255), 10)
#cv.circle(tmpimg, (l[2],l[3]), 1, (0, 255, 255), 10)
for l in newhline:
cv.line(tmpimg, (l[0], l[1]), (l[2], l[3]), (0,0,255), 1)
#cv.circle(tmpimg, (l[0],l[1]), 1, (0, 255, 255), 10)
#cv.circle(tmpimg, (l[2],l[3]), 1, (0, 255, 255), 10)
'''
#print(hline)
#print(newhline)
#drawAllLines1()
#Border
'''for h in hline:
if(h[0] <= snapToBorder):
h[0] = 0
if(img_rgb.shape[1] - h[2] <= snapToBorder):
h[2] = img_rgb.shape[1]'''
'''for v in vline:
if(img_rgb.shape[0] - v[1] <= snapToBorder):
v[1] = img_rgb.shape[0]
if(v[3] <= snapToBorder):
v[3] = 0'''
'''print("Hline: ", len(hline))
print("Vline: ", len(vline))
print(newblank_image_gray.shape)
print(type(newblank_image_gray))
c = 0
for i in vline:
cv.putText(tmpimg, str(c), (i[0],i[1]), cv2.FONT_HERSHEY_PLAIN, 1, (255,255,0), 1, cv2.LINE_AA)
c += 1
cv.imwrite('op2-text.png',tmpimg)'''
for h in hline:
tmp = [True for i in newblank_image_gray[h[1], 0:h[0]-2] if i != 0]
if(h[0] <= snapToBorder and len(tmp) == 0):
h[0] = 0
#print("Left: Nothing between")
cols = newblank_image_gray.shape[1]
tmp = [True for i in newblank_image_gray[h[1], h[2]+2:cols] if i != 0]
if(newblank_image_gray.shape[1] - h[2] <= snapToBorder and len(tmp) == 0):
h[2] = newblank_image_gray.shape[1]-1
#print("Right: Nothing between")
for v in vline:
tmp = [True for i in newblank_image_gray[0:v[3], v[0]-2] if i!= 0]
if(v[3] <= snapToBorder and len(tmp) == 0):
v[3] = 0
#print("Up: Nothing between")
rows = newblank_image_gray.shape[0]
tmp = [True for i in newblank_image_gray[v[1]:rows, v[0]+2] if i!= 0]
if(newblank_image_gray.shape[0] - v[1] <= snapToBorder and len(tmp) == 0):
v[1] = newblank_image_gray.shape[0]-1
#print("Down: Nothing between")
tmpimg = np.zeros((img_rgb.shape[0], img_rgb.shape[1], 3), dtype=np.uint8)
drawAllLines(tmpimg, hline, 3)
drawAllLines(tmpimg, vline, 3)
row = tmpimg.shape[0]
col = tmpimg.shape[1]
tmpimg[0:3,:] = (0,0,255)
tmpimg[row-3:, :] = (0,0,255)
tmpimg[:, 0:3] = (0,0,255)
tmpimg[:, col-3:] = (0,0,255)
cv.imwrite('op2.png',tmpimg)
tmpimgGrey = cv.cvtColor(tmpimg, cv.COLOR_BGR2GRAY)
ret,thresh = cv.threshold(tmpimgGrey,20,255,cv.THRESH_BINARY_INV)
nlabels, labels, stats, centroids = cv.connectedComponentsWithStats(thresh, connectivity=8)
row, col = stats.shape
for i in range(1,row):
if(40000 <= stats[i, 4] <img_rgb.shape[0]*img_rgb.shape[1]): # and (stats[i, 2]/stats[i,3] <= 3 and stats[i, 3]/stats[i,2] <= 3 )):
x = stats[i, 0]
y = stats[i, 1]
w = stats[i, 2]
h = stats[i, 3]
import random
r = random.randint(0,255)
g = random.randint(0,255)
b = random.randint(0,255)
cv.rectangle(img_rgb, (x,y), (x+w, y+h), (b,g,r), -1)
#cv.putText(img_rgb, str(c), (x+10,y+10), cv2.FONT_HERSHEY_PLAIN, 1, (0,0,255), 3, cv2.LINE_AA)
'''plt.figure(figsize=(5,5)).add_axes([0, 0, 1, 1])
plt.imshow(img_rgb, cmap='gray')
plt.show() '''
cv.imwrite('op2-cc.png',img_rgb)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment