Created
October 4, 2018 06:58
-
-
Save leftrk/94d63087a525ec9d47e6e691742429a6 to your computer and use it in GitHub Desktop.
capture
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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