diff --git a/exp/histogram.py b/exp/histogram.py --- a/exp/histogram.py +++ b/exp/histogram.py @@ -1,5 +1,6 @@ import os import sys +import random import cv2 as cv import numpy as np @@ -54,7 +55,7 @@ def quantize(img): colors=np.array([[0,0,0],[255,255,255],[193,165,116]],np.float) print(colors) (centers,distortion)=scipy.cluster.vq.kmeans(arr,colors) - print(centers) + print("k-means centers:",centers) return centers @@ -89,60 +90,133 @@ def ellipse(a,b): img.save("/tmp/ellipse.png") return np.array(img,dtype=np.uint8) +def detectStones(img): + (bh,bw)=img.shape + sw=bw//19 + sh=bh//19 + print(img.shape,(sw,sh)) + ell=ellipse(sw,sh)*255 + # print(ell) + hitMap=np.zeros_like(img,dtype=np.uint8) + for i in range(sw,bw): + for j in range(sh,bh): + region=stones[j-sh:j, i-sw:i] + hitMap[j,i]=255*score(region,ell) + show(hitMap) + return hitMap -filepath=sys.argv[1] -annotations=DataFile(sys.argv[2]) -filename=os.path.basename(filepath) -(x1,y1,x2,y2)=computeBoundingBox(annotations[filename][0]) -(w,h)=(x2-x1,y2-y1) -img=cv.imread(filepath) -(x3,x4,y3,y4)=(x1+w//4,x1+3*w//4,y1+h//4,y1+3*h//4) -print(x3,x4,y3,y4) -rect=img[y3:y4,x3:x4,:] -centers=quantize(rect) +def detectGrid(img): + (bh,bw)=img.shape + + gridMap=np.zeros_like(img,dtype=np.uint8) + for i in range(5,bw): + for j in range(5,bh): + region=img[j-5:j, i-5:i] + gridMap[j,i]=255*maxOp55(region) + show(gridMap) -for x in range(x1,x2): - for y in range(y1,y2): - pix=img[y,x] - img[y,x]=computeClosest(pix,centers) +def locateStone(img): + (bh,bw)=img.shape + sw=bw//19 + sh=bh//19 + print(img.shape,(sw,sh)) + ell=ellipse(sw,sh)*255 + # print(ell) + + y=random.randrange(sh,bh) + x=random.randrange(sw,bw) + region=stones[y-sh:y, x-sw:x] + sc=score(region,ell) + print(sc) + show(region) + return sc -rect=img[y1:y2,x1:x2] -maskB=cv.inRange(rect,np.array([0,0,0]),np.array([80,80,80])) -maskB=cv.erode(maskB,np.ones((3,3),np.uint8)) -# maskB=cv.erode(maskB,np.ones((3,3),np.uint8)) -# maskB=cv.erode(maskB,np.ones((3,3),np.uint8)) -maskW=cv.inRange(rect,np.array([160,160,160]),np.array([256,256,256])) -maskW=cv.erode(maskW,np.ones((3,3),np.uint8)) -# maskW=cv.erode(maskW,np.ones((3,3),np.uint8)) -# maskW=cv.erode(maskW,np.ones((3,3),np.uint8)) +def locateLocalMaximum(img): + (bh,bw)=img.shape + x=random.randrange(0,bw) + y=random.randrange(0,bh) + val=img[y,x] + img_=cv.cvtColor(img,cv.COLOR_GRAY2BGR) + while True: + for (dx,dy) in [(0,1),(1,0),(0,-1),(-1,0),(1,1),(-1,1),(1,-1),(-1,-1)]: + x_=x+dx + y_=y+dy + val_=img[y_,x_] if 0<=x_val: + x=x_ + y=y_ + val=val_ + img_.itemset((y,x,0),255) + continue + break + print(x,y,val) + img_.itemset((y,x,2),255) + show(img_) + return (x,y,val) -show(img,filename) -show(maskB,filename) -show(maskW,filename) -stones=cv.bitwise_or(maskB,maskW) -# houghLines(stones) + +if __name__=="__main__": + filepath=sys.argv[1] + annotations=DataFile(sys.argv[2]) + filename=os.path.basename(filepath) + (x1,y1,x2,y2)=computeBoundingBox(annotations[filename][0]) + (w,h)=(x2-x1,y2-y1) + img=cv.imread(filepath) + (x3,x4,y3,y4)=(x1+w//4,x1+3*w//4,y1+h//4,y1+3*h//4) + print("x3,x4,y3,y4:",x3,x4,y3,y4) + rect=img[y3:y4,x3:x4,:] + centers=quantize(rect) + print("x1,x2,y1,y2:",(x1,x2,y1,y2)) + data=np.reshape(img[y1:y2,x1:x2,:],(-1,3)) + print("data.shape:",data.shape) + (keys,dists)=scipy.cluster.vq.vq(data,centers) + print("keys.shape:",keys.shape) + pixels=np.array([centers[k] for k in keys],dtype=np.uint8).reshape((y2-y1,x2-x1,3)) + img[y1:y2,x1:x2,:]=pixels + print("image quantized") + + rect=img[y1:y2,x1:x2] + maskB=cv.inRange(rect,np.array([0,0,0]),np.array([80,80,80])) + maskB=cv.erode(maskB,np.ones((3,3),np.uint8),iterations=2) + maskW=cv.inRange(rect,np.array([160,160,160]),np.array([256,256,256])) + maskW=cv.erode(maskW,np.ones((3,3),np.uint8),iterations=2) -(bh,bw)=stones.shape -sw=bw//19 -sh=bh//19 -print(stones.shape,(sw,sh)) -ell=ellipse(sw,sh)*255 -# print(ell) -hitMap=np.zeros_like(stones,dtype=np.uint8) -for i in range(sw,bw): - for j in range(sh,bh): - region=stones[j-sh:j, i-sw:i] - hitMap[j,i]=255*score(region,ell) -show(hitMap) + show(img,filename) + show(maskB,filename) + show(maskW,filename) + stones=cv.bitwise_or(maskB,maskW) + # houghLines(stones) + show(stones) -gridMap=np.zeros_like(hitMap,dtype=np.uint8) -for i in range(5,bw): - for j in range(5,bh): - region=hitMap[j-5:j, i-5:i] - gridMap[j,i]=255*maxOp55(region) -show(gridMap) + (contours,hierarchy)=cv.findContours(stones,cv.RETR_LIST,cv.CHAIN_APPROX_SIMPLE) + contourImg=cv.drawContours(cv.cvtColor(stones,cv.COLOR_GRAY2BGR), contours, -1, (0,255,0), 1) + for (i,c) in enumerate(contours): + print(i) + moments=cv.moments(c) + center=(moments["m10"]/(moments["m00"] or 1), moments["m01"]/(moments["m00"] or 1)) + print("center:", center) + cv.circle(contourImg,tuple(map(int,center)),3,(255,255,0)) + area=cv.contourArea(c) + print("area:",area) + (x,y,w,h)=cv.boundingRect(c) + print("bounding box:",(x,y,w,h)) + print("coverage1:",area/(w*h or 1)) + hull=cv.convexHull(c) + print("coverage2:",area/(cv.contourArea(hull) or 1)) + print() + show(contourImg) -houghLines(gridMap) + # for i in range(10): + # locateStone(stones) + # distMap=cv.distanceTransform(stones,cv.DIST_L2,5) + # print("dist map:") + # show(distMap) + # print("hit map:") + # hitMap=detectStones(stones) + # for i in range(10): + # locateLocalMaximum(hitMap) +# dlib.find_peaks + # ministones=cv.resize(stones,None,fx=0.25,fy=0.25,interpolation=cv.INTER_AREA) # dft = cv.dft(np.float32(ministones),flags = cv.DFT_COMPLEX_OUTPUT) # dft_shift = np.fft.fftshift(dft)