Skip to content

Instantly share code, notes, and snippets.

@leftrk
Created October 4, 2018 06:58
Show Gist options
  • Select an option

  • Save leftrk/94d63087a525ec9d47e6e691742429a6 to your computer and use it in GitHub Desktop.

Select an option

Save leftrk/94d63087a525ec9d47e6e691742429a6 to your computer and use it in GitHub Desktop.
capture
import cv2
from matplotlib import pyplot as plt
import numpy as np
from sklearn.cluster import *
from sklearn import mixture
from sklearn import metrics
from scipy.stats import mode
class ImgProcessor:
def __init__(self, fname=None):
self.img = cv2.imread(fname)
self.small_size = 256
self.small_img = self.resize(self.small_size)
#print(self.img.shape)
self.fname = fname
self.log_count = 0
self.grayimg = self.gray(self.small_img)
self.log(self.grayimg)
#self.grayimg = self.fillGap2(img=self.grayimg)
self.log(self.cluster())
#self.log(self.grayimg)
#self.log(self.grayimg)
#self.log(self.getMainImage())
# self.sharpen(self.grayimg)
# self.log()
#
# self.gradient = cv2.Laplacian(self.img, cv2.CV_8U)
# self.log(self.gradient)
#
#
# self.edges = self.findEdges(img=self.grayimg)
# self.log(self.edges)
#
# self.gradient = cv2.Laplacian(self.edges, cv2.CV_8U)
# self.log(self.gradient)
#
# self.edges = self.findEdges(img=self.gradient)
# self.log(self.edges)
# self.sobelx = cv2.Sobel(self.edges, cv2.CV_64F, 2, 0, ksize=5)
# self.sobely = cv2.Sobel(self.edges, cv2.CV_64F, 0, 2, ksize=5)
# self.contours = self.findContours(img=self.edges)
# self.lines = cv2.HoughLines(self.edges,1,np.pi/180,100, 300, 50)
# self.lines = cv2.HoughLinesP(self.edges, 1, np.pi / 180, 100, 500, 100)
#
# self.log(self.drawContours())
#
# self.log(self.sobelx)
# self.log(self.sobely)
# self.log(self.drawLines())
# self.log(self.segmentation(self.grayimg))
def cluster(self):
mask = self.grayimg>0
pad = int(min(self.small_img.shape[:2])/10)
mask[0:pad,:] = False
mask[-pad:,:] = False
mask[:,0:pad] = False
mask[:,-pad:] = False
ids = np.vstack(np.where(mask>0)).T
y = DBSCAN(eps=3, min_samples=min(self.small_img.shape)/3, metric='cityblock').fit(ids).labels_
unique, counts = np.unique(y, return_counts=True)
index = np.argmax(counts)
id = unique[index]
cids = ids[y==id,:]
plt.plot(ids[:, 1], -ids[:, 0], 'ro')
plt.plot(cids[:,1],-cids[:,0],'yo')
unique, counts = np.unique(cids[:,0], return_counts=True)
hids = unique[counts>= np.median(counts)*0.3]
unique, counts = np.unique(cids[:, 1], return_counts=True)
wids = unique[counts >= np.median(counts)*0.3]
#hids,wids = cids[:,0],cids[:,1]
#plt.plot(wids, -hids, 'bo')
plt.show()
l,r,b,t=min(wids),max(wids),min(hids),max(hids)
factor = np.max(self.img.shape) / self.small_size
l, r, b, t = tuple((np.array([l, r, b, t]) * factor).astype('int32'))
img = self.img.copy()
img[:, :, :] = 0
img[b:t, l:r, :] = self.img[b:t, l:r, :]
return img
def getMainImage(self):
small, l, r, b, t = self.scanRect2()
factor = np.ceil(np.max(self.img.shape) / self.small_size)
l, r, b, t = tuple((np.array([l, r, b, t]) * factor).astype('int32'))
img = self.img.copy()
img[:,:,:]=0
img[b:t,l:r,:] = self.img[b:t,l:r,:]
return img
def resize(self, n, img=None):
if img is None:
img = self.img
x,y,z = img.shape
if x>y:
nx = n
ny = int(float(n)/x*y)
else:
ny = n
nx = int(float(n) / y * x)
print(nx,ny)
img = cv2.resize(img, (ny, nx),(0,0))
return img
def sharpen(self, img=None):
if img is None:
img = self.img
p = cv2.GaussianBlur(img, (0, 0), 3)
self.img = cv2.addWeighted(img, 1.5, p, -0.5, 0, img)
def drawLines(self, img=None):
if img is None:
img = self.img.copy()
for x1, y1, x2, y2 in self.lines[0]:
cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
return img
def log(self, img=None, tag=None):
fname = tag
if tag is None:
fname = self.fname + '-' + str(self.log_count) + '.jpg'
self.log_count += 1
else:
fname = self.fname + '-' + tag + '.jpg'
if img is None:
img = self.img
cv2.imwrite(fname, img)
def findEdges(self, thresh1=50, thresh2=400, img=None):
if img is None:
img = self.img
return cv2.Canny(img, thresh1, thresh2, apertureSize=3)
def gray(self, img=None):
if img is None:
img = self.img
#mask = self.small_img.mean(axis=2) < 30
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
#mask = self.small_img.mean(axis=2) < 30
#mask = imgray[:,:,2]<20
imgray = imgray[:,:,1]
#imgray[mask]=0
#imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#imgray = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# imgray[:,:, 0]=0
# imgray[:, :, 1] = 0
#imgray[:, :, 2] = 0
#imgray = img.min(axis=2)
#thresh=imgray
ret2, thresh = cv2.threshold(imgray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# thresh = cv2.adaptiveThreshold(imgray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
# cv2.THRESH_BINARY+cv2.THRESH_OTSU,7,2)
#ret, thresh = cv2.threshold(imgray[:, :, 1], 80, 255, cv2.THRESH_BINARY)
return thresh
def findContours(self, img=None, len_thresh=500):
if img is None:
img = self.grayimg
image, contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cons = []
for c in contours:
if cv2.arcLength(c, False) > len_thresh:
# print(cv2.arcLength(c, True))
cons.append(c)
return cons
def drawContours(self, contours=None, img=None):
if img is None:
img = self.img.copy()
if contours is None:
contours = self.contours
return cv2.drawContours(img, contours, -1, (0, 0, 255), 1)
def poly(self, contour):
epsilon = 0.1 * cv2.arcLength(contour, True)
p = cv2.approxPolyDP(contour, epsilon, True)
return p
def drawPoly(self, poly, img=None):
img = img if img is not None else self.img
dimg = img.copy()
# l = len(poly)
# s, e = 0, 1
# for i in range(l):
# print(poly)
# showimg = cv2.line(showimg, poly[(s+i)%l][0][0], poly[(e+i)%l][0][1], (255,0,0), 1)
dimg = cv2.drawContours(dimg, poly, -1, (255, 0, 0), 1)
return dimg
def fillGap(self, step=1, img=None, iter=5):
if img is None:
img = self.img.copy()
m = int(step / 2)
kernel = np.zeros((4,step, step))
kernel[0,:m+1, :m + 1] = 1
kernel[1,:m+1, m:] = 1
kernel[2,m:, :m + 1] = 1
kernel[3,m:, m:] = 1
w, h, c = self.img.shape
for ll in range(iter):
for i in range(m, w - m, 2):
for j in range(m, h - m, 2):
count = 0
temp = np.tile(img[i - m:i + m + 1, j - m:j + m + 1],(4,1,1))
score = sum(np.sum(temp * kernel>0,axis=(1,2))>= (m+1) ** 2*0.8)
if score>3:
img[i - m:i + m + 1, j - m:j + m + 1] = 255
elif score<2:
img[m,m] = 0
return img
def fillGap2(self, img=None, iter=100):
if img is None:
img = self.small_img
h, w = img.shape
for k in range(iter):
mask = img > 0
stop = True
for i in range(1,h-1):
for j in range(1,w-1):
if mask[i,j]==False and np.sum(mask[i-1:i+2,j-1:j+2])>=5:
img[i,j]=255
stop = False
if stop:
break
return img
def findRect(self):
h, w, c = self.img.shape
mask = self.grayimg>0
wsum = np.sum(mask, axis=0)>h*0.2
hsum = np.sum(mask, axis=1)>w*0.3
img = self.grayimg.copy()
img = img * np.tile(wsum,[h,1]) * np.tile(hsum,[w,1]).T
return img
def scanRect(self):
h, w, c = self.small_img.shape
img = self.grayimg.copy()
mask = img > 0
mx,l,r,b,t = 0,0,0,0,0
for i in range(1,h-5):
for j in range(1,w-5):
for k in range(i+5,h):
for m in range(j+5,w):
#sq = (k-i)+(m-j)
#new = (np.sum(np.sum(mask[i:k, j:m],axis=0)>(k-i)*0.6)/(k-i)**0.5 + np.sum(np.sum(mask[i:k, j:m],axis=1)>(m-j)*0.6)/(m-j)**0.5)
sq = (k - i) * (m - j)
new = float(np.sum(np.sum(mask[i:k,j:m])))/sq**0.5
if new > mx:
mx = new
l,r,b,t = j,m,i,k
img[:,:]=0
img[b:t, l:r] = 255
return img, l,r,b,t
def segmentation(self, img=None):
img = img if img is not None else self.img
# Finding sure foreground area
dist_transform = cv2.distanceTransform(img, cv2.DIST_L2, 5)
ret, sure_fg = cv2.threshold(dist_transform, 0.05 * dist_transform.max(), 255, 0)
return sure_fg
if __name__ == '__main__':
for i in range(1, 7):
img = ImgProcessor('pic/%d.jpg' % i)
# img.log()
#
#
#
#
# edges = cv2.Canny(img,100,200)
# grayimg = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
#
# cv2.imwrite('pic/1-1.jpg',showimg)
#
# image, contours, hierarchy = cv2.findContours(edges,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# showimg = cv2.drawContours(grayimg, contours, -1, (0,255,0), 1)
#
# recs = []
# for c in contours:
# epsilon = 0.1 * cv2.arcLength(c, True)
# poly = cv2.approxPolyDP(c, epsilon, True)
#
# if len(poly) == 4:
# recs.append(poly)
#
#
# for r in recs:
# l = len(r)
# s , e = 0, 1
# for i in range(len(r)):
# #print(poly)
# #showimg = cv2.line(showimg, poly[(s+i)%l][0][0], poly[(e+i)%l][0][1], (255,0,0), 1)
# showimg = cv2.drawContours(showimg, r, -1, (255, 0, 0), 1)
#
# cv2.imwrite('pic/1-p.jpg',showimg)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment