PYTHON程式語言的學習-openCV, cv2

這裡介紹如何使用 Python 與 OpenCV 讀取影像圖檔,以及將處理好的圖形寫入檔案。
導入cv2模組: import cv2
  1. cv2的基本指令
  2. cv2.imread(); cv2.IMREAD_GRAYSCALE; cv2.imshow(); cv2.waitKey(0); cv2.destroyAllWindows(); cv2.destroyWindow(); cv2.imwrite()
    import numpy as np
    import cv2
    # 讀取圖檔
    img = cv2.imread('rect-3.png')
    print('type=',type(img))
    print('shape=',img.shape,'   ndim=',np.ndim(img))
    img_gray = cv2.imread('rect-3.png', cv2.IMREAD_GRAYSCALE)
    print('type=',type(img_gray))
    print('shape=',img_gray.shape,'   ndim=',np.ndim(img_gray))
    # 顯示圖片
    cv2.imshow('My Image 1', img)
    # 按下任意鍵則關閉所有視窗
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    cv2.imshow('My Image 2', img)
    cv2.imshow('My Image 3', img_gray)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    cv2.imshow('My Image 2', img)
    cv2.imshow('My Image 3', img_gray)
    cv2.waitKey(0)
    # 關閉 'My Image 2' 視窗
    cv2.destroyWindow('My Image 2')
    
    cv2.waitKey(0)
    cv2.destroyWindow('My Image 3')
    
    # 寫入圖檔
    cv2.imwrite('rect-3gray.png', img_gray)
    
    type= 
    shape= (260, 298, 3)    ndim= 3
    type= 
    shape= (260, 298)    ndim= 2
    



  3. 圖片的縮圖與陣列的關係
  4. 圖片是以像素的形式呈現而像素的資訊由陣列所儲存的數據所決定。將圖片縮圖等同於將一個比較多的資訊的大的陣列指,指按照比例保留部分的陣列數據,因此縮圖與陣列之間是有對應關係的。
    import numpy as np
    import cv2
    img = cv2.imread('rect-3.png')
    (Lx,Ly)=(img.shape[0],img.shape[1])
    F=4
    Lx2=int(Lx/F); Ly2=int(Ly/F)
    img2=np.full((Lx2,Ly2,3),0,dtype=np.uint8)
    print('Lx=',Lx,'  Ly=',Ly,'  Lx2=',Lx2,'  Ly2=',Ly2)
    for i in range(0,Lx2):
        for j in range(0,Ly2):
            x=i*F; y=j*F
            for k in range(3):
                img2[i][j][k]=img[x][y][k]    
    
    print(img.shape)
    print(img2.shape)
    cv2.imwrite('rect-3F4.png', img2)
    cv2.imshow('My Image 1', img)
    cv2.imshow('My Image 2', img2)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    Lx= 260   Ly= 298   Lx2= 65   Ly2= 74
    (260, 298, 3)
    (65, 74, 3)
    



  5. 直接取代陣列的數值進而可以有目的地改變圖片
  6. 用雙重迴圈直接將陣列的數值,以黃色所對應的數值取代(B,G,R)=(0.255,255),就可將圖片某個區塊的顏色完全取代為黃色,達到遮蔽的效應。
    import numpy as np
    import cv2
    img = cv2.imread('rect-3.png')
    (Lx,Ly)=(img.shape[0],img.shape[1])
    F=2
    Lx2=int(Lx/F); Ly2=int(Ly/F)
    img2=np.copy(img)
    print('Lx=',Lx,'  Ly=',Ly,'  Lx2=',Lx2,'  Ly2=',Ly2)
    for i in range(0,Lx2):
        for j in range(0,Ly2):
            for k in range(3):
                img2[i][j][0]=0;img2[i][j][1]=255;img2[i][j][2]=255;
    print(img.shape)
    print(img2.shape)
    cv2.imwrite('rect-3block_1.png', img2)
    cv2.imshow('My Image 1', img)
    cv2.imshow('My Image 2', img2)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    Lx= 260   Ly= 298   Lx2= 130   Ly2= 149
    (260, 298, 3)
    (260, 298, 3)
    



  7. 列印陣列的數值
  8. 列印陣列的數值內容以便驗證與圖形的對應關係。
    import numpy as np
    import cv2
    img = cv2.imread('rect-3F4.png')
    (Lx,Ly)=(img.shape[0],img.shape[1])
    Lx2=int(Lx/2)
    print('Lx=',Lx,'  Ly=',Ly)
    for i in range(Lx2,Lx2+1):
        for j in range(0,Ly):
            if(j < int(Ly/2)):
                print(i,j,img[i,j,0],img[i,j,1],img[i,j,2])
            for k in range(3):
                img[i][j][0]=0;img[i][j][1]=0;img[i][j][2]=255;
    print(img.shape)
    cv2.imwrite('rect-3VL.png', img)
    cv2.imshow('My Image 1', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    Lx= 65   Ly= 74
    32 0 255 255 255
    32 1 255 255 255
    32 2 255 255 255
    32 3 255 255 255
    32 4 255 255 255    白色
    32 5 255 255 255
    32 6 255 255 255
    32 7 255 255 255
    32 8 255 255 255
    32 9 255 255 255
    32 10 0 0 0          黑色
    32 11 0 0 0
    32 12 255 255 255
    32 13 255 255 255
    32 14 255 255 255
    32 15 255 255 255
    32 16 255 255 255
    32 17 255 255 255
    32 18 255 255 255    白色
    32 19 255 255 255
    32 20 255 255 255
    32 21 255 255 255
    32 22 255 255 255
    32 23 255 255 255
    32 24 36 28 237
    32 25 36 28 237      紅色
    32 26 255 255 255
    32 27 255 255 255
    32 28 255 255 255    白色
    32 29 255 255 255
    32 30 255 255 255
    32 31 255 255 255
    32 32 232 162 0
    32 33 232 162 0
    32 34 232 162 0    藍色
    32 35 232 162 0
    32 36 232 162 0
    (65, 74, 3)
    



  9. 分析軌道的斜率
  10. 為了能夠節省計算機時間,我們先將攝影機所拍攝到的相片的像素降低,然後再捕捉紅色像素的位置,根據紅色像素的兩端坐標決定紅色軌道的斜率。未來我們將藉由軌道的斜率和軌道的底端初始位置,決定自駕車將調整為什麼樣的方向行駛。
    import numpy as np
    import cv2
    
    def rescale(img,Lx,Ly):
        F=8
        Lx2=int(Lx/F); Ly2=int(Ly/F)
        img2=np.full((Lx2,Ly2,3),0,dtype=np.uint8)
        for i in range(0,Lx2):
            for j in range(0,Ly2):
                x=i*F; y=j*F
                for k in range(3):
                    img2[i][j][k]=img[x][y][k]  
                if(j==int(Ly2/2)): img2[i][j][0]=0; img2[i][j][1]=0; img2[i][j][2]=0;
        return img2,Lx2,Ly2
    
    def laneRED(img2,Lx2,Ly2,Lx3,Ly3):
        img3=np.full((Lx2,Ly2,3),255,dtype=np.uint8)
        NR=0; NL=0; RED=[]
        for i in range(Lx2):
            for j in range(Ly2):
                if(img2[i][j][2] > 255*0.7 and img2[i][j][2] > 1.2*img2[i][j][1] and img2[i][j][2] > 1.2*img2[i][j][1]):
                    RED.append([i,j])
                    img3[i][j][0]=img2[i][j][0]; img3[i][j][1]=img2[i][j][1]; img3[i][j][2]=img2[i][j][2];
                    if(j < Ly3): 
                        NL+=1
                    else:
                        NR+=1
                if(j==Ly3): img3[i][j][0]=0; img3[i][j][1]=0; img3[i][j][2]=0; 
        NR=len(RED)
        x0=RED[NR-1][1];y0=Lx2-RED[NR-1][0];
        x1=RED[1][1];y1=Lx2-RED[1][0];
        slope=(y1-y0)/(x1-x0)
        i=RED[NR-1][0];j=RED[NR-1][1]
        img3[i][j][0]=0; img3[i][j][1]=255; img3[i][j][2]=0
        i=RED[1][0];j=RED[1][1]
        img3[i][j][0]=255; img3[i][j][1]=0; img3[i][j][2]=0
        return NL,NR,img3,(x0,y0),(x1,y1),slope
    
    
    for j in range(1,4):
        flin='laneBox_0'+str(j)+'.png'
        flout='laneBox_SLOPE_0'+str(j)+'.png'
        img = cv2.imread(flin)
        (Lx,Ly)=(img.shape[0],img.shape[1])
        img2,Lx2,Ly2=rescale(img,Lx,Ly)
        Lx3=int(Lx2/2); Ly3=int(Ly2/2)
        #print(img.shape, img2.shape)
        NL,NR,img3,(x0,y0),(x1,y1),slope=laneRED(img2,Lx2,Ly2,Lx3,Ly3)
        print('NL=',NL,'  NR=',NR,(x0,y0),(x1,y1),'  slope=',slope,np.arctan(slope))
        cv2.imwrite(flout,img3)
        #cv2.imshow('My Image 3', img3)    
        #cv2.waitKey(0)
        #cv2.destroyAllWindows()
    
    NL= 221   NR= 384 (49, 1) (41, 52)   slope= -6.375 -1.415201498817867
    NL= 219   NR= 538 (78, 1) (7, 34)   slope= -0.4647887323943662 -0.4350839511620461
    NL= 299   NR= 337 (5, 1) (49, 41)   slope= 0.9090909090909091 0.7378150601204649
    1