# Pytho影像辨識 \\192.168.100.254 python版本3.6 pip install tensorflow==1.9.0 pip install opencv-python==3.4.3.18 pip install numpy==1.16.0 ndim 維度 shape n*m的矩陣 size n*m矩陣的大小 ```python= import numpy as np import cv2 as cv #讀取圖檔 img = cv.imread('./img/nut_screw.jpg') #顯示影像資訊(寬 高 通道(RGB彩色圖片為3,灰階圖片為1)) print('width:%d\nheight:%d\nchannel:%d'%(img.shape[0],img.shape[1],img.shape[2])) #顯示圖片 cv.imshow('nut_screw',img) #按下任意鍵關閉式窗 cv.waitKey(0) cv.destroyAllWindows() ``` width:480 height:640 channel:3 ## 基本繪圖 ```python= import numpy as np import cv2 as cv #首先建立一個256*256空白圖片,並在上面畫一個長方形,繪圖的方式一樣有函式可以提供使用,但須依照函式參數的規定 #建立一張256*256的RGB圖片 img = np.zeros((256,256,3),np.uint8) #uint8是沒有符號的整數 大致上的意思就是非負整數 #長方形(影像,頂點座標,對向頂點座標,顏色,線條寬度,(-1為填滿)) cv.rectangle(img,(20,60),(120,160),(0,0,255),2) #顯示會徒影像 cv.imshow('shape image',img) #按下任意鍵關閉式窗 cv.waitKey(0) cv.destroyAllWindows() ``` ![](https://i.imgur.com/SYyRrBK.png) ```python= import numpy as np import cv2 as cv #首先建立一個256*256空白圖片,並在上面畫一個長方形,繪圖的方式一樣有函式可以提供使用,但須依照函式參數的規定 #建立一張256*256的RGB圖片 img = np.zeros((256,256,3),np.uint8) #uint8是沒有符號的整數 大致上的意思就是非負整數 #長方形(影像,頂點座標,對向頂點座標,顏色,線條寬度,(-1為填滿)) cv.rectangle(img,(40,800),(100,140),(125,0,0),-1) #實心長方形 #顯示會徒影像 cv.imshow('shape image',img) #按下任意鍵關閉式窗 cv.waitKey(0) cv.destroyAllWindows() ``` ![](https://i.imgur.com/7HTbs9S.png) ```python= import numpy as np import cv2 as cv #首先建立一個256*256空白圖片,並在上面畫一個長方形,繪圖的方式一樣有函式可以提供使用,但須依照函式參數的規定 #建立一張256*256的RGB圖片 img = np.zeros((256,256,3),np.uint8) #uint8是沒有符號的整數 大致上的意思就是非負整數 #圓形(影像,圓心座標,半徑,顏色,線條寬度) cv.circle(img,(90,120),30,(0,255,255),3) #橢圓形(影像,中心座標,軸長,旋轉角度,起始角度,結束角度,顏色,線條寬度) cv.ellipse(img,(180,200),(25,55),45,0,360,(205,0,255),2) #設定多邊形頂點座標 pts= np.array([[170,55],[165,75],[220,90],[200,60]], np.int32) #多邊形(影像,頂點座標,封閉型,顏色,線條寬度) cv.polylines(img,[pts],True,(255,255,0),4) #顯示會徒影像 cv.imshow('shape image',img) #按下任意鍵關閉式窗 cv.waitKey(0) cv.destroyAllWindows() ``` ![](https://i.imgur.com/Y0unpvG.png) ------------------------------------------------------- ![](https://i.imgur.com/UFjwtSV.jpg) 影像處理的典型處理有翻轉,形態學處理,濾波,縮放,旋轉等 形態學有腐蝕,膨脹,開運算,閉運算,形態學是從影像分析其分量資訊,該資訊通常對表達和描繪影像的形式具有重要意義,舉例來說在處理手寫識別 只要針對骨架運算即可,所以在視覺檢測,醫學影像處理,影像壓縮編碼都有重要的應用 腐蝕是最基本的,可以把影像的邊界點消除,使影像沿著邊界向內收縮,也可以將小於指定結構元素部分去除 膨脹和腐蝕的作用是相反的,它是對影像的邊界進行擴張,如果影像內兩個物件距離較近,兩個物件可能連通在一起 kernel = cv2.getStructuringElement() 傳回指定形狀的結構 矩形: MORPH_RECT 交叉形:MORPH_CROSS 橢圓形:MORPH_ELLIPSE 第二和第三的參數主要是尺寸和觸點的位置 erode -> 腐蝕 dilate -> 膨脹 ```python= import numpy as np import cv2 img = cv2.imread('./img/1-1.bmp',0) #OpenCV定義的結構元素 kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3)) #腐蝕圖像 eroded = cv2.erode(img,kernel) cv2.imshow("Eroded Image",eroded) #膨脹圖像 dilated = cv2.dilate(img,kernel) cv2.imshow("Dilated Image",dilated) #顯示原圖 cv2.imshow("origin",img) #NumPy定義的結構元素 NpKernel = np.uint8(np.ones((3,3))) Nperoded = cv2.erode(img,NpKernel) #顯示腐蝕後的圖像 cv2.imshow("Eroded by NumPy kernal",Nperoded); cv2.waitKey(0) cv2.destroyAllWindows() ``` ![](https://i.imgur.com/HuFMqBL.png) ```python= import numpy as np import cv2 img = cv2.imread('./img/1-1.bmp',0) #定義結構元素 kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) #閉運算 closed = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)#先膨脹,後腐蝕,去黑噪點 先開再合,淺色成分得勢 cv2.imshow("Close",closed) #開運算 opened = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)#先腐蝕,後膨脹,去白噪點 先合再開,對淺色成分不利 cv2.imshow("Open",opened) cv2.waitKey(0) cv2.destroyAllWindows() ``` ![](https://i.imgur.com/G1sJexs.png) ## 影象掩模主要用於: ①提取感興趣區,用預先製作的感興趣區掩模與待處理影象相乘,得到感興趣區影象,感興趣區內影象值保持不變,而區外影象值都為0。 ②遮蔽作用,用掩模對影象上某些區域作遮蔽,使其不參加處理或不參加處理引數的計算,或僅對遮蔽區作處理或統計。 ③結構特徵提取,用相似性變數或影象匹配方法檢測和提取影象中與掩模相似的結構特徵。 ④特殊形狀影象的製作。 ```python= import numpy as np import cv2 as cv # set blue thresh lower_yellow=np.array([11,43,46]) upper_yellow=np.array([25,255,255]) frame=cv.imread("./img/1-4.png") cv.imshow('who',frame) #compress cp = cv.resize(frame,(300,300), interpolation=cv.INTER_AREA) cv.imwrite("tulips_1.jpg",cp) #change to hsv model hsv = cv.cvtColor(cp, cv.COLOR_BGR2HSV) #get mask mask = cv.inRange(hsv, lower_yellow, upper_yellow) cv.imshow('Mask',mask)#掩模 #deect blue res = cv.bitwise_and(cp, cp, mask=mask) cv.imshow('Result',res)#處理後 cv.waitKey(0) cv.destroyAllWindows() ``` ![](https://i.imgur.com/HmyxLhu.png) ## 陣列的重塑 reshape要注意重塑後的尺寸要和原來的符合 ```python= import numpy as np np.random.seed(0) x1 = np.random.randint(10,size=6) x2 = np.random.randint(10,size=(3,4)) x3 = np.random.randint(10,size=(3,4,5)) print('x1:',x1) print('x2:',x2) print('x3:',x3) ``` x1: [5 0 3 3 7 9] x2: [[3 5 2 4] [7 6 8 8] [1 6 7 7]] x3: [[[8 1 5 9 8] [9 4 3 0 3] [5 0 2 3 8] [1 3 3 3 7]] [[0 1 9 9 0] [4 7 3 2 7] [2 0 0 4 5] [5 6 8 4 1]] [[4 9 8 1 1] [7 9 9 3 6] [7 2 0 3 5] [9 4 4 6 4]]] ```python= x2.reshape((4,3))# 計算方式原陣列(3,4)=12,重塑後的質也要是一樣 ``` array([[3, 5, 2], [4, 7, 6], [8, 8, 1], [6, 7, 7]]) ```python= z=np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14,15,16]]) z.reshape(-1,1)#這跟(16,1)是一樣的,會用-1是因為你不知道總共幾列的時候再使用的 ``` array([[ 1], [ 2], [ 3], [ 4], [ 5], [ 6], [ 7], [ 8], [ 9], [10], [11], [12], [13], [14], [15], [16]]) ## 串接 vstack 垂直串接 hstack 水平串接 ```python= x = np.array([1,2,3]) grid = np. array([[9,8,7],[6,5,4]]) np.vstack([x,grid]) ``` array([[1, 2, 3], [9, 8, 7], [6, 5, 4]]) ```python= y = np.array([[99],[99]]) np.hstack([y,grid]) ``` array([[99, 9, 8, 7], [99, 6, 5, 4]]) ### imread() imwrite() 支援bmp,png,jpg,jpeg,tiff格式 imread()函數的參數 IMREAD_ANYCOLOR=4 IMREAD_ANYDEPTH=2 IMREAD_COLOR=1 以RGB格是讀取 IMREAD_GRAYSCALE=0 灰度圖像讀取 IMREAD_LOAD_GDAL=8 IMREAD_UNCHANGED=-1 原始圖像讀取 ```python= mport numpy as np import cv2 as cv img = cv.imread('img/va.jpg',0) cv.imwrite('img/va.png',img) ``` ![](https://i.imgur.com/2I8Q5Ml.png) ### 非黑即白的二值圖 THRESH_BINARY(黑白) THRESH_BINARY_INY(黑白反轉) THRESH_TRUNC(多像素值) THRESH_TOZERO THRESH_TOZERO_INV ```python= import cv2 as cv import matplotlib.pyplot as plt img = cv.imread('img/va.jpg',0) ret,thresh1 = cv.threshold(img,127,255,cv.THRESH_BINARY) ret,thresh2 = cv.threshold(img,127,255,cv.THRESH_BINARY_INV) ret,thresh3 = cv.threshold(img,127,255,cv.THRESH_TRUNC) ret,thresh4 = cv.threshold(img,127,255,cv.THRESH_TOZERO) ret,thresh5 = cv.threshold(img,127,255,cv.THRESH_TOZERO_INV) titles = ['img','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV'] images = [img,thresh1,thresh2,thresh3,thresh4,thresh5] for i in range(6): plt.subplot(2,3,i+1),plt.imshow(images[i],'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show() ``` ![](https://i.imgur.com/pbnzwqE.png) ### 圖像疊加或圖像混合 cv2.addWeighted(src1(第一張圖), alpha(第一張圖權重), src2(第二張圖), beta(第二張圖權重), gamma(標量加到每個和上), dtype(輸出的陣列型態)) ```python= import cv2 img1 = cv2.imread('img/lena.jpeg') img = cv2.imread('img/opencv-logo-white.png') h,w,_ = img1.shape img2 = cv2.resize(img,(w,h),interpolation=cv2.INTER_AREA) alpha=0.7 beta=1-alpha gamma=0 img_add = cv2.addWeighted(img1,alpha,img2,beta,gamma) cv2.namedWindow('addImage') cv2.imshow('img_add',img_add) cv2.waitKey(0) cv2.destroyAllWindows() ``` ![](https://i.imgur.com/Ot62EE2.png) ```python= import cv2 image=cv2.imread('img/va.jpg') gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) cv2.imshow('Original Image',image) cv2.imshow('Gray Image',gray) cv2.waitKey(0) cv2.destroyAllWindows() ``` ![](https://i.imgur.com/ij9lBmN.png) ## kaeras/tensorflew 純量 向量 張量 還有一個(? #### 3D張量 股票交易 1個叫一日有350分鐘,股票價格 推文數據 10000條推文,1條推文編碼280個字,每個的大小飆馬維128二進制 #### 4D張量 圖像 (sample,width,height,channel) #### 5D張量 影片 (sample,frame,width,height,channel) ## 神經網路 感知器->多層感知器->深度學習->機器學習 CNN->LSTM RNN->圖片 ANN->產品預測 土木 ![](https://i.imgur.com/6oJ8HAR.jpg) 真伪表 ```python= import numpy as np print('導入全重(w)和偏差值(bias)') def AND(x1,x2): x=np.array([x1,x2]) w=np.array([0.5,0.5]) b=-0.7 tep=np.sum(x*w)+b if tep<=0: return 0 elif tep>0: return 1 print(AND(1,1)) print(AND(0,1)) print(AND(1,0)) print(AND(0,0)) ``` 導入全重(w)和偏差值(bias) 1 0 0 0 ```python= import numpy as np def OR(x1,x2): x=np.array([x1,x2]) w=np.array([0.5,0.5]) b=-0.7 tep=np.sum(x*w)+b if tep==-0.7: return 0 if tep!=-0.7: return 1 print(OR(1,1)) print(OR(1,0)) print(OR(0,1)) print(OR(0,0)) ``` 1 1 1 0 ### 激活函數 activation function ```python= #sigmoid import numpy as np import matplotlib.pyplot as plt def sigmoid(x): return 1/(1+np.exp(-x)) #sigmoid繪圖 x=np.arange(-5.0,5.0,0.1) y=sigmoid(x) plt.plot(x,y) plt.ylim(-0.1,1.1) plt.title('sigmoid model') print(y) print(plt.show()) ``` ![](https://i.imgur.com/X7x4IHN.png) ```python= #Relu import numpy as np import matplotlib.pyplot as plt def relu(x): return np.maximum(0,x) x=np.arange(-5.0,5.0,0.1) y=relu(x) print(y) plt.plot(x,y) plt.title('Relu Model') plt.ylim(-0.1,1.1) print(plt.show()) ``` ![](https://i.imgur.com/jCNeLyW.png) ![](https://i.imgur.com/BxCOp9y.jpg) ```python= #開始使用 keras Sequential from keras.models import Sequential #從上而下的模型 from keras.layers import Dense,Activation #全連接層(圖像辨識) 激活函數 model = Sequential() model.add(Dense(32,input_shape=(784,)))#shape輸入尺寸 model=Sequential() model.add(Dense(32,input_dim=784))#dim指定大小 ``` 其實這邊的shape 跟 dim是一樣的意思 #### 優化器 SGD(常用) Aaagrad RMSprop(常用) Adam(常用) Nadam #### learning rate 學習速率 簡寫 lr 學習速率值不是越大越好 也不是越小越好 是有一個中間值 #### loss function 損失函數 categorial_crossentropy 多分類 binary_crossentropy 二分類 mse 均方誤差回歸的問題 ```python= from keras.models import Sequential from keras.layers import Dense,Activation model=Sequential() model.add(Dense(32,activation='relu',input_dim=100)) model.add(Dense(1,activation='sigmoid')) model.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['accuracy']) #生成虛擬數據 import numpy as np data=np.random.random((1000,100)) labels=np.random.randint(2,size=(1000,1)) #訓練模型 以32個像本為一個小batch進行跌代 model.fit(data,labels,epochs=30,batch_size=32) ``` 損失函數越少越好 確率越高越好 ```python= import numpy as np # 讀進檔案,以,(逗號)分隔的csv 檔,不包含第一行的欄位定義 my_data= np.genfromtxt('pkgo_city66_class5_v1.csv',delimiter=',',skip_header=1) # Input 是有200 個欄位(index從0 –199) X_train= my_data[:,0:200] #Output 是第201 個欄位(index 為200) y_train= my_data[:,200] # 確保資料型態正確 X_train= X_train.astype('float32') y_train= y_train.astype('int') ``` ```python= # 觀察一筆X_train print(X_train[1,:32]) ``` [ 7.3256761e-02 -7.0322311e-01 9.0000000e+00 8.0000000e+00 2.0000000e+00 5.0000000e+01 4.5000000e+01 4.0000000e+00 4.0000000e+00 5.0000000e+01 1.0000000e+00 8.0000000e+00 8.0000000e+00 1.3000000e+01 0.0000000e+00 6.6000000e+01 2.0000000e+00 5.0000000e+00 5.1172823e-01 -1.1999401e-01 2.6103905e-01 4.3340247e-02 1.2053800e+00 1.8323834e+00 -1.3990576e+00 1.1236267e+00 6.2422687e-01 -8.8116989e-02 1.4191625e+00 -1.1424987e+00 -4.7916454e-01 0.0000000e+00] ```python= #[重要] 將Output 從特定類別轉換成one-hot encoding 的形式 from keras.utils import np_utils Y_train= np_utils.to_categorical(y_train,5)#to_categorical就是将类别向量转换为二进制(只有0和1)的矩阵类型 # 轉換成one-hot encoding 後的Y_train print(Y_train[1,:]) ``` [1. 0. 0. 0. 0.] ```python= #pip install scikit-learn import numpy as np exec(open("00_readingInput.py").read()) ``` ```python= from keras.models import Sequential from keras.layers import Dense,Activation ``` ```python= model = Sequential() model.add(Dense(128,input_dim=200)) model.add(Activation('sigmoid')) model.add(Dense(256)) model.add(Activation('sigmoid')) model.add(Dense(5)) model.add(Activation('softmax')) model.summary() ``` ![](https://i.imgur.com/J2pGHMu.png) ```python= from keras.optimizers import SGD, Adam, RMSprop, Adagrad sgd = SGD(lr=0.1,momentum=0.0,decay=0.0,nesterov=False) #lr學習速率 #momentum 更新的動能,一般定為0.5 #decay 每次更新後,學習速率隨之衰減的比率 #nesterov 是否使用Nesterov動量 model.compile(loss='categorical_crossentropy',optimizer=sgd,metrics=['accuracy']) batch_size=16 epochs=30 history_ce=model.fit(X_train,Y_train,batch_size=batch_size,epochs=epochs,verbose=1,shuffle=True,validation_split=0.1) loss_ce = history_ce.history.get('loss') acc_ce = history_ce.history.get('acc') ''' Visualize the loss and accuracy of both models''' import matplotlib.pyplot as plt plt.figure(0) plt.subplot(121) plt.plot(range(len(loss_ce)), loss_ce,label='CE') plt.title('Loss') plt.legend(loc='upper left') plt.subplot(122) plt.plot(range(len(acc_ce)), acc_ce,label='CE') plt.title('Accuracy') plt.savefig('00_firstModel.png',dpi=300,format='png') plt.close() print('Result saved into 00_firstModel.png') ``` ![](https://i.imgur.com/pG6v6HA.png) ![](https://i.imgur.com/5v3LQJX.png) ![](https://i.imgur.com/nLDjsHC.png) ![](https://i.imgur.com/aBA90WS.png) ![](https://i.imgur.com/LQqHdCX.png) ![](https://i.imgur.com/mmNGv6P.png) ![](https://i.imgur.com/qUH43cG.png) ![](https://i.imgur.com/6WHCpXu.png) ![](https://i.imgur.com/yCDHrye.png) 我一共訓練了9次 ```python= #改變損失函數 mean_squared_error from keras.optimizers import SGD, Adam, RMSprop, Adagrad sgd = SGD(lr=0.1,momentum=0.0,decay=0.0,nesterov=False) model.compile(loss='mean_squared_error',optimizer=sgd,metrics=['accuracy']) batch_size=16 epochs=30 history_ce=model.fit(X_train,Y_train,batch_size=batch_size,epochs=epochs,verbose=1,shuffle=True,validation_split=0.1) loss_ce = history_ce.history.get('loss') acc_ce = history_ce.history.get('acc') ''' Visualize the loss and accuracy of both models''' import matplotlib.pyplot as plt plt.figure(0) plt.subplot(121) plt.plot(range(len(loss_ce)), loss_ce,label='CE') plt.title('Loss') plt.legend(loc='upper left') plt.subplot(122) plt.plot(range(len(acc_ce)), acc_ce,label='CE') plt.title('Accuracy') plt.savefig('00_firstModel.png',dpi=300,format='png') plt.close() print('Result saved into 00_firstModel.png') ``` ![](https://i.imgur.com/BUp1AoQ.png) ![](https://i.imgur.com/cwdZB0l.png) 訓練了2次 表示這個損失函數在這模型不是很好 ```python= from keras.models import Sequential from keras.layers import Dense,Activation model = Sequential() model.add(Dense(128,input_dim=200)) model.add(Activation('relu')) model.add(Dense(256)) model.add(Activation('relu')) model.add(Dense(5)) model.add(Activation('softmax')) model.summary() from keras.optimizers import SGD, Adam, RMSprop, Adagrad #sgd = SGD(lr=0.1,momentum=0.0,decay=0.0,nesterov=False) adam=Adam(lr=0.001) model.compile(loss='categorical_crossentropy',optimizer=sgd,metrics=['accuracy']) batch_size=16 epochs=30 history_adam=model.fit(X_train,Y_train,batch_size=batch_size,epochs=epochs,verbose=1,shuffle=True,validation_split=0.1) loss_adam = history_adam.history.get('loss') acc_adam = history_adam.history.get('acc') val_loss_adam = history_adam.history.get('loss') val_acc_adam = history_adam.history.get('acc') ''' Visualize the loss and accuracy of both models''' import matplotlib.pyplot as plt plt.figure(0,figsize=(8,6)) plt.subplot(121) plt.plot(range(len(loss_adam)), loss_adam,label='Training') plt.plot(range(len(val_loss_adam)), val_loss_adam,label='Validation') plt.title('Loss') plt.xlabel("epoch") plt.legend(loc='upper left') plt.subplot(122) plt.plot(range(len(acc_adam)), acc_adam,label='Training') plt.plot(range(len(val_acc_adam)), val_acc_adam,label='Validation') plt.title('Accuracy') plt.xlabel("epoch") plt.tight_layout() plt.savefig('05_overfittingCheck.png',dpi=300,format='png') plt.show() plt.close() print('Result saved into 05_overfittingCheck.png') ``` ![](https://i.imgur.com/AOaeG42.png) ```python= #新增Dropout from keras.layers.core import Dropout model_adam=Sequential() model_adam.add(Dense(128,input_dim=200)) model_adam.add(Activation('relu')) model_adam.add(Dropout(0.4)) model_adam.add(Dense(256)) model_adam.add(Activation('relu')) model_adam.add(Dropout(0.4)) model_adam.add(Dense(5)) model_adam.add(Activation('softmax')) # Visualize the loss and accuracy of both models import matplotlib.pyplot as plt plt.figure(0,figsize=(8,6)) plt.subplot(121) plt.plot(range(len(loss_adam)), loss_adam,label='Training') plt.plot(range(len(val_loss_adam)), val_loss_adam,label='Validation') plt.title('Loss') plt.xlabel("epoch") plt.legend(loc='upper left') plt.subplot(122) plt.plot(range(len(acc_adam)), acc_adam,label='Training') plt.plot(range(len(val_acc_adam)), val_acc_adam,label='Validation') plt.title('Accuracy') plt.xlabel("epoch") plt.tight_layout() plt.savefig('08_dropout.png',dpi=300,format='png') plt.show() plt.close() print('Result saved into 08_dropout.png') ``` ![](https://i.imgur.com/IEfezUM.png) ```python= import cv2 cap=cv2.VideoCapture(0) #影片尺寸 # width=960 # height=780 # cap.set(cv2.CAP_PROP_FRAME_WIDTH,width) # cap.set(cv2.CAP_PROP_FRAME_HEIGHT,height) sz=(int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))) fps=20 fourcc=cv2.VideoWriter_fourcc(*'mp4v') vout= cv2.VideoWriter() vout.open('output.mp4',fourcc,fps,sz,True) cnt=1 while cnt < 201: _,frame=cap.read() cv2.putText(frame,str(cnt),(10,20),cv2.FONT_HERSHEY_PLAIN,1,(0,255,0),1,cv2.LINE_AA) vout.write(frame) cnt+=1 cv2.imshow('video',frame) cv2.waitKey(30) vout.release() cap.release() ``` 抓取鏡頭錄影 ```python= import cv2 ##開啟攝像頭 cap = cv2.VideoCapture(0) # 設定影像尺寸 width = 960 height = 780 # 設定擷取影像的尺寸大小 cap.set(cv2.CAP_PROP_FRAME_WIDTH, width) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height) ##視訊大小設定,獲取幀寬度,獲取幀高度 sz = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))) fps = 20 # 輸出格式 fourcc = cv2.VideoWriter_fourcc(*'mp4v') # 使用 XVID 編碼 #fourcc = cv2.VideoWriter_fourcc(*'XVID') #影片常見編碼格式:DIVX、XVID、MJPG、X264、WMV1、WMV2 mp4v ##open and set props vout = cv2.VideoWriter() vout.open('output.mp4', fourcc, fps, sz, True) cnt = 1 while cnt < 201: _, frame = cap.read() ##putText輸出到視訊上,各引數依次是:照片/新增的文字/左上角座標/字型/字型大小/顏色/字型粗細 cv2.putText(frame, str(cnt), (10, 20), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 0), 1, cv2.LINE_AA) vout.write(frame) cnt += 1 cv2.imshow('vidio', frame) cv2.waitKey(30) vout.release() cap.release() ``` ```python= import cv2 import numpy as np # 開啟網路攝影機 cap = cv2.VideoCapture(0) # 設定影像尺寸 width = 960 height = 780 # 設定擷取影像的尺寸大小 cap.set(cv2.CAP_PROP_FRAME_WIDTH, width) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height) # 計算畫面面積 area = width * height # 初始化平均影像 ret, frame = cap.read() avg = cv2.blur(frame, (4, 4))#圖片平滑模糊化 avg_float = np.float32(avg) while(cap.isOpened()): # 讀取一幅影格 ret, frame = cap.read() # 若讀取至影片結尾,則跳出 if ret == False: break # 模糊處理 blur = cv2.blur(frame, (4, 4)) # 計算目前影格與平均影像的差異值 diff = cv2.absdiff(avg, blur) # 將圖片轉為灰階 gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY) # 篩選出變動程度大於門檻值的區域 ret, thresh = cv2.threshold(gray, 25, 255, cv2.THRESH_BINARY) # 使用型態轉換函數去除雜訊 kernel = np.ones((5, 5), np.uint8) thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2) thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2) # 產生等高線 cntImg, cnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for c in cnts: # 忽略太小的區域 if cv2.contourArea(c) < 2500: continue # 偵測到物體,可以自己加上處理的程式碼在這裡... # 計算等高線的外框範圍 (x, y, w, h) = cv2.boundingRect(c) # 畫出外框 cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) # 畫出等高線(除錯用) cv2.drawContours(frame, cnts, -1, (0, 255, 255), 2) # 顯示偵測結果影像 cv2.imshow('frame', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break # 更新平均影像 cv2.accumulateWeighted(blur, avg_float, 0.01) avg = cv2.convertScaleAbs(avg_float) cap.release() cv2.destroyAllWindows() ``` 回家作業 合併兩個 ```python= #抓人臉並框起來 import cv2 face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') img = cv2.imread('a.jpeg') gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray,scaleFactor=1.08,minNeighbors=5,minSize=(32,32)) for (x,y,w,h) in faces: cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2) cv2.namedWindow('img',cv2.WINDOW_NORMAL) cv2.imshow('img',img) cv2.imwrite('result.jpg',img) cv2.waitKey(0) cv2.destroyAllWindows() ``` ![](https://i.imgur.com/hYrQqt2.jpg) 但還是有問題 因為還有便是錯誤的問題 ```python= import requests from json import JSONDecoder def compareimage(filepath1 ,filepath2): #人臉比對 try: http_url = "https://api-cn.faceplusplus.com/facepp/v3/compare" key = "SIAoSmoNSyaGC5gVZEWlwe323fnA2oi3" secret = "oTwQw3CbdkDL-nFVtAeGz53bE-OdU15c" data = {"api_key":key, "api_secret": secret} files = {"image_file1": open(filepath1, "rb"),"image_file2": open(filepath2, "rb")} response = requests.post(http_url, data=data, files=files) #進行辨識 req_con = response.content.decode('utf-8') #取得結果 req_dict = JSONDecoder().decode(req_con) #將結果轉為字典 confidence = req_dict['confidence'] #取得相似度指數 return confidence except Exception: print("產生錯誤,無法識別!") return 0 def showcompare(filepath1 ,filepath2): result = compareimage(filepath1 ,filepath2) print('相似度指數=' + str(result)) if result >= 75: print(filepath1+' 和 '+filepath2+' 為同一人!') else: print(filepath1+' 和 '+filepath2+' 為不同人!') showcompare('media/David1.jpg', 'media/face1.jpg') showcompare('media/jeng1.jpg', 'media/face1.jpg') ``` 相似度指數=39.54 media/David1.jpg和media/face1.jpg為不同人! 相似度指數=93.154 media/jeng1.jpg和media/face1.jpg為同一人! ```python= import requests from json import JSONDecoder import tkinter as tk from tkinter import filedialog def compareimage(filepath1 ,filepath2): #人臉比對 try: http_url = "https://api-cn.faceplusplus.com/facepp/v3/compare" key = "LDFvYGZWrSy3w1rwuQ_TAlKlK1HisylS" secret = "D4SxZ8wT4t6RCyqI5fI9E3rgKO93EbEM" data = {"api_key":key, "api_secret": secret} files = {"image_file1": open(filepath1, "rb"),"image_file2": open(filepath2, "rb")} response = requests.post(http_url, data=data, files=files) #進行辨識 req_con = response.content.decode('utf-8') #取得結果 req_dict = JSONDecoder().decode(req_con) #將結果轉為字典 confidence = req_dict['confidence'] #取得相似度指數 return confidence except Exception: print("產生錯誤,無法識別!") return 0 def showcompare(filepath1 ,filepath2): result = compareimage(filepath1 ,filepath2) print('相似度指數=' + str(result)) if result >= 75: print(filepath1+' 和 '+filepath2+' 為同一人!') else: print(filepath1+' 和 '+filepath2+' 為不同人!') #檔案選擇 import tkinter as tk from tkinter import filedialog def loadfiles(): root = tk.Tk() root.withdraw() file_path = filedialog.askopenfilename() return file_path file_path1 = loadfiles() file_path2 = loadfiles() showcompare(file_path1,file_path2) #暫停畫面 import os os.system("pause") ``` ```python= import requests from json import JSONDecoder def compareimage(filepath1,filepath2): try: http_url = "https://api-cn.faceplusplus.com/facepp/v3/compare" key = "SIAoSmoNSyaGC5gVZEWlwe323fnA2oi3" secret = "oTwQw3CbdkDL-nFVtAeGz53bE-OdU15c" data = {"api_key":key,"api_secret":secret} files = {"image_file1":open(filepath1,"rb"),"image_file2":open(filepath2,"rb")} response = requests.post(http_url,data=data,files=files) req_con = response.content.decode('utf-8') req_dict = JSONDecoder().decode(req_con) confidence = req_dict['confidence'] return confidence except Exception: print('產生錯誤,無法識別!') return 0 def login(filepath): success = False for img in imagelibrary: print(imagelibrary[img]) if compareimage(imagelibrary[img],filepath)>=75: print('登入成功!你是:',img) seccess = True break if not success: print('登入失敗!') print("==============================") imagelibrary = {'Lily':'memberPic/Lily.jpg', 'David':'memberPic/David.jpg', 'Bear':'memberPic/Bear.jpg', 'Cynthia':'memberPic/Cynthia.jpg', 'jeng':'memberPic/jeng.jpg'} login('media/face2.jpg') login('media/emmy1.jpg') ``` memberPic/Lily.jpg memberPic/David.jpg 產生錯誤,無法識別! memberPic/Bear.jpg 登入成功!你是: Bear 登入失敗! ============================== memberPic/Lily.jpg memberPic/David.jpg memberPic/Bear.jpg memberPic/Cynthia.jpg memberPic/jeng.jpg 登入失敗! ============================== ```python= #新增資料庫 import sqlite3 conn = sqlite3.connect('member_local.sqlite') cursor = conn.cursor() sqlstr = 'CREATE TABLE IF NOT EXISTS membertext("memberid" TEXT,"picture" TEXT)' cursor.execute(sqlstr) sqlstr = 'CREATE TABLE IF NOT EXISTS logintext("memberid" TEXT,"Itime" TEXT)' cursor.execute(sqlstr) conn.commit() conn.close() ``` https://hackmd.io/8DBZb5YBSdia8perdLFUVQ