# OpenCV Part2
## 螢幕手寫繪圖 OCR
```python=
```
## 螢幕手寫繪圖 OCR + CNN 模型
```python=
```
## 二質化
* 目的 : 降低變化,只是要取得外觀
* 結論 : 端看要辨識的物品,如果沒有要辨識顏色或複雜細項,畫素能小就小,能二質化就二質化
```python=
```
### opencv + cnn 實作辨識
```python=
# 步驟1 : 模型訓練
from sklearn.model_selection import train_test_split # 匯入 sklearn 用於分割訓練和測試數據
import glob # 匯入 glob 模組,用於檔案模式匹配
import numpy as np # 匯入 NumPy 庫,用於數據處理
import os.path as path # 匯入 os.path 模組,用於處理路徑
import os # 匯入 os 模組,用於操作檔案和目錄
import cv2 # 匯入 OpenCV 庫,用於影像處理
import tensorflow as tf # ��入 TensorFlow ��,用於建立深度�
# 定義影像所在的目錄路徑
IMAGEPATH = 'C:\\openCV\\images'
# 獲取 IMAGEPATH 目錄下的所有子目錄名稱(每個子目錄代表一個類別)
dirs = os.listdir(IMAGEPATH)
# 初始化空列表,用於存放影像資料和標籤
X = []
Y = []
print(dirs) # 輸出子目錄名稱列表
i = 0 # 初始化標籤計數器
# 遍歷每個子目錄(每個子目錄代表一個類別)
for name in dirs:
# 獲取子目錄下所有影像檔案的完整路徑
file_paths = glob.glob(path.join(IMAGEPATH + "/" + name, '*.*'))
# 遍歷每個影像檔案
for path3 in file_paths:
img = cv2.imread(path3) # 讀取影像
img = cv2.resize(img, (224, 224), interpolation=cv2.INTER_AREA) # 調整影像大小至 224x224
im_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 將影像從 BGR 轉換為 RGB 格式
X.append(im_rgb) # 將影像資料添加到 X 列表中
Y.append(i) # 將影像的標籤(對應子目錄的索引)添加到 Y 列表中
i = i + 1 # 每處理完一個子目錄,將標籤計數器加一
# 將影像資料和標籤列表轉換為 NumPy 陣列
X = np.asarray(X)
Y = np.asarray(Y)
# 將影像資料轉換為浮點型,並進行標準化處理
X = X.astype('float32')
X = X / 255 # 將像素值歸一化至 [0, 1] 範圍
h=224
w=224
# 將影像資料重塑為 (樣本數量, 224, 224, 3),3 代表 RGB 三個頻道
X = X.reshape(X.shape[0], h, w, 3)
# 獲取分類數目,即子目錄的數量
category = len(dirs)
# 獲取影像的維度
dim = X.shape[1]
# 將資料集分為訓練集和測試集,測試集佔 5%
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.05)
# 輸出訓練集的資料形狀
print(x_train.shape)
print(y_train.shape)
X = X.astype('float32')
X=X/255
X=X.reshape(X.shape[0],h,w,3)
category=len(dirs)
dim=X.shape[1]
x_train , x_test , y_train , y_test = train_test_split(X,Y,test_size=0.05)
# 將數字轉為 One-hot 向量
y_train2 = tf.keras.utils.to_categorical(y_train, category)
y_test2 = tf.keras.utils.to_categorical(y_test, category)
# 載入資料(將資料打散,放入 train 與 test 資料集)
print(x_train.shape)
datagen = tf.keras.preprocessing.image.ImageDataGenerator(
rotation_range=25 ,
width_shift_range=[-3,3],
height_shift_range=[-3,3] ,
zoom_range=0.3 ,
data_format='channels_last')
# 建立模型
model = tf.keras.models.Sequential()
# 加入 2D 的 Convolution Layer,接著一層 ReLU 的 Activation 函數
model.add(tf.keras.layers.Conv2D(filters=32, kernel_size=(3, 3),
padding="same",
activation='relu',
input_shape=(h,w,3)))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(50, activation='relu'))
model.add(tf.keras.layers.Dense(units=category,
activation=tf.nn.softmax ))
learning_rate = 0.001
opt1 = tf.keras.optimizers.Adam(learning_rate=learning_rate)
model.compile(
optimizer=opt1,
loss=tf.keras.losses.categorical_crossentropy,
metrics=['accuracy'])
model.summary()
"""
with open("model_ImageDataGenerator_myImage.json", "w") as json_file:
json_file.write(model.to_json())
try:
with open('model_ImageDataGenerator_myImage.h5', 'r') as load_weights:
model.load_weights("model_ImageDataGenerator_myImage.h5")
except IOError:
print("File not exists")
"""
#checkpoint = tf.keras.callbacks.ModelCheckpoint("model_ImageDataGenerator_myImage.weights.keras", monitor='loss', verbose=1,
# save_best_only=True, mode='auto', save_freq=1)
# 訓練模型
trainData=datagen.flow(x_train,y_train2,batch_size=64)
history = model.fit(trainData,
epochs=100,
# callbacks=[checkpoint]
)
#保存模型權重
model.save_weights("model_ImageDataGenerator_myImage.weights.h5")
#測試
score = model.evaluate(x_test, y_test2, batch_size=128)
# 輸出結果
print("score:",score)
predict = model.predict(x_test)
print("Ans:",np.argmax(predict[0]),np.argmax(predict[1]),np.argmax(predict[2]),np.argmax(predict[3]))
# predict2 = model.predict_classes(x_test)
predict2 = np.argmax(predict, axis=1)
print("predict_classes:",predict2)
print("y_test",y_test[:])
for t1 in predict2:
print(dirs[t1])
img=x_test[0]
img=img.reshape(h,w,3)
img=img*255
img = img.astype('uint8')
img = cv2.resize(img, (224, 224), interpolation=cv2.INTER_AREA)
im_bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
i = np.argmax(predict[0])
str1 = dirs[i] + " " + str(predict[0][i])
print(str1)
im_bgr = cv2.putText(im_bgr, str1, (10,30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,0, 0), 1, cv2.LINE_AA)
cv2.imshow('image', im_bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
```python=
步驟2 : 執行opencv 進行辨識
import tensorflow as tf
import cv2
import numpy as np
import os.path as path
import os
import time
IMAGEPATH = 'C:\\openCV\\images'
dirs = os.listdir(IMAGEPATH)
"""
json_file = open('model_ImageDataGenerator_myImage.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
model = tf.keras.models.model_from_json(loaded_model_json)
"""
h=224
w=224
category = len(dirs)
# 建立模型
model = tf.keras.models.Sequential()
# 加入 2D 的 Convolution Layer,接著一層 ReLU 的 Activation 函數
model.add(tf.keras.layers.Conv2D(filters=32, kernel_size=(3, 3),
padding="same",
activation='relu',
input_shape=(h,w,3)))
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(50, activation='relu'))
model.add(tf.keras.layers.Dense(units=category,
activation=tf.nn.softmax ))
model.compile(loss=tf.keras.losses.categorical_crossentropy,
optimizer=tf.keras.optimizers.Adadelta(),
metrics=['accuracy'])
model.load_weights("model_ImageDataGenerator_myImage.weights.h5")
model.summary()
url="http://172.19.106.80:4747/video"
cap = cv2.VideoCapture(url)
# while(True):
# ret, img = cap.read()
# if ret==True:
# resized = cv2.resize(img, (224, 224), interpolation=cv2.INTER_AREA)
# image = cv2.cvtColor(resized, cv2.COLOR_BGR2RGB)
# print(image.shape)
# image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
# predict = model.predict(image)
# i=np.argmax(predict[0])
# str1 =dirs[i] +" "+str(predict[0][i])
# print(str1)
# img = cv2.putText(img, str1, (30, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0),2,cv2.LINE_AA)
# cv2.imshow('image',img)
# # time.sleep(5)
# if cv2.waitKey(50) & 0xFF == ord('q'):
# break
# cap.release()
# cv2.destroyAllWindows()
# start_recognition = False # 初始化為 False,表示尚未開始辨識
# while True:
# ret, img = cap.read()
# if ret == True:
# key = cv2.waitKey(50) & 0xFF
# if key == ord('c'):
# resized = cv2.resize(img, (224, 224), interpolation=cv2.INTER_AREA)
# image = cv2.cvtColor(resized, cv2.COLOR_BGR2RGB)
# print(image.shape)
# image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
# predict = model.predict(image)
# i = np.argmax(predict[0])
# str1 = dirs[i] + " " + str(predict[0][i])
# print(str1)
# img = cv2.putText(img, str1, (30, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)
# cv2.imshow('image', img)
# if key == ord('q'):
# break
# cap.release()
# cv2.destroyAllWindows()
freeze_frame = False # 初始化為 False,表示畫面未凍結
while True:
if not freeze_frame: # 當畫面未凍結時,讀取新的影像
ret, img = cap.read()
if ret == True:
key = cv2.waitKey(50) & 0xFF # 檢查是否有按鍵輸入
if key == ord('c') and not freeze_frame: # 當按下C鍵且畫面未凍結時進行辨識
resized = cv2.resize(img, (224, 224), interpolation=cv2.INTER_AREA) # 調整影像大小
image = cv2.cvtColor(resized, cv2.COLOR_BGR2RGB) # 將影像轉換為RGB格式
print(image.shape) # 輸出影像的形狀資訊
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2])) # 重新塑形以符合模型輸入
predict = model.predict(image) # 執行模型預測
i = np.argmax(predict[0]) # 找出預測結果中機率最高的類別
str1 = dirs[i] + " " + str(predict[0][i]) # 構建顯示的文字訊息
print(str1) # 輸出辨識結果
img = cv2.putText(img, str1, (30, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA) # 在影像上顯示結果
freeze_frame = True # 當按下C鍵後,凍結畫面
cv2.imshow('image', img) # 顯示影像
if key == ord('c') and freeze_frame: # 再次按下C鍵時,解除凍結,準備讀取下一幀影像
freeze_frame = False
if key == ord('q'):
break # 按下Q鍵結束程式
cap.release() # 釋放攝影機資源
cv2.destroyAllWindows() # 關閉所有OpenCV視窗
```


## 多物件影像辨識
### HSL HSV
* 目的 把顏色與物體拆分
> 多物件
> 
參數不會調整,主要是返回值
> 找特徵物件
> 只要是黑色或是白色的邊緣都可以找到輪廓
> 如果是在流水線上面的檢驗,盡量讓背景是差異很大,例如 動畫綠背景,就是為了這個目的
> 
>算面積
>
> 寫字
> 框起來
可以透過程式加上及時調整參數方式,找到最好的參數
```python=
# part1
#!/usr/bin/env python
# author: Powen Ko 柯博文老師 www.powenko.com
# -*- coding: utf-8 -*-
from sklearn.model_selection import train_test_split # 匯入 sklearn 用於分割訓練和測試數據
import glob # 匯入 glob 模組,用於檔案模式匹配
import numpy as np # 匯入 NumPy 庫,用於數據處理
import os.path as path # 匯入 os.path 模組,用於處理路徑
import os # 匯入 os 模組,用於操作檔案和目錄
import cv2 # 匯入 OpenCV 庫,用於影像處理
import tensorflow as tf # 匯入 TensorFlow 庫,用於建立深度學習模型
# 定義影像所在的目錄路徑
IMAGEPATH = 'images'
# 獲取 IMAGEPATH 目錄下的所有子目錄名稱(每個子目錄代表一個類別)
dirs = os.listdir(IMAGEPATH)
# 初始化空列表,用於存放影像資料和標籤
X = []
Y = []
print(dirs) # 輸出子目錄名稱列表
i = 0 # 初始化標籤計數器
# 遍歷每個子目錄(每個子目錄代表一個類別)
for name in dirs:
# 獲取子目錄下所有影像檔案的完整路徑
file_paths = glob.glob(path.join(IMAGEPATH + "/" + name, '*.*'))
# 遍歷每個影像檔案
for path3 in file_paths:
img = cv2.imread(path3) # 讀取影像
img = cv2.resize(img, (224, 224), interpolation=cv2.INTER_AREA) # 調整影像大小至 224x224
im_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 將影像從 BGR 轉換為 RGB 格式
X.append(im_rgb) # 將影像資料添加到 X 列表中
Y.append(i) # 將影像的標籤(對應子目錄的索引)添加到 Y 列表中
i = i + 1 # 每處理完一個子目錄,將標籤計數器加一
# 將影像資料和標籤列表轉換為 NumPy 陣列
X = np.asarray(X)
Y = np.asarray(Y)
# 將影像資料轉換為浮點型,並進行標準化處理
X = X.astype('float32')
X = X / 255 # 將像素值歸一化至 [0, 1] 範圍
h = 224 # 設定影像的高度
w = 224 # 設定影像的寬度
# 將影像資料重塑為 (樣本數量, 224, 224, 3),3 代表 RGB 三個頻道
X = X.reshape(X.shape[0], h, w, 3)
# 獲取分類數目,即子目錄的數量
category = len(dirs)
# 獲取影像的維度
dim = X.shape[1]
# 將資料集分為訓練集和測試集,測試集佔 5%
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.05)
# 輸出訓練集的資料形狀
print(x_train.shape)
print(y_train.shape)
# 再次將影像資料轉換為浮點型,並進行標準化處理(多餘的步驟,已在上面處理過)
X = X.astype('float32')
X = X / 255 # 將像素值歸一化至 [0, 1] 範圍
X = X.reshape(X.shape[0], h, w, 3) # 重塑影像資料為 (樣本數量, 224, 224, 3)
category = len(dirs) # 獲取分類數目
dim = X.shape[1] # 獲取影像的維度
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.05) # 分割資料集
# 將數字標籤轉為 One-hot 向量
y_train2 = tf.keras.utils.to_categorical(y_train, category)
y_test2 = tf.keras.utils.to_categorical(y_test, category)
# 建立資料增強器,用於在訓練過程中進行影像增強
datagen = tf.keras.preprocessing.image.ImageDataGenerator(
rotation_range=25, # 影像隨機旋轉角度
width_shift_range=[-3, 3], # 影像隨機水平平移範圍
height_shift_range=[-3, 3], # 影像隨機垂直平移範圍
zoom_range=0.3, # 影像隨機縮放範圍
data_format='channels_last' # 指定資料格式為 channels_last (即 (height, width, channels))
)
# 建立模型
model = tf.keras.models.Sequential()
# 加入 2D 的 Convolution Layer,使用 ReLU 激活函數
model.add(tf.keras.layers.Conv2D(filters=32, kernel_size=(3, 3),
padding="same",
activation='relu',
input_shape=(h, w, 3)))
# 將多維度的輸出轉為一維
model.add(tf.keras.layers.Flatten())
# 加入全連接層,包含 50 個神經元,使用 ReLU 作為激活函數
model.add(tf.keras.layers.Dense(50, activation='relu'))
# 最後一層使用 softmax 激活函數進行分類,輸出單元數與分類數相同
model.add(tf.keras.layers.Dense(units=category,
activation=tf.nn.softmax))
# 設定學習率
learning_rate = 0.001
opt1 = tf.keras.optimizers.Adam(learning_rate=learning_rate)
# 編譯模型,使用 categorical_crossentropy 作為損失函數,評估指標為準確率
model.compile(
optimizer=opt1,
loss=tf.keras.losses.categorical_crossentropy,
metrics=['accuracy'])
# 輸出模型摘要資訊
model.summary()
# 準備訓練資料
trainData = datagen.flow(x_train, y_train2, batch_size=64)
# 訓練模型
history = model.fit(trainData,
epochs=100) # 設定訓練的迭代次數為 100 次
# 保存模型權重
model.save_weights("model_ImageDataGenerator_myImage.weights.h5")
# 測試模型
score = model.evaluate(x_test, y_test2, batch_size=128)
# 輸出結果
print("score:", score)
# 進行預測
predict = model.predict(x_test)
print("Ans:", np.argmax(predict[0]), np.argmax(predict[1]), np.argmax(predict[2]), np.argmax(predict[3]))
# 將預測結果轉為標籤類別
predict2 = np.argmax(predict, axis=1)
print("predict_classes:", predict2)
print("y_test", y_test[:])
for t1 in predict2:
print(dirs[t1])
# 顯示測試影像及其預測結果
img = x_test[0] # 取出第一張測試影像
img = img.reshape(h, w, 3) # 重塑影像為原本形狀
img = img * 255 # 將歸一化的影像像素值還原
img = img.astype('uint8') # 轉換資料型別為 unsigned 8-bit integer
img = cv2.resize(img, (224, 224), interpolation=cv2.INTER_AREA) # 調整影像大小
im_bgr = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) # 將影像從 RGB 轉換回 BGR 格式(OpenCV 使用 BGR)
i = np.argmax(predict[0]) # 獲取預測結果的最大值索引
str1 = dirs[i] + " " + str(predict[0][i]) # 組合顯示文字
print(str1)
im_bgr = cv2.putText(im_bgr, str1, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 1, cv2.LINE_AA) # 在影像上顯示文字
cv2.imshow('image', im_bgr) # 顯示影像
cv2.imshow('image', im_bgr) # 顯示影像窗口
cv2.waitKey(0) # 等待鍵盤輸入,防止窗口自動關閉
cv2.destroyAllWindows() # 關閉所有 OpenCV 窗口
```
```python=
#part2
#!/usr/bin/env python
# -*- coding=utf-8 -*-
__author__ = "柯博文老師 Powen Ko, www.powenko.com"
import numpy as np
import cv2
import os
import tensorflow as tf
# 定義影像所在的目錄路徑
IMAGEPATH = 'images'
# 獲取 IMAGEPATH 目錄下的所有子目錄名稱(每個子目錄代表一個類別)
dirs = os.listdir(IMAGEPATH)
# 設定影像高度和寬度
h = 224
w = 224
# 獲取分類數目,即子目錄的數量
category = len(dirs)
# 建立模型
model = tf.keras.models.Sequential()
# 加入 2D 的 Convolution Layer,接著一層 ReLU 的 Activation 函數
model.add(tf.keras.layers.Conv2D(filters=32, kernel_size=(3, 3),
padding="same",
activation='relu',
input_shape=(h, w, 3)))
# 將多維度的輸出轉為一維
model.add(tf.keras.layers.Flatten())
# 加入全連接層,包含 50 個神經元,使用 ReLU 作為激活函數
model.add(tf.keras.layers.Dense(50, activation='relu'))
# 最後一層使用 softmax 激活函數進行分類,輸出單元數與分類數相同
model.add(tf.keras.layers.Dense(units=category,
activation=tf.nn.softmax ))
# 設定學習率
learning_rate = 0.001
opt1 = tf.keras.optimizers.Adam(learning_rate=learning_rate)
# 編譯模型,使用 categorical_crossentropy 作為損失函數,評估指標為準確率
model.compile(
optimizer=opt1,
loss=tf.keras.losses.categorical_crossentropy,
metrics=['accuracy'])
# 輸出模型摘要資訊
model.summary()
# 讀取已訓練的權重
model.load_weights("model_ImageDataGenerator_myImage.weights.h5")
# 定義 CNN 模型的預測函數
def CNNPredict(img):
# 調整影像大小為模型要求的大小
resized = cv2.resize(img, (224, 224), interpolation=cv2.INTER_AREA)
# 轉換影像顏色為 RGB
image = cv2.cvtColor(resized, cv2.COLOR_BGR2RGB)
# 重塑影像為符合模型輸入格式的四維陣列
image = image.reshape((1, image.shape[0], image.shape[1], image.shape[2]))
# 使用模型進行預測
predict2 = model.predict(image)
return predict2
# 初始化計數器與影像寬度
counter = 0
w2 = 640
# 定義調整面積閾值的函數
def update_area_threshold(val):
global area_threshold
area_threshold = val
# 定義調整 threshold 閾值的函數
def update_threshold(val):
global threshold_value
threshold_value = val
# 初始化 OpenCV 視訊捕捉裝置
cap = cv2.VideoCapture(0)
# 建立 OpenCV 視窗與 trackbar
cv2.namedWindow('Objects Detected')
cv2.createTrackbar('Area Threshold', 'Objects Detected', 2000, 40000, update_area_threshold)
cv2.createTrackbar('Threshold', 'Objects Detected', 0, 255, update_threshold)
# 初始化閾值
area_threshold = 2236
threshold_value = 46
while(True):
# 讀取攝影機畫面
ret, rawImage = cap.read()
if ret == True:
# 調整影像大小,保持寬度為 w2,且保持比例
resize = cv2.resize(rawImage, (w2, int(rawImage.shape[0] * w2 / rawImage.shape[1])), interpolation=cv2.INTER_AREA)
# 將影像從 BGR 轉為 HSV 色彩空間
hsv = cv2.cvtColor(resize, cv2.COLOR_BGR2HSV)
# 分割 HSV 影像的色調、飽和度與明度
hue, saturation, value = cv2.split(hsv)
# 進行二值化處理,使用 OTSU 方法自動決定最佳 threshold
retval, thresholded = cv2.threshold(saturation, threshold_value, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cv2.imshow('thresholded', thresholded)
# 使用中值濾波來去除噪點
medianFiltered = cv2.medianBlur(thresholded, 5)
# 找出影像中的輪廓
contours, hierarchy = cv2.findContours(medianFiltered, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contour_list = []
# 遍歷所有輪廓,並將面積大於指定值的輪廓加入列表
for contour in contours:
area = cv2.contourArea(contour)
if area > area_threshold:
contour_list.append(contour)
# 遍歷符合條件的輪廓,進行影像分類預測
for contour1 in contour_list:
contour_list_x = []
contour_list_y = []
# 取得輪廓的所有座標點
for xy in contour1:
contour_list_x.append(xy[0][0])
contour_list_y.append(xy[0][1])
# 找出輪廓的最小與最大座標點
x = x1 = min(contour_list_x)
y = y1 = min(contour_list_y)
x2 = max(contour_list_x)
y2 = max(contour_list_y)
# 使用模型進行預測
predict = CNNPredict(resize[y1:y2, x1:x2, :].copy())
# 畫出預測框
cv2.rectangle(resize, (x1, y1), (x2, y2), (0, 255, 0), 1)
# 獲得預測結果
i = np.argmax(predict[0])
# 組合顯示文字,包括類別名稱、預測機率與面積
str1 = dirs[i] + " ," + str(predict[0][i]) + " , " + str(cv2.contourArea(contour1))
# 顯示預測結果文字
cv2.putText(resize, str(str1), (x, y), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0))
# 畫出所有符合條件的輪廓
cv2.drawContours(resize, contour_list, -1, (255, 0, 0), 2)
# 顯示處理後的影像
cv2.imshow('Objects Detected', resize)
# 偵測按鍵,如果按下 'q' 或 'Esc' 鍵,則退出循環
key = cv2.waitKey(10)
if key & 0xFF == ord('q') or key == 27:
break
# 釋放攝影機並關閉所有視窗
cap.release()
cv2.destroyAllWindows()
```
### YOLO
> 先介紹opencv 的 haar cascades
> 進行局部人臉辨識

```python=
#v1
import numpy as np
import cv2
face_cascade = cv2.CascadeClassifier('C:\\03-haar\\haarcascades/haarcascade_frontalface_default.xml') #讀取權重檔
url="http://172.19.106.80:4747/video"
cap = cv2.VideoCapture(url)
while(True):
k=cv2.waitKey(1)
if k==27 or k == ord('q'): # 離開迴圈
break
ret, img = cap.read()
if img is not None:
img = cv2.resize(img, (640,480), interpolation = cv2.INTER_AREA)# 調整圖片大小
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 彩色轉灰階
faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=3, minSize=(100, 100), flags=cv2.CASCADE_SCALE_IMAGE) # 找物件
for (x, y, w, h) in faces: # 位置
img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) # 圈出臉的位置
cv2.imshow('img',img)
cap.release()
cv2.destroyAllWindows()
```
```python=
#v2
import numpy as np
import cv2
import datetime
import os
import time
# 讀取權重檔
cascade_path = 'C:\\opencv/haarcascade_frontalface_default.xml'
face_cascade = cv2.CascadeClassifier(cascade_path)
# 照片存檔路徑與權重檔案相同
save_directory = os.path.dirname(cascade_path)
# 開啟攝影機
cap = cv2.VideoCapture(0)
# 是否開始連續拍照的旗標
save_face = False
while(True):
k = cv2.waitKey(1)
if k == 27 or k == ord('q'): # 按下ESC或q鍵離開迴圈
break
elif k == ord('s'): # 按下s鍵後開始連續拍照
save_face = True
ret, img = cap.read()
if img is not None:
img = cv2.resize(img, (640, 480), interpolation=cv2.INTER_AREA) # 調整圖片大小
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 彩色轉灰階
faces = face_cascade.detectMultiScale(
gray,
scaleFactor=1.05, # 調整縮放係數,更細緻地檢測較小臉部
minNeighbors=3,
minSize=(50, 50), # 調整最小臉部大小以便檢測嬰兒臉部
flags=cv2.CASCADE_SCALE_IMAGE
) # 偵測臉部
for (x, y, w, h) in faces: # 取得臉部位置
img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) # 圈出臉的位置
if save_face:
# 取得臉部區域
face_img = img[y:y+h, x:x+w]
# 取得當前日期和時間,包括毫秒
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S_%f")
# 設定檔名並存檔到權重檔案相同路徑
filename = os.path.join(save_directory, f"face_{timestamp}.png")
cv2.imwrite(filename, face_img)
print(f"圖片已存檔為: {filename}")
# 每秒拍攝一張
time.sleep(1)
# 顯示圖片
cv2.imshow('img', img)
# 釋放攝影機資源並關閉視窗
cap.release()
cv2.destroyAllWindows()
```
### 專題做法
1. 先拍照透過haar抓臉,
2. 丟CNN訓練
3. 得到權重檔後,
4. 再透過haar 拍照抓臉,丟比對
> 用google colab執行人家的權重 與設定檔
### VOC
一個XML + JPG檔案

因為在做標籤時使用VOC,所以要將VOC型態轉yolo需要的型態

如果檔案有問題可以刪除或是修檔案

如果準度不理想可以調整這裡(訓練次數)

訓練完後最值錢的權重檔案

