iT邦幫忙

2021 iThome 鐵人賽

DAY 28
17
Software Development

奇怪的知識增加了!原來程式還可以這樣用?!系列 第 28

[Day28] 戲弄老闆! 教你用Machine Learning將老闆玩弄於股掌之間!

大家每上班摸魚的時候都很怕老闆突然出現在你後面對吧!
難道只能在辦公桌前放鏡子或聽音辨位,判斷老闆是否經過嗎?

今天要教大家用YOLOv4製作老闆來了裝乖神器
只要有人朝你方向走來,就會馬上關掉摸魚網頁,跳出技術文件!

開發工具

程式碼

import numpy as np
import cv2
import os
import imutils
import subprocess
import psutil
import time

NMS_THRESHOLD=0.3
MIN_CONFIDENCE=0.2

# 參考來源: https://data-flair.training/blogs/pedestrian-detection-python-opencv/
def pedestrian_detection(image, model, layer_name, personidz=0):
	(H, W) = image.shape[:2]
	results = []

	blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416),
		swapRB=True, crop=False)
	model.setInput(blob)
	layerOutputs = model.forward(layer_name)

	boxes = []
	centroids = []
	confidences = []

	for output in layerOutputs:
		for detection in output:

			scores = detection[5:]
			classID = np.argmax(scores)
			confidence = scores[classID]

			if classID == personidz and confidence > MIN_CONFIDENCE:

				box = detection[0:4] * np.array([W, H, W, H])
				(centerX, centerY, width, height) = box.astype("int")

				x = int(centerX - (width / 2))
				y = int(centerY - (height / 2))

				boxes.append([x, y, int(width), int(height)])
				centroids.append((centerX, centerY))
				confidences.append(float(confidence))
	idzs = cv2.dnn.NMSBoxes(boxes, confidences, MIN_CONFIDENCE, NMS_THRESHOLD)
    
	if len(idzs) > 0:
		for i in idzs.flatten():
			(x, y) = (boxes[i][0], boxes[i][1])
			(w, h) = (boxes[i][2], boxes[i][3])
			res = (confidences[i], (x, y, x + w, y + h), centroids[i])
			results.append(res)
	return results

# 讀入類別名稱
labelsPath = "coco.names"
LABELS = open(labelsPath).read().strip().split("\n")

# 讀入yolo-v4參數以及設定檔
weights_path = "yolov4-tiny.weights"
config_path = "yolov4-tiny.cfg"
model = cv2.dnn.readNetFromDarknet(config_path, weights_path)
layer_name = model.getLayerNames()
layer_name = [layer_name[i[0] - 1] for i in model.getUnconnectedOutLayers()]

# 針對筆電視訊影像進行偵測,也可改為其他影像來源
cap = cv2.VideoCapture(0)

while True:
    (grabbed, image) = cap.read()

    if not grabbed:
        break
    
    image = imutils.resize(image, width=700)
    results = pedestrian_detection(image, model, layer_name,
		personidz=LABELS.index("person"))

    # 畫出偵測到的每個方框
    for res in results:
	    cv2.rectangle(image, (res[1][0],res[1][1]), (res[1][2],res[1][3]), (0, 255, 0), 2)

    cv2.imshow("Detection",image)
    
    # 若當前影像中有兩個人以上,則關掉當前瀏覽器並開啟指定網站
    if len(results) >= 2:
        subprocess.Popen('taskkill /im chrome.exe')
        time.sleep(0.1)
        subprocess.Popen("start chrome https://docs.microsoft.com/zh-tw/sql/database-engine/availability-groups/windows/overview-of-always-on-availability-groups-sql-server?view=sql-server-2017",shell = True)
        break
        
    key = cv2.waitKey(1)
    if key == 27:
        break

cap.release()
cv2.destroyAllWindows()

成果發表會

(因為怕錄到影片內容會侵犯版權,所以只錄預告部分)

本來有想過要不要做只有偵測老闆長相的人臉辨識功能,但考量到被其他人看到在偷懶也不太好,
所以就統一設定偵測到任何人朝你走來時就關上偷懶網站。

就算老闆遠遠看到你好像在看什麼五彩繽紛的畫面,走進後也只會看到你在看技術文件,
而且你的手根本沒動過,老闆也只會覺得眼睛業障重,進而達到戲弄老闆的效果!

想要更早判斷老闆有沒有經過的話,也可以裝外接攝像頭在桌子邊增加判斷範圍喔~


上一篇
[Day27] 超萌❤ 教你用Python畫天竺鼠車車逗女友開心!
下一篇
[Day29] 不敢把聊天紀錄上傳到分析網站? 自己用Python分析LINE聊天紀錄!
系列文
奇怪的知識增加了!原來程式還可以這樣用?!31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
2
cheerupche
iT邦新手 5 級 ‧ 2021-09-28 12:41:32

笑死,相當實用XDDDDDD
但要一直開著鏡頭(??)

lulu_meat iT邦研究生 5 級 ‧ 2021-09-28 13:07:40 檢舉

是的,把視訊畫面最小化也可以偵測的到喔~

1
dscwferp
iT邦高手 1 級 ‧ 2021-09-28 13:33:03

Pedestrian Detection 拿來偵測背後靈!
很好的應用!
還可以拿來偵測"小偷"? 闖入警報?
加上拍照 後 用LINE NOTIFY 警告?

lulu_meat iT邦研究生 5 級 ‧ 2021-09-28 17:03:52 檢舉

如果要偵測小偷還是用人臉辨識比較好~

1
Molly
iT邦新手 5 級 ‧ 2021-09-28 15:50:50

好好笑XDD
超喜歡你的文章~~~

lulu_meat iT邦研究生 5 級 ‧ 2021-09-28 17:04:15 檢舉

謝謝Molly的支持!

1
obarisk
iT邦研究生 2 級 ‧ 2021-09-28 22:40:57

看起來很簡單. 抄起來不知道簡不簡單?

lulu_meat iT邦研究生 5 級 ‧ 2021-09-30 10:55:49 檢舉

要跟著連結的YoloV4訓練集一起下載喔~

obarisk iT邦研究生 2 級 ‧ 2021-10-01 11:08:19 檢舉

第二個連結那個嗎?
我也來弄土炮一個

1
gash5502
iT邦新手 5 級 ‧ 2021-09-30 19:16:16

可以玩成這樣真的太強了...

1
小妹
iT邦新手 5 級 ‧ 2021-10-24 01:49:57

太厲害了!
收藏起來哈哈阿哈~~

1
joe
iT邦新手 3 級 ‧ 2022-04-02 16:01:37

layer_name = [layer_name[i[0] - 1] for i in model.getUnconnectedOutLayers()]這行出錯了

要更改成layer_name = [layer_name[i-1] for i in model.getUnconnectedOutLayers()]

lulu_meat iT邦研究生 5 級 ‧ 2022-04-03 21:29:00 檢舉

謝謝Joe!!!

我要留言

立即登入留言