import time
MF=6


def BWRAT(img):
    Lx=img.shape[1]; Ly=img.shape[0]; A1=Lx*Ly
    if(A1<100): return 0,0,0
    if(A1>50000): print('A1=',A1,Lx,Ly); return 0,0,0
    Lx2=int(Lx/4); Ly2=int(Ly/4); A=Lx2*Ly2
    im1=np.copy(img)
    im2=cv2.resize(im1,(Lx2,Ly2))
    gray=cv2.cvtColor(im2, cv2.COLOR_BGR2GRAY)
    ret,bina=cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)     
    NWT=0; NB=0;
    for x in range(Lx2):
        for y in range(Ly2):
            if(bina[y,x]<40): NB+=1
            if(gray[y,x]>150): NWT+=1
    rat=round(NB/A,3); ratW=round(NWT/A,3)
    if(0.1<rat<0.9): KBW=1
    else: KBW=0
    if(ratW<0.1): KBW=0; 
    return KBW,ratW,rat


def HLA(hsv):
    Lx=hsv.shape[1]; Ly=hsv.shape[0]; hv=[]; N10=int(Lx/10)*1
    BW=[]
    for j in range(Lx):
        for i in range(Ly):
            if(hsv[i,j,2]>120 and hsv[i,j,1]>100): continue
            BW.append(int(hsv[i,j,2]))
    shv=sorted(BW)
    L1=int(len(shv)/10); H1=L1*9
    if(L1<2 or len(shv)<2): return 0,0
    avL=int(np.average(shv[0:L1]))
    avH=int(np.average(shv[H1:len(shv)]))
    return avL,avH



def highlow(hsv,Y):
    rH=0.4; rL=0.1
    Lx=hsv.shape[1]; Ly=hsv.shape[0]; hv=[]; N10=int(Lx/10)*1
    for j in range(N10,N10*9):
        hv.append(int(hsv[Y,j,2]))
    shv=sorted(hv)
    NH=int(Lx*rH); NL=int(Lx*rL)
    H10=int(np.average(shv[-NH:-1]))
    L10=int(np.average(shv[0:NL]))
    return H10,L10


def high10(hsv,Y):
    Lx=hsv.shape[1]; Ly=hsv.shape[0]; hv=[]; N10=int(Lx/10)*1+1
    if(Lx<2 or Ly<2): return 250,10
    for j in range(int(Lx/4),int(3*Lx/4)):
        hv.append(int(hsv[Y,j,2]))
    if(len(hv)<N10*2): return 250,10
    if(len(hv[-N10:-1])<2): return 250,10
    shv=sorted(hv)
    H10=int(np.average(shv[-N10:-1]))
    L10=int(np.average(shv[0:N10]))
    return H10,L10



def CLR(img):
    Lx=img.shape[1]; Ly=img.shape[0]
    hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    NC=0; NCY=0; dy=int(Ly/10); dx=int(Lx/10); color=[]; 
    #cv2.waitKey(0)
    for Y in range(dy*3,dy*9,dy):
        NC=0; cc=[]
        for j in range(dx*2,dx*8):
            if(hsv[Y,j,2]>100 and hsv[Y,j,1]>120): 
                NC+=1; cc.append((Y,j,hsv[Y,j,:]))
        color.append((Y,NC))
        if(NC>(dx*2)): NCY+=1; 
    if(NCY>1): KCLR=0; 
    else: KCLR=1
    return KCLR


def SUBGR(img):
    F=4
    Lx=img.shape[1]; Ly=img.shape[0]; Yin1=0; Yin2=Ly
    imgrs=cv2.resize(img,(int(Lx/F),int(Ly/F)));
    im1=np.copy(imgrs)
    XA1,XB1,YA1,YB1=scHL(im1)
    XA=XA1*F; XB=XB1*F; YA=YA1*F; YB=YB1*F
    imgsub=img[YA:YB,XA:XB]
    return imgsub,XA,XB,YA,YB



def scHL(img):
    Lx=img.shape[1]; Ly=img.shape[0]; Yin1=0; Yin2=Ly; im1=np.copy(img)
    imgrs=np.copy(img); X1=0; X2=Lx; Y1=0; Y2=Ly
    hsvrs=cv2.cvtColor(imgrs,cv2.COLOR_BGR2HSV)
    Lx2=hsvrs.shape[1]; Ly2=hsvrs.shape[0]
    NY=40; YS=[int(Ly2/NY*i) for i in range(NY)]; NHL=0; YHL=[]
    for j in range(NY):
        Y=YS[j]; a=hsvrs[Y,:,2]; sa=np.sort(a); LC=int(len(sa)/4)
        L10=int(np.average(sa[0:LC])); H10=int(np.average(sa[-LC:-1])); 
        D10=H10-L10; D10C=int(D10*0.5)
        #print('scHL,j,Y=',j,Y,H10,L10,D10,D10C)
        if(D10<60): continue
        NSW=0; SW=[]
        for i in range(Lx2-1):
            DH=abs(int(hsvrs[Y,i,2])-int(hsvrs[Y,i+1,2]))
            if(DH>D10C): NSW+=1; SW.append(i)
        if(NSW>10):
            NHL+=1
            cv2.line(imgrs,(0,Y),(Lx2,Y),(255,0,0),2)
            cv2.line(im1,(0,Y),(Lx,Y),(255,0,0),1)
            YHL.append(Y)
    if(NHL>0): 
        KHL=1; 
        if(NHL==1): 
            Y1=int(YHL[0]-YS[1]*3); Y2=Y1+int(2*YS[1]*3)
        else: Y1=int(YHL[0]-YS[1]*3); Y2=int(YHL[NHL-1]+2*YS[1]*3)
    else: KHL=0; Y1=YS[0]; Y2=YS[-1]
    if(Y2-Y1<10): return X1,X2,Y1,Y2
    im2=img[Y1:Y2,:]
    rtwsc=0.8; X1,X2,imx=borderVL(rtwsc,im2)
    im3=im2[:,X1:X2]
    return X1,X2,Y1,Y2






def DBKWT(img):
    Lx=img.shape[1]; Ly=img.shape[0]
    Lx2=int(Lx/10); Ly2=int(Ly/10); RX=40; RY=int(Ly/Lx*RX)
    im1=np.copy(img)
    hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    if(Lx>=RX):
        imgrs=cv2.resize(img,(RX,RY))
    else:
        imgrs=np.copy(img)
    hsvrs=cv2.cvtColor(imgrs,cv2.COLOR_BGR2HSV)
    a=hsvrs[:,:,2]; aa=a.ravel(); sa=np.sort(aa);L10=int(len(sa)/10)
    L10=int(np.average(sa[0:L10])); H10=int(np.average(sa[-L10:-1])); 
    D10=H10-L10
    avL,avH=HLA(hsvrs); Dav=avH-avL
    if(Dav<60 or L10>120 or H10<160):
        #print('fail_DB',L10,H10,Dav); 
        return 0,avH,avL,Dav
    else: return 1,avH,avL,Dav



def CKHL(img):
    Lx=img.shape[1]; Ly=img.shape[0]; Yin1=0; Yin2=Ly
    im1=np.copy(img); SX=1
    imgrs=np.copy(img)
    hsvrs=cv2.cvtColor(imgrs,cv2.COLOR_BGR2HSV)
    Lx2=hsvrs.shape[1]; Ly2=hsvrs.shape[0]
    NY=20; YS=[int(Ly2/NY*i) for i in range(NY)]; NHL=0; YHL=[]; SWS=[]
    if(Lx>80): NSWC=10
    else: NSWC=6
    for j in range(NY):
        Y=YS[j]
        a=hsvrs[Y,:,2]; sa=np.sort(a); LC=int(len(sa)/4)
        if(LC<3): continue
        L10=int(np.average(sa[0:LC])); H10=int(np.average(sa[-LC:-1])); 
        D10=H10-L10
        #if(L10>100 or H10<180): continue
        if(D10<60): SWS.append(0); continue
        DCX=int(D10*0.7)
        NSW=0; SW=[]
        for i in range(Lx2-1):
            if(abs(int(hsvrs[Y,i,2])-int(hsvrs[Y,i+1,2]))>DCX): 
                NSW+=1; SW.append(i)
        SWS.append(NSW)
        if(NSW>NSWC):
            NHL+=1
            cv2.line(imgrs,(0,Y),(Lx2,Y),(255,0,0),1)
            cv2.line(im1,(0,Y*SX),(Lx,Y*SX),(255,0,0),1)
            YHL.append(Y*SX)
    if(NHL>1): KHL=1; 
    else: KHL=0; 
    return KHL,NHL





def borderHL(img):
    Lx=img.shape[1]; Ly=img.shape[0]; Yin1=0; Yin2=Ly; 
    sx=int(Lx/4); sy=int(Ly/4)
    im1=np.copy(img)
    imgrs=cv2.resize(img,(sx,sy)); 
    hsvrs=cv2.cvtColor(imgrs,cv2.COLOR_BGR2HSV)
    hsv=cv2.cvtColor(im1,cv2.COLOR_BGR2HSV)
    avL,avH=HLA(hsvrs); WHITE=int(avH*0.6)
    YA1=0; YA2=Ly-1
    NY=80; YS=[int(Ly/NY*i) for i in range(NY)]; NHL=0; YHL=[]; Lxc=int(Lx*0.6)
    for j in range(NY):
        Y=YS[j]; NW=0
        for i in range(Lx):
            if(hsv[Y,i,2]>WHITE): NW+=1
        if(NW>Lxc): 
            NHL+=1; YHL.append((Y,NW))
            cv2.line(im1,(0,Y),(Lx,Y),(0,128,255),1)
    NHL=len(YHL)
    if(NHL<3): return YA1,YA2,im1
    YA1=YHL[0][0]; YA2=YHL[NHL-1][0]
    return YA1,YA2,im1


def borderVL(rtw,img):
    Lx=img.shape[1]; Ly=img.shape[0]; Yin1=0; Yin2=Ly; 
    XA1=0; XA2=Lx-1
    sx=int(Lx/4); sy=int(Ly/4)
    im1=np.copy(img)
    if(sx<4 or sy<4): return XA1,XA2,im1
    imgrs=cv2.resize(img,(sx,sy));
    hsvrs=cv2.cvtColor(imgrs,cv2.COLOR_BGR2HSV)
    hsv=cv2.cvtColor(im1,cv2.COLOR_BGR2HSV)
    avL,avH=HLA(hsvrs);
    WHITE=int(avH*rtw); #if too black, reduce rtw
    NX=80; XS=[int(Lx/NX*i) for i in range(NX)]; NVL=0; XVL=[]; Lyc=int(Ly*rtw)
    for j in range(NX):
        X=XS[j]; NW=0
        for i in range(Ly):
            if(hsv[i,X,2]>WHITE): NW+=1
        if(NW>Lyc):
            NVL+=1; XVL.append((X,NW))
            cv2.line(im1,(X,0),(X,Ly),(255,128,0),1)
    NVL=len(XVL)
    if(len(XVL)>1): XA1=XVL[0][0]; XA2=XVL[NVL-1][0]
    if(XA1>10): XA1-=10
    if(XA2<Lx-10): XA2+=10
    return XA1,XA2,im1




def censcan(img):
    Lx=img.shape[1]; Ly=img.shape[0]
    im1=np.copy(img)
    hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    hsvrs=np.copy(hsv)
    avL,avH=HLA(hsvrs)
    YC=int(Ly/2); NC=0; NBW=0; NWB=0; Y=YC; NW=0; NB=0
    H10,L10=high10(hsv,Y); D10=H10-L10; Dav=avH-avL
    DCX=int(D10*0.7)*1
    if(Lx>80): NSWC=10
    else: NSWC=6
    CLR=0
    for j in range(1,Lx-2):
        if(hsv[Y,j,2]>180 and hsv[Y,j,1]>150): CLR+=1; 
    if(CLR>Lx*0.2): return 0,0
    for j in range(1,Lx-2):
        D1=int(hsv[Y,j-1,2]); D2=int(hsv[Y,j,2])
        D3=int(hsv[Y,j+1,2]); D4=int(hsv[Y,j+2,2])
        DC1=D1+D2-D3-D4; DC2=D3+D4-D1-D2
        if(DC2>DCX): NBW+=1
        if(DC1>DCX): NWB+=1
        if(hsv[Y,j-1,2]<avL): NB+=1
        if(hsv[Y,j-1,2]>avH*0.7): NW+=1
    NSW=NBW+NWB
    if(NW>0): ratBW=round(NB/NW,3)
    else: ratBW=100
    if(ratBW>1.2): NSW=0
    if(NSW>NSWC): KC=1; 
    else: KC=0; 
    return KC,NSW





def TVS(img):
    Lx=img.shape[1]; Ly=img.shape[0]; Ly1=int(Ly/10)
    im1=np.copy(img)
    hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    YC=int(Ly/2); NC=0; NBW=0; NWB=0; cut=[]; bkdot=[]
    YB=[]; XS=[int(Lx/20)*i for i in range(20)]
    for j in range(20):
        x=XS[j]
        NSW=0; SW=[]
        for i in range(Ly1*2,Ly-Ly1*2):
            KW=1
            if(hsv[i,x,2]<120): 
                NSW+=1; 
                cv2.circle(im1,(x,i),1,(255,0,0),-1)
            if(NSW>10): KW=0; break
        if(KW==1): YB.append(i); #print(x,NSW,len(YB)) #,hsv[:,x,2]); 
    LYB=len(YB)
    ratV=round(LYB/20,2)
    return LYB,ratV






def cntr(img):
    Lx=img.shape[1]; Ly=img.shape[0]; YC=int(Ly/2); XC=int(Lx/2)
    img1=np.copy(img)
    im1=np.copy(img)
    imp=np.copy(img)
    if(img.shape[0]<5 or img.shape[1]<5): return img,[],[]
    hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    avL,avH=HLA(hsv); WHITE=int(avH*0.8)
    lowT=np.array([0,0 ,WHITE])
    uppT=np.array([255,120 ,255])
    maskT=cv2.inRange(hsv,lowT,uppT)
    mask3=maskT
    bina=np.copy(mask3)
    #............................................... AN3 1st bina with HC
    cnts2,_ = cv2.findContours(bina.copy(), cv2.RETR_LIST,
          cv2.CHAIN_APPROX_SIMPLE) # cv2.RETR_LIST, EXTERNAL
    #...............................................
    lencnt2=len(cnts2)
    gr4=np.copy(bina)
    gr5=np.copy(bina)
    Lx4=int(Lx*0.4)
    DXC=int(Lx/10); DYC=int(Ly*0.2); DXC1=DXC*5; DXC2=DXC*0.5; arc=100
    N4=0; NC4=0; data4=[]; shp=[]; PX1=Lx; PX2=0; P1=[]; P2=[]; NUMA=[]
    for C in cnts2: 
        shp.append(C.shape)
        NC4+=1
        (a,b,c,d)=cv2.boundingRect(C); 
        ar=c*d; asp2=round(d/c,2)
        if(ar<arc): continue
        if(c>DXC1 or c<DXC2): continue 
        if(d<DYC): continue 
        if(N4==0): H1=d
        N4+=1
        data4.append([a,b,c,d,ar])
        cv2.rectangle(gr5,(a,b),(a+c,b+d),50,2)
        nump=gr5[b:b+d,a:a+c]
        NUMA.append(nump)
        if(a<PX1): PX1=a; P1=[b,c,d]
        if(a>PX2): PX2=a; P2=[b,c,d]
    LN4=len(data4); #print('cntr_N4=',N4,' LN4=',LN4)
    return LN4,data4,NUMA,gr5,PX1,P1,PX2,P2






def RUNcntr(img):
    img1=np.copy(img)
    LN4,data4,NUMA,gr5,PX1,P1,PX2,P2=cntr(img1)
    for t in range(LN4): print('NUMt=',t,data4[t])
    return img,data4,NUMA



def AN3(img):
    Lx=img.shape[1]; Ly=img.shape[0]; YC=int(Ly/2); XC=int(Lx/2)
    img1=np.copy(img); im1=np.copy(img); imp=np.copy(img)
    if(img.shape[0]<5 or img.shape[1]<5): return img,[],[]
    hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    hsv2=cv2.resize(hsv,(int(Lx/4),int(Ly/4)))
    tH1=time.time()
    avL,avH=HLA(hsv2); WHITE=int(avH*0.8)
    tH2=time.time();#print('dHLA=',round(tH2-tH1,3),' WHI=',WHITE,hsv2.shape)
    lowT=np.array([0,0 ,WHITE])
    uppT=np.array([255,120 ,255])
    maskT=cv2.inRange(hsv,lowT,uppT)
    mask3=maskT
    bina=np.copy(mask3)
    #............................................... AN3 1st bina with HC
    cnts2,_ = cv2.findContours(bina.copy(), cv2.RETR_LIST,
          cv2.CHAIN_APPROX_SIMPLE) # cv2.RETR_LIST, EXTERNAL
    #...............................................
    lencnt2=len(cnts2)
    gr4=np.copy(bina)
    gr5=np.copy(bina)
    Lx4=int(Lx*0.4)
    DXC=int(Lx/10); DYC=int(Ly*0.3); DXC1=DXC*5; DXC2=DXC/2; arc=100
    N4=0; NC4=0; data4=[]; shp=[]; PX1=Lx; PX2=0; P1=[]; P2=[]
    #------- use rectangle corners to find P1,P2 for p1,2,3 & q1,2,3 ----
    for C in cnts2: 
        shp.append(C.shape)
        NC4+=1
        (a,b,c,d)=cv2.boundingRect(C); 
        ar=c*d; asp2=round(d/c,2)
        if(ar<arc): continue
        if(c>DXC1 or c<DXC2): continue 
        if(d<DYC): continue 
        if(N4==0): H1=d
        N4+=1
        data4.append([a,b,c,d,ar])
        cv2.rectangle(gr5,(a,b),(a+c,b+d),50,2)
        if(a<PX1): PX1=a; P1=[b,c,d]
        if(a>PX2): PX2=a; P2=[b,c,d]
    LN4=len(data4); #print('N4=',N4,' LN4=',LN4)
    KTIL=1
    if(len(P1)==0): print('len(P1) zero:'); imgTL=np.copy(img); KTIL=0
    if(len(P2)==0): print('len(P2) zero:'); imgTL=np.copy(img); KTIL=0
    #========================TILT&TWIST operation=====================
    if(KTIL==1):
        p1=(PX1,P1[0]); p2=(PX1,P1[0]+P1[2]); 
        x1=PX1; y1=P1[0]; w1=P1[1]; h1=P1[2]
        SW=[]; Nj=0
        for j in range(y1+5,y1+h1-5):
            Nj+=1
            for i in range(x1-2,x1+w1-2):
                if(i<0): continue
                if(bina[j,i]>100 and bina[j,i+1]<100 and bina[j,i+2]<100): 
                    if(len(SW)>1 and Nj>3 and i>SW[-1][0]+5): 
                        #print('jump:',j,i,SW[-1]); 
                        continue
                    cv2.circle(gr4,(i,j),2,125,-1)
                    SW.append([i,j]); break
        LSW=len(SW); LSW2=int(LSW/2)
        #print('AN3_LSW=',LSW)
        if(LSW<1 or LSW2<1):
            print('LSW=',LSW,LSW2,len(P1),len(P2))
            return img,[],[]
            #input('LLLLL')
        yy=np.array(SW); yy2=yy[0:LSW2,0].astype(int); LT=int(np.average(yy2))
        p1=[LT,SW[0][1]]; p2=SW[-1]; p3=(PX2+P2[1],P2[0]+5)
        q1=p1; q2=(p1[0],p2[1]); q3=(p3[0],p1[1])
        pts1=np.float32([p1,p2,p3])
        pts2=np.float32([q1,q2,q3])
        #....................................
        M=cv2.getAffineTransform(pts1,pts2)
        #....................................
        rows,cols,ch = img.shape
        co2=int(cols*1.0); ro2=int(rows*1.0)
        imgTL=cv2.warpAffine(img,M,(co2,ro2)) 
        #print('p1,2,3=',p1,p2,p3,' P1,2=',(PX1,P1),(PX2,P2))
        cv2.circle(imp,p1,8,(0,0,255),-1)
        cv2.circle(imp,p2,8,(0,0,255),-1)
        cv2.circle(imp,p3,8,(0,0,255),-1)
        #cv2.imshow('gr4_AN3',gr4)
        #cv2.imshow('gr5_AN3',gr5)
        #cv2.imshow('imp_AN3',imp)
        #cv2.imshow('imgTL_AN3',imgTL)
        #cv2.waitKey(0)
    #==========================================  NUMBER contours/bina with HC
    imgTLx=np.copy(imgTL); 
    #cv2.imshow('imgTLx',imgTLx)
    print('imgTLx.shape=',imgTLx.shape)
    XA1=0; XA2=imgTL.shape[1]; YA1=0; YA2=imgTL.shape[0]; 
    XA1,XA2,imx=borderVL(0.6,imgTL)
    imgT2=imgTL[YA1:YA2,XA1:XA2,:]
    YA1,YA2,imy=borderHL(imgT2)
    imgT2=imgTL[YA1:YA2,XA1:XA2,:]; imgTL=np.copy(imgT2)
    LTx=imgTL.shape[1]; LTy=imgTL.shape[0];
    newT=np.full((LTy,LTx+5,3),255,dtype=np.uint8)
    newT[:,0:LTx,:]=imgTL[:,:,:]
    imgTL=np.copy(newT)
    #cv2.imshow('TL',imgTL)
    hsv=cv2.cvtColor(imgTL,cv2.COLOR_BGR2HSV)
    #-------NUM-HLA---------------------
    hsv2=cv2.resize(hsv,(int(hsv.shape[1]/4),int(hsv.shape[0]/4)))
    avL,avH=HLA(hsv2); WHITE=int(avH*0.8)
    lowT=np.array([0,0 ,WHITE]); uppT=np.array([255,120 ,255])
    maskT=cv2.inRange(hsv,lowT,uppT)
    mask3=maskT
    bina=np.copy(mask3); Lbx=bina.shape[1]; Lby=bina.shape[0]; w8=Lbx/8
    #..............................AN3 2nd contour for Numbers
    cnts2,_ = cv2.findContours(bina.copy(), cv2.RETR_LIST,
          cv2.CHAIN_APPROX_SIMPLE) # cv2.RETR_LIST, EXTERNAL
    #.......................................................
    lencnt2=len(cnts2)
    gr4=np.copy(bina)
    gr5=np.copy(bina)
    N4=0; NC4=0; data4=[]; NUM=[]; XN=[]; HN=[]; WN=[]
    print('lencnt2=',lencnt2,' bina.shape=',bina.shape)
    for C in cnts2: 
        NC4+=1
        (a,b,c,d)=cv2.boundingRect(C); 
        ar=c*d; asp2=round(d/c,2)
        if(d<15): continue
        K4=100
        if(ar<200 or d<Lby*0.3): K4=1;print('K4=',K4,NC4,N4,ar,d,Lby);continue
        if(c>Lbx*0.4): K4=2; print('K4=',K4,NC4,N4,c,Lbx); continue
        if(c/d>0.6): K4=3; print('K4=',K4,NC4,N4); continue
        if(c<w8*0.4 and d<Lby*0.2): K4=4; print('K4=',K4,NC4,N4); continue
        if(d>LTy*0.8 and c<8): K4=5; print('K4=',K4,NC4,N4); continue
        N4+=1
        cv2.rectangle(gr5,(a,b-2),(a+c,b+d+2),50,1)
        E=2
        numc=gr4[b-E:b+d+E,a-E:a+c+E]; nx=numc.shape[1]; ny=numc.shape[0]
        if(nx<2 or ny<2 or nx>Lbx-3 or ny>Lby-3): numc=gr4[b:b+d,a:a+c]
        NUM.append(numc)
        data4.append([a,b,c,d]); XN.append(a); WN.append(c); HN.append(d)
    print('NC4=',NC4,N4,'lenWN=',len(WN),' WN=',WN)
    avW=round(np.average(WN),1); avH=round(np.average(HN),1)
    #if(len(WN)==0): avW=0; avH=0
    #else: avW=round(np.average(WN),1); avH=round(np.average(HN),1)
    XN2=XN.copy(); HN2=HN.copy(); WN2=WN.copy(); NUM2=NUM.copy()
    XN=[]; HN=[]; WN=[]; data=[]; NUM=[]; NN=0
    for i in range(len(XN2)):
        if(WN2[i]<avW*0.8 and HN2[i]<avH*0.8): 
            continue
        NN+=1; NUM.append(NUM2[i])
        XN.append(XN2[i]);data.append(data4[i]);
        WN.append(WN2[i]);HN.append(HN2[i])
    #------------------ divide 2 numbers----------
    len1=len(XN); XN0=XN.copy()
    if(len1>2): 
        XN2=XN.copy();WN2=WN.copy();HN2=HN.copy();data2=data4.copy()
        Wav=int(np.average(WN)); Wavc=int(Wav*2.2); XR=sorted(XN0);
        nt=0; 
        for t in range(len1-1):
            if(XR[t+1]-XR[t]>Wavc):
                nt+=1
                Xt=int((XR[t+1]+XR[t])/2)
                Wt=XR[t+1]-Xt
                Ht=HN[t]
                dt=[Xt,data4[t][1],Wt,Ht]
                numc=gr4[dt[1]:dt[1]+dt[3],dt[0]:dt[0]+dt[2]];
                XN2.append(Xt);WN2.append(Wt);HN2.append(Ht);
                data2.append(dt);NUM.append(numc)
        XN=XN2.copy(); WN=WN2.copy(); HN=HN2.copy(); data4=data2.copy()
    #---------------------------------------- partition numbers by box-------
    #cv2.imshow('TL_gr5',gr5); 
    XS=sorted(XN); NUM2=[]; WS=[]; print('XN=',XN,' XS=',XS)
    if(len(XN)<1): 
        print('lenXN=0',len(XN))
        #cv2.imshow('img_AN3_in',img)
        #cv2.imshow('img_AN3_imgTL',imgTL)
        #cv2.waitKey(0)
        return imgTL,[],[]
    for i in range(len(XS)):
        k=XN.index(XS[i])
        if(i<len(XS)-1): dX=XS[i+1]-XS[i]
        else: dX=0
    for i in range(len(XS)):
        k=XN.index(XS[i])
        print(i,k,(XS[i],XN[k]),data4[k])
        NUM2.append(NUM[k])
        WS.append(WN[k])
    Lnum2=len(NUM2)
    print('Lnum2=',Lnum2,XS,' WS=',WS)
    hsta=hstack(NUM2)
    #cv2.imshow('hsta',hsta)
    if(len(NUM2)<7): print('error lenNUM2=',len(NUM2))
    #cv2.destroyAllWindows();

    return imgTL,data4,NUM2
        


def hstack(NUM):
    hVL=100
    VL=np.full((hVL,5),128,dtype=np.uint8)
    PB=np.full((100,100),255,dtype=np.uint8)
    hsta=np.copy(VL)
    #cv2.imshow('hsta',hsta)
    for s in range(len(NUM)):
        pts=NUM[s]
        r=hVL/pts.shape[0]
        RX=int(pts.shape[1]*r); 
        if(RX>100): RX=100
        pts2=cv2.resize(pts,(RX,hVL)); XN=pts2.shape[1]
        IX=50-int(XN/2)
        pts3=np.copy(PB); pts3[:,IX:IX+XN]=pts2[:,:]
        hsta=np.hstack((hsta,pts3)); hsta=np.hstack((hsta,VL))
        #cv2.imshow('pts3'+str(s),pts3)
    #cv2.imshow('hsta',hsta)
    #cv2.waitKey(0)
    return hsta



#----------------------FFFFFBOX-------
def FBOX(image):
    ct0=time.time()
    im=np.copy(image); imga=np.copy(im); imgb=np.copy(im)
    Lx=im.shape[1]; Ly=im.shape[0]; Lxs=int(Lx/4); Lys=int(Ly/4);
    Lx2=int(Lx/MF); Ly2=int(Ly/MF); YC=Ly2
    im2=cv2.resize(im,(Lx2,Ly2)); img=np.copy(im2); im3=np.copy(im2)
    imrs=np.copy(im2); 
    img1=np.copy(im2); img2=np.copy(im2); im4=np.copy(im2)
    tw1=time.time()
    hsv=cv2.cvtColor(im2,cv2.COLOR_BGR2HSV)
    tw2=time.time()
    hsv2=cv2.resize(hsv,(int(Lx2/4),int(Ly2/4)))
    avL,avH=HLA(hsv2); rtw=0.8; WHITE0=int(avH*rtw); #if too black, reduce rtw
    tw3=time.time()
    for jw in range(0,1):
        tz1=time.time()
        im3=np.copy(imrs); im4=np.copy(imrs);
        #----------------------------- mask on black
        #WHITE=100+20*jw
        WHITE=WHITE0+20*jw
        lowT=np.array([0,0 ,WHITE])
        uppT=np.array([255,120 ,255])
        #-----------------------------
        mask3=cv2.inRange(hsv,lowT,uppT)
        imC=cv2.bitwise_and(img,img,mask=mask3)
        ct1=time.time()
        cnts1,_ = cv2.findContours(mask3.copy(), cv2.RETR_LIST,
              cv2.CHAIN_APPROX_SIMPLE) # cv2.RETR_LIST, EXTERNAL
        ct2=time.time()
        #..........................................................
        #cv2.drawContours(im3,cnts1,-1,(0,255,0),2)
        #cv2.imshow('im3',im3)
        Nc=0; Nac=0; NU=0; NBA=0; NFL=0; box=[]; data1=[]; 
        IMGSA=[]; PLAT=[]; PNUM=[]; dataAN=[]; TL=[]
        tz2=time.time()
        dt1=time.time()
        for c in cnts1: 
            tc1=time.time()
            Nc+=1
            M=cv2.moments(c)
            if(M['m00']==0): M['m00']=1
            cX=int(M['m10']/M['m00']); cY=int(M['m01']/M['m00'])
            area=int(cv2.contourArea(c));
            (x,y,w,h)=cv2.boundingRect(c); 
            xx1=[x,y,w,h]; mx1=[cX,cY]; xxa=[x,y,w,h]; xx0=[x,y,w,h]
            Ac=w*h; asp=round(h/w,2); ratA=round(area/Ac,3); aspx=1.*asp
            imgc=img1[y:y+h,x:x+w,:]; imgc0=np.copy(imgc)
            tc8=time.time()

            if(w<20 or h<10): continue
            if(h<30/MF or w<90/MF): NU+=1; continue
            if(Ac<1000/MF/MF): NU+=1; continue
            if(w>700/MF): NU+=1; continue
            if(asp<0.1): NU+=1; continue
            if(asp>0.9): NU+=1; continue
            if(y<xx1[3]/2 and w>xx1[2]/20): NU+=1; continue
            KC,NSW=censcan(imgc); RSW=round(NSW/w,2)
            if(KC==0): NU+=1; continue
            DBW,avH,avL,Dav=DBKWT(imgc)
            if(DBW==0): NU+=1; continue
            KHL,NHL=CKHL(imgc)
            if(KHL==0): NU+=1; continue

            NBA+=1; tcx=time.time(); tc2=time.time()
            tc3=time.time()
            KCNT=100
            if(KCNT<50): NFL+=1; continue
            cv2.destroyAllWindows();
            Nac+=1
            data1.append([xx1,mx1,Ac,asp])
            xx2=xx1.copy();mx2=mx1.copy();Ac2=Ac*MF*MF;asp2=asp*1;
            for t in range(4): xx2[t]=xx2[t]*MF;
            for t in range(2): mx2[t]=mx1[t]*MF;
            imgd=imga[xx2[1]:xx2[1]+xx2[3],xx2[0]:xx2[0]+xx2[2],:]; 
            #------------------------------FAN3-----
            ta1=time.time()
            imgTL,data4,NUM=AN3(imgd); 
            ta2=time.time(); dtan3=round(ta2-ta1,3)
            dataAN.append(data4)
            PNUM.append(NUM)
            TL.append(imgTL)
            #--------------------------------------
            PLAT.append(imgc)
            lenNUM=len(NUM)
            print('Nac,shape=',Nac,dtan3,imgTL.shape,imgd.shape,imgc.shape)
        ct2=time.time(); TFBOX=round(ct2-ct0,3)
        print('jw,WH=',jw,WHITE,WHITE0,' Nac=',Nac,'shape=',im4.shape,TFBOX)
        #cv2.waitKey(0)
    tw4=time.time()
    #cv2.imshow('im4_',im4)
    #print('im4 is done...jw_time_tw4-tw3=',tw4-tw3)
    #cv2.waitKey(0)
    return Nac,data1,PLAT,TL,PNUM,dataAN
    
    

def readpic():
    NPIC=15; PIC=[]
    for i in range(NPIC):
        s='plate02/P'+str(i+1).zfill(2)+'.JPG'
        PIC.append(s)
    return PIC


import os
def load_images_from_folder(folder):
    images=[]
    for filename in os.listdir(folder):
        img=cv2.imread(os.path.join(folder,filename))
        if img is not None: images.append(img)
    return images


def readimg():
    folder='comp'
    IMGS=load_images_from_folder(folder)
    return IMGS




if __name__ == '__main__':
    from time import sleep
    import cv2
    import numpy as np
    #print('fcolor.py as a main')

    tm0=time.time()
    readimg()
    #input('RRRR')

    #PIC=readpic()
    IMGS=readimg()
    print('lenIMGS=',len(IMGS))
    NPIC=len(IMGS)
    low=np.array([10,0 ,150 ])
    upp=np.array([250,40 ,255 ])


    #-------------------PPPPPPP
    tm1=time.time(); 
    FW=open('plate.txt','w'); FW2=open('pnum.txt','w')
    for j in range(NPIC):
    #for j in range(1,2):
        PJ=j
        fn='PLATE/plate_D2_'+str(j).zfill(2)
        imgi0=IMGS[j]
        Ly=imgi0.shape[0]; Lx=imgi0.shape[1]; Lx2=int(Lx/10); Ly2=int(Ly/10)
        imgi=np.copy(imgi0);img1=np.copy(imgi0)
        imgs=cv2.resize(imgi,(Lx2,Ly2))
        Ly=imgi.shape[0]; Lx=imgi.shape[1]
        if(Ly>3000):
            img1=imgi[1200:2400,100:3600,:]  # shaping in size (1200,3500)
            imgi=np.copy(img1)
        else:
            img1=imgi[int(Ly*0.2):,:,:]  # remove the farrest image
            imgi=np.copy(img1)
        Lx=imgi.shape[1]; Ly=imgi.shape[0]; Lxs=int(Lx/4); Lys=int(Ly/4);
        X1=img1.shape[1];Y1=img1.shape[0];X2=int(X1/4); Y2=int(Y1/4)
        imgis=cv2.resize(imgi,(Lxs,Lys))
        #============================================     MMM-FBOX
        ttm1=time.time()
        Nac,data1,PLAT,TL,PNUM,dataAN=FBOX(imgi)
        ttm2=time.time()
        dtm=round(ttm2-ttm1,3)
        print('PIC_j=',j,'out FBOX...,box_dtm',dtm)
        #cv2.waitKey(0)
        #============================================
        #continue

        PL0=np.copy(PLAT[0])
        print('showing PL0, Nac=',Nac,len(PLAT),len(PNUM),PL0.shape)
        PL0=cv2.resize(PLAT[0],(Lxs,Lys))
        #cv2.imshow('PL0',PL0); cv2.waitKey(0)

        s=data1
        FW.write(str(s)+'\n')
        s2=[1000+Nac]
        for t in range(Nac): s2.append(len(PNUM[t]))
        FW2.write(str(s2)+'\n')
        cv2.destroyAllWindows();
        fn0=fn+'.png'
        cv2.imwrite(fn0,PLAT[0])
        PL0=cv2.resize(PLAT[0],(Lxs,Lys))
        #cv2.imshow('PL0',PL0); cv2.waitKey(0)
        #print('s=',s,' s2=',s2)
        for t in range(1,Nac+1):
            fnt=fn+'_'+str(t).zfill(2)+'.png'
            #cv2.imwrite(fnt,PLAT[t])
            #cv2.imshow('PL',PLAT[t])
            #cv2.imshow('TL',TL[t-1])
            fntL=fn+'_L'+str(t).zfill(2)+'.png'
            #cv2.imwrite(fntL,TL[t-1])
            hVL=100
            VL=np.full((hVL,5),128,dtype=np.uint8)
            PB=np.full((100,100),255,dtype=np.uint8)
            hsta=np.copy(VL)
            #cv2.imshow('hsta',hsta); cv2.waitKey(0)
            for s in range(len(PNUM[t-1])):
                pts=PNUM[t-1][s]
                r=hVL/pts.shape[0]
                RX=int(pts.shape[1]*r); 
                if(RX>100): RX=100
                #print(t,s,'pts.shape=',pts.shape,RX,hVL)
                pts2=cv2.resize(pts,(RX,hVL)); XN=pts2.shape[1]
                IX=50-int(XN/2)
                #print('pts.shape=',pts.shape,pts2.shape,PB.shape,XN,IX)
                pts3=np.copy(PB); pts3[:,IX:IX+XN]=pts2[:,:]
                hsta=np.hstack((hsta,pts3)); hsta=np.hstack((hsta,VL))
                #print(t,len(PNUM[t-1]),pts.shape,pts2.shape,hsta.shape)
                fnts=fn+'_N'+str(t).zfill(2)+'_'+str(s)+'.png'
                #cv2.imwrite(fnts,PNUM[t-1][s])
                cv2.imwrite(fnts,pts3)
                #cv2.imshow('TLN'+str(s),PNUM[t-1][s])
            cv2.imshow('hsta'+str(t),hsta)
            #cv2.imshow('plat_'+str(t).zfill(2),PLAT[t])
            #cv2.waitKey(0)
        #print('j_file=',j,fn,Nac,data1[0:2])
        print('j_file=',j,fn,Nac,data1[0:2])

        #print('back from Wbox in main, lenda2=',lenda2)
        #print('back from Wbox in main')
        #cv2.waitKey(0)
        #cv2.destroyAllWindows();
        #if(lenda2==0): continue
        #gr3s=cv2.resize(gr3,(Lxs,Lys))
        #cv2.imshow('gr3s',gr3s)
        cv2.waitKey(0)


tm2=time.time()
ttm0=round(tm1-tm0,3)
ttm=round(tm2-tm1,3)
TEXE=round(tm2-tm0,3)
print('read-in: ttm0=',ttm0,' from PPP to the end, ttm=',ttm,' TEXE=',TEXE)
FW.close()
FW2.close()
#cv2.waitKey(0)
cv2.destroyAllWindows();
#cap.release()

