首頁>科技>

這是昨天收到的作者投稿,在iN的建議下就給大家改成了一個教程。

利用攝像頭和舵機組建的一隻人臉跟蹤大魔。只要你出現在它的視野中,這隻大摩頭就會一隻盯著你。

有一種 硝煙散盡 在廢墟里找到了一個大魔 只剩下頭 但眼睛還亮著的感覺……

那麼我們來看看這隻大摩頭是如何製作出來的:

作者的教程:

這個大魔源於一個我在寫的人臉追蹤的專案,做好了就像下面這個。

但是作為膠佬自然不會就這麼止步,所以就想到了把他美化一下,就想到了買一個大魔頭,然後把它裝在裡面。

接下來先教大家制作這個人臉追蹤平臺,成本不到100元。

需要的東西有:

舵機兩個 二軸雲臺一個 Arduino nano3開發板一個 usb攝像頭一個 usb線一根

網上買的雲臺品質不會很好,舵機可能不能很好的卡進去,所以要先把舵機打磨好,然後像下圖這樣組裝好。

舵機一共有三根線,黃色的是訊號線,紅色和褐色分別是正負極。如下圖所示。

我們將正負極的線剪斷,然後將兩個舵機的正極接在一起,負極接在一起,再剪斷一根沒用的usb線,usb線裡面也會有正負極線,對應的將正極接在一起,負極接在一起。這樣就可以通過usb向舵機供電了。

再將x軸的舵機訊號線接到arduino nano開發板的D8介面接到Y軸的舵機訊號線上,D9介面接到X軸的舵機訊號線上。

這樣硬體部分的連線就算完成了。

接下來就是向arduino nano燒錄程式了。

下載arduino的IDE

將arduino nano通過usb連線到電腦上。做如下配置,在工具中選擇開發板。

配置埠,我這裡是COM5,大家根據自己的實際情況選擇。

等待上傳完成。

最後將攝像頭連線到電腦上,開啟pycharm軟體,執行python人臉識別程式碼。

Python會將識別到的人臉的座標通過串列埠傳送給arduino nano開發板。開發板根據接收到的座標對舵機進行控制。

以上關於人臉追蹤的介紹就完成了。

下面就是大魔頭的做舊了。

首先把大魔頭的眼睛以下的部分全部掏空,然後打磨平整,保證大魔頭可以正好套在雲臺上。

然後在外甲加上傷痕,我沒有電動鋸,所以就用了三角形的銼刀,一點一點搓出來的傷口。隨後就是對動力管等上漆,這裡用的田宮的噴灌,金屬淺槍鐵色。

先在表面上一層消光,以免裂件。然後就是漬洗。我用了郡仕的鐵鏽色滲線液進行漬洗。

等漬洗液乾透,就可以用棉籤蘸取稀釋劑擦去多餘的漬洗液了。

然後幹掃、用面相筆蘸取黑色補充細節掉漆。

完成!

後面則是程式碼了:

Arduino 舵機驅動程式碼:

#include <Servo.h> // 宣告呼叫Servo.h庫Servo myservo; // 建立一個舵機物件Servo myservo1; // 建立一個舵機物件int posx = 60; // 變數pos用來儲存舵機位置int posy = 60; // 變數pos用來儲存舵機位置int c = 0;void setup() { Serial.begin(9600); myservo.attach(9); // 將引腳9上的舵機與宣告的舵機物件連線起來 myservo1.attach(8); // 將引腳9上的8機與宣告的舵機物件連線起來 myservo.write(posx); myservo1.write(posy);// 給舵機寫入角度}

void loop() { while(Serial.available()>0)//當有訊號的時候 { char val=Serial.read(); Serial.println(val); if(val=='0'){ //左上 if(posx -3>=60){ posx = posx -3; c = 1; } if(posy -2>=0){ posy = posy -2; c = 1; } }else if(val=='1'){ //右上 if(posx +3<=120){ posx = posx +3; c = 1; } if(posy -2>=60){ posy = posy -2; c = 1; } }else if(val=='2'){ //左下 if(posx -3>=0){ posx = posx -3; c = 1; } if(posy +2<=120){ posy = posy +2; c = 1; } }else if(val=='3'){ //右下 if(posx +3<=120){ posx = posx +3; c = 1; } if(posy +2<=120){ posy = posy +2; c = 1; } }else if(val=='4'){ //上 if(posy -2>=0){ posy = posy -2; c = 1; } }else if(val=='5'){ //左 if(posx -3>=0){ posx = posx -3; c = 1; } }else if(val=='6'){ //右 if(posx +3<=120){ posx = posx +3; c = 1; } }else if(val=='7'){ //下 if(posy +2<=120){ posy = posy +2; c = 1; } } if(c ==1){ Serial.println("dong"); myservo.write(posx); myservo1.write(posy);// 給舵機寫入角度 } c = 0; Serial.println(posx); Serial.println(val); } }

上位機(也就是我們的電腦)人臉識別程式碼:

#!Anaconda/anaconda/python

import dlib #人臉識別的庫dlibimport numpy as np #資料處理的庫numpyimport cv2 #影象處理的庫OpenCvfrom pyfirmata import Arduino, utilimport timeimport serial

class face_emotion():

def __init__(self): # 使用特徵提取器get_frontal_face_detector self.detector = dlib.get_frontal_face_detector() # dlib的68點模型,使用作者訓練好的特徵預測器 self.predictor = dlib.shape_predictor("./shape_predictor_68_face_landmarks.dat")

# 建cv2攝像頭物件,這裡使用電腦自帶攝像頭,如果接了外部攝像頭,則自動切換到外部攝像頭 self.cap = cv2.VideoCapture(0) # 設定視訊引數,propId設定的視訊引數,value設定的引數值 self.cap.set(3, 480) # 截圖screenshoot的計數器 self.cnt = 0 self.ser = serial.Serial() self.ser.baudrate = 9600 # 設定波特率 self.ser.port = "COM5" # 埠是COM3 self.ser.open() # 開啟串列埠

def learning_face(self): # cap.isOpened() 返回true/false 檢查初始化是否成功 while(self.cap.isOpened()):

# cap.read() # 返回兩個值: # 一個布林值true/false,用來判斷讀取視訊是否成功/是否到視訊末尾 # 影象物件,影象的三維矩陣 flag, im_rd = self.cap.read()

# 每幀資料延時1ms,延時為0讀取的是靜態幀 k = cv2.waitKey(1)

# 取灰度 gray = cv2.cvtColor(im_rd, cv2.COLOR_RGB2GRAY)

# 使用人臉檢測器檢測每一幀影象中的人臉。並返回人臉數rects faces = self.detector(img_gray, 0)

# 待會要顯示在螢幕上的字型 font = cv2.FONT_HERSHEY_SIMPLEX

# 如果檢測到人臉 if len(faces) != 0:

# 對每個人臉都標出68個特徵點 for i in range(len(faces)): # enumerate方法同時返回資料物件的索引和資料,k為索引,d為faces中的物件 for k, d in enumerate(faces):

cv2.rectangle(im_rd, (d.left(), d.top()), (d.right(), d.bottom()), (0, 0, 255)) fw(self, d.top(), d.bottom(), d.left(), d.right())

# 計算人臉熱別框邊長 self.face_width = d.right() - d.left()

# 標出人臉數 cv2.putText(im_rd, "Faces: "+str(len(faces)), (20,50), font, 1, (0, 0, 255), 1, cv2.LINE_AA) else: # 沒有檢測到人臉 cv2.putText(im_rd, "No Face", (20, 50), font, 1, (0, 0, 255), 1, cv2.LINE_AA)

# 視窗顯示 cv2.imshow("camera", im_rd)

# 釋放攝像頭 self.cap.release()

def fw(self, t, b, l, r):

y = (b - t) / 2 + t x = (r - l) / 2 + l print(str(t)+" "+str(b)+" "+str(l)+" "+str(r)) print(" " +str(x) + " " + str(y))

if x-280>=50 and abs(y-300)<=40: print("右") self.ser.write(b"5") elif x - 280 >= 50 and y - 300 >= 40: print("右下") self.ser.write(b"2") elif x - 280 >= 50 and y - 300<=-40: print("右上") self.ser.write(b"0") elif x - 280 <= -50 and abs(y-300)<=40: print("左") self.ser.write(b"6") elif x - 280 <= -50 and y-300<=-40: print("左上") self.ser.write(b"1") elif x - 280 <= -50 and y-300 >= 40: print("左下") self.ser.write(b"3") elif abs(x - 280) <= 50 and y-300>=40: print("下") self.ser.write(b"7") elif abs(x - 280) <= 50 and y-300<=-40: print("上") self.ser.write(b"4")

if __name__ == "__main__": my_face = face_emotion() my_face.learning_face()

最新評論
  • 整治雙十一購物亂象,國家再次出手!該跟這些套路說再見了
  • 中國移動,再見!13年的老使用者終於對你忍無可忍!