1. OpenCV學習
2. NODE-RED學習
3. MQTTx學習
4. STM32學習
5. STM32與NODE-RED結合
6. STM32與MQTT結合
學習參考影片
Learn More →
import cv2
img= cv2.imread('colorcolor.jpg') #讀取照片
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5) #改變一開始的圖片大小使其為原本的一半fx=0.5是指為原來的0.5倍
img = cv2.resize(img,(300,300)) #resize可以指定(300X300)改變一開始的圖片大小
cv2.imshow('img',img) #顯示叫IMG的圖片
cv2.waitKey(0) #等待時間(毫秒)
import cv2
cap = cv2.VideoCapture('thumb.mp4')#讀取影片
while True:
ret, fram= cap.read() #read會回傳兩個數一是有沒有成功取得下一張圖片(1:成功0:失敗)=ret;二是下一張圖片=fram
fram= cv2.resize(fram,(0,0),fx=0.4,fy=0.4)
if ret:
cv2.imshow('video',fram)
else:
break
if cv2.waitKey(1) == ord('q'):#等待時間按下Q結束影片
break
import cv2
cap = cv2.VideoCapture(0) #讀取影片若括號打0則使用電腦預設鏡頭
while True:
ret, fram= cap.read()#read會回傳兩個數一是有沒有成功取得下一張圖片(1:成功0:失敗)=ret;二是下一張圖片=fram
fram= cv2.resize(fram,(0,0),fx=0.4,fy=0.4)
if ret:
cv2.imshow('video',fram)
else:
break
if cv2.waitKey(1) == ord('q'):#等待時間按下Q結束影片
break
img = cv2.imread('colorcolor.jpg')
print(img.shape) #取得此img.shape陣列的大小 結果:(1015, 700, 3) 1015代表列有1015個[] 700代表每列裡包含700個[] 3代表700個[]裡的3個值 分別代表 B G R (0~255)
因為要使用陣列所以須引入import numpy as np
img = np.empty((300,300,3),np.uint8) #創建一陣列指定長寬並且顏色種類 np.uint8為正整數大小範圍2的8次方256
for row in range(300):
for col in range(300):
img[row][col]= [random.randint(0,255),random.randint(0,255),random.randint(0,255)]
cv2.imshow('img',img)
cv2.waitKey(0)
img = cv2.imread('colorcolor.jpg')
newimg = img[:150,200:400]#切成列0~150 行200~400
cv2.imshow('img',img)
cv2.imshow('newimg',newimg)
cv2.waitKey(0)
img= cv2.imread('colorcolor.jpg')
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5)
img_1 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #將BGR圖片變成灰階
img_2 = cv2.GaussianBlur(img,(3,3),0) #高斯模糊 工用去除雜訊 圖檔,合(基數),標準差
img_3 = cv2.Canny(img,100,400) #圖片輪廓描邊 (圖片,最低門檻值,最高門檻值) 解釋:若兩齡近像素點顏色落差太大就會形成輪廓 Canny將點評分若低於150則視為邊緣若高於200視為邊緣
kernel=np.ones((10, 10), np.uint8) #新建一陣列來當作我們dilate的合(kermel)
img_4 = cv2.dilate(img_3,kernel,iterations=1) #將突變輪廓變粗 (圖片,kernel合(二維陣列),變粗次數)
kernel1=np.ones((3, 3), np.uint8) #新建一陣列來當作我們erode的合(kermel)
img_5 = cv2.erode(img_4,kernel1,iterations=2) #將突變輪廓變系 (圖片,kernel合(二維陣列),變細次數)
# cv2.imshow('img',img)
# cv2.imshow('img_1',img_1)
# cv2.imshow('img_2',img_2)
cv2.imshow('img_3',img_3)
cv2.imshow('img_4',img_4)
cv2.imshow('img_5',img_5)
cv2.waitKey(0)
img = np.zeros((600,600,3),np.uint8) #新建多維振烈zreo代表都為0(黑色) (列,行,色種)
cv2.line(img,(0,0),(img.shape[1],img.shape[0]),(255,0,0),1) #畫直線 (檔案,線的點,線的點,顏色(BGR),粗度) #img.shap[1]可讀取圖片列的長度[0]則是寬
cv2.rectangle(img,(0,0),(300,300),(255,0,0),cv2.FILLED) #畫方形 (檔案,方形的點,方形的點,顏色(BGR),粗度) #img.FILLED 將圖形內填滿
cv2.circle(img,(300,400),30,(255,0,0),1) #畫圓形 (檔案,圓心,半徑,顏色(BGR),粗度)
cv2.putText(img,'hello',(100,500),cv2.FONT_HERSHEY_SIMPLEX,2,(255,0,0),2) #寫字 (檔案,起始點,字體,文字大小,顏色(BGR),粗度)NOTE:沒辦法支援中文
cv2.imshow('img',img)
cv2.waitKey(0)
img = cv2.imread('XiWinnie.jpg')
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5)
def empty(v):#下面定義的empty所回傳的值
pass
cv2.namedWindow('TrackBar')#建立一新視窗
cv2.resizeWindow('TrackBar', 640, 320)#視窗大小設定
cv2.createTrackbar('Hue Min', 'TrackBar', 0, 179, empty)#建立一控制條範圍是0~179 色調
cv2.createTrackbar('Hue Max', 'TrackBar', 179, 179, empty)#建立一控制條範圍是0~179 色調
cv2.createTrackbar('Sat Min', 'TrackBar', 0, 255, empty)#建立一控制條範圍是0~179 飽和度
cv2.createTrackbar('Sat Max', 'TrackBar', 255, 255, empty)#建立一控制條範圍是0~179 飽和度
cv2.createTrackbar('Val Min', 'TrackBar', 0, 255, empty)#建立一控制條範圍是0~179 亮度
cv2.createTrackbar('Val Max', 'TrackBar', 255, 255, empty)#建立一控制條範圍是0~179 亮度
hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)#將圖片轉換成HSV(色調,飽和度,亮度)
while True: #將控制條的值印出來
h_min = cv2.getTrackbarPos('Hue Min', 'TrackBar')
h_max = cv2.getTrackbarPos('Hue Max', 'TrackBar')
s_min = cv2.getTrackbarPos('Sat Min', 'TrackBar')
s_max = cv2.getTrackbarPos('Sat Max', 'TrackBar')
v_min = cv2.getTrackbarPos('Val Min', 'TrackBar')
v_max = cv2.getTrackbarPos('Val Max', 'TrackBar')
print(h_min, h_max, s_min, s_max, v_min, v_max)
#過濾顏色
lower = np.array([h_min,s_min,v_min])
upper = np.array([h_max,s_max,v_max])
mask = cv2.inRange(hsv,lower,upper)#過濾顏色(檔案,h、s、v的最小值,h、s、v的最大值# )
cv2.waitKey(1)
result=cv2.bitwise_and(img,img,mask=mask)#將圖片1與圖片2的每個bit做and運算 (圖片1,圖片2,遮罩) 將白色地方蓋回原圖
cv2.imshow('img',img)
cv2.imshow('hsv',hsv)
cv2.imshow('mask',mask)#白色為保留
cv2.imshow('result',result)#白色為保留
img = cv2.imread('shape.jpg')
imgContour=img.copy()#複製一張
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#將圖片轉為灰階因為判斷形狀並不需要顏色
canny = cv2.Canny(img,150,200)#圖片輪廓描邊 (圖片,最低門檻值,最高門檻值) 解釋:若兩齡近像素點顏色落差太大就會形成輪廓 Canny將點評分若低於150則視為邊緣若高於200視為邊緣
contours, hierarchy = cv2.findContours(canny,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)#偵測輪廓(圖片,使用模式(內、外、內外,輪廓),壓縮輪廓點) EXTERNAL:外輪廓
for cnt in contours:
cv2.drawContours(imgContour,cnt,-1,(255,0,0),4)#(畫的位置,要畫得輪廓,第幾個輪廓;都要(-1),顏色,粗度)
area=cv2.contourArea(cnt)#輪廓面積
if area > 500:
peri=cv2.arcLength(cnt,True)#輪廓邊長
vertices=cv2.approxPolyDP(cnt,peri * 0.02,True)
corners=len(vertices)#顯示輪廓的角數
x,y,w,h = cv2.boundingRect(vertices)#將每個多邊形用方形圈起來
cv2.rectangle(imgContour,(x,y),(x+w,y+h),(0,255,0),4)#畫方形 (檔案,方形的點,方形的點,顏色(BGR),粗度) #img.FILLED 將圖形內填滿
#判斷形狀
if corners ==3:
cv2.putText(imgContour,'triangle',(x,y-5),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,0),1)#寫字 (檔案,起始點,字體,文字大小,顏色(BGR),粗度)NOTE:沒辦法支援中文
elif corners==4:
cv2.putText(imgContour, 'rectangle', (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0),1) # 寫字 (檔案,起始點,字體,文字大小,顏色(BGR),粗度)NOTE:沒辦法支援中文
elif corners==5:
cv2.putText(imgContour, 'pentagon', (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0),1) # 寫字 (檔案,起始點,字體,文字大小,顏色(BGR),粗度)NOTE:沒辦法支援中文
elif corners>=6:
cv2.putText(imgContour, 'circle', (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0),1) # 寫字 (檔案,起始點,字體,文字大小,顏色(BGR),粗度)NOTE:沒辦法支援中文
cv2.imshow('img',img)
cv2.imshow('canny',canny)
cv2.imshow('imgContour',imgContour)
cv2.waitKey(0)
img = cv2.imread('qq.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faceCascade = cv2.CascadeClassifier('face_detect.xml')#載入訓練好的模型 (路徑)
faceRect = faceCascade.detectMultiScale(gray, 1.1, 5)#辨識人臉(圖片,下一次偵測縮圖倍率,被框到幾次為正確) 流程:偵測 縮小圖片 偵測 ....
for (x, y, w, h) in faceRect:
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow('img', img)
cv2.waitKey(0)
1.node-red工具
2.node-red上網抓資料
學習網址:https://tutorials.webduino.io/zh-tw/docs/socket/useful/node-red.html
inject | debug | |
---|---|---|
功能 | 輸入信號 | 輸出訊號 |
類似於 | 訊號產生器 | 示波器 |
範例Image Not Showing Possible ReasonsLearn More →
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
設定輸入節點屬性:
結果:
設計
部屬完後點右上角進入
參考網址:https://tutorials.webduino.io/zh-tw/docs/socket/useful/exchange-node-red.html
1.找需要的網頁並開啟原始碼
2.設計NODE-RED
3.找到要的資料(第幾行?)
4.輸出Image Not Showing Possible ReasonsLearn More →
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
原始碼:
閱讀網頁的原始碼我們可以得知現金的買入與賣出名稱為'rate-content-cash text-right print_hide'
編輯'http in'節點:
URL輸入要載入資料的網址(舉例:https://rate.bot.com.tw/xrt?Lang=zh-TW)
編輯'html'節點::
選取項要輸入要是篩選的資料名稱(rate-content-cash text-right print_hide)
deploy後並觸發後,到debug找尋需要的資料在哪一行:
編輯'function'節點:
將正確的那一個資訊抓出並打包送出
var massage = msg.payload[15];//輸入需要傳送行數
var date = new Date();
var h = date.getHours();
var m = date.getMinutes();
var s = date.getSeconds();
if (h < 10) {
h = '0' + h;
}
if (m < 10) {
m = '0' + m;
}
if (s < 10) {
s = '0' + s;
}
msg.payload = '(' + h + ':' + m + ':' + s + ')\n' +
'日幣匯率:' + massage;
return msg;
新增頁面:
服務器位置使用'test.mosquitto.org'
連線頁面:
QOS是傳輸檔案的重要分級,數字越大越重
訂閱 | 發布 | |
---|---|---|
意思 | 輸入資料 | 輸出資料 |
類似於 | 到公佈欄抓資料回來 | 張貼資料到公布欄 |
1.IO例題
2.LCD模組
3.ESP32連上WIFI
4.抓取網路資料至ESP32
設定額外開發管理員:
https://github.com/espressif/arduino-esp32/releases/download/2.0.4/package_esp32_dev_index.json
腳位認識:
https://zerotech.club/esp32-gpio/
PIO 34,35,36,39:Input only(不能作為輸出腳位)
GPIO 0,6,7,8,9,10,11:系統用,勿使用(淺灰色標示)
GPIO 18:重開機
簡單控制RGB LED模組。
const byte Red = 4;
const byte Green = 16;
const byte Blue = 17; //const 確保往後程式不會修改到
char data; //擷取資料
void setup() {
pinMode(Red,OUTPUT);
pinMode(Green,OUTPUT);
pinMode(Blue,OUTPUT);
Serial.begin(9600);
}
void loop() {
if(Serial.available()){
data = Serial.read();
if(data == '1'){
digitalWrite(Blue,LOW);
digitalWrite(Red,HIGH);
delay(500);
digitalWrite(Red,LOW);
digitalWrite(Green,HIGH);
delay(500);
digitalWrite(Green,LOW);
digitalWrite(Blue,HIGH);
delay(500); }
else {
digitalWrite(Blue,LOW);
digitalWrite(Green,LOW);
digitalWrite(Red,LOW); }
}
}
結果:
使用電腦發送訊號啟動LED,並結合LED狀態顯示當下Red、Green、Blue的狀態。
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
//LCD接腳SDA SCL
const byte Red = 4;
const byte Green = 16;
const byte Blue = 17; //const 確保往後程式不會修改到
char data; //擷取資料
void setup() {
lcd.init(); // initialize the lcd
// Print a message to the LCD.
lcd.setCursor(0,0);//第一字元開始位置
lcd.print("waiting.....");
lcd.backlight();
pinMode(Red,OUTPUT);
pinMode(Green,OUTPUT);
pinMode(Blue,OUTPUT);
Serial.begin(9600);
}
void loop() {
if(Serial.available()){
data = Serial.read();
if(data == '1'){
lcd.setCursor(0,0);//第一字元開始位置
lcd.clear();
Serial.println("紅");
digitalWrite(Blue,LOW);
digitalWrite(Red,HIGH);
lcd.setCursor(0,0);//第一字元開始位置
lcd.print("Red open");
delay(600);
Serial.println("綠");
digitalWrite(Red,LOW);
digitalWrite(Green,HIGH);
lcd.setCursor(0,0);//第一字元開始位置
lcd.print("Green open");
delay(600);
Serial.println("藍");
digitalWrite(Green,LOW);
digitalWrite(Blue,HIGH);
lcd.setCursor(0,0);//第一字元開始位置
lcd.print("Blue open");
delay(600);
Serial.println("空");
digitalWrite(Blue,LOW);
digitalWrite(Green,LOW);
digitalWrite(Red,LOW);
lcd.setCursor(0,0);//第一字元開始位置
lcd.print("waiting....."); }
else {
digitalWrite(Blue,LOW);
digitalWrite(Green,LOW);
digitalWrite(Red,LOW);
lcd.setCursor(0,0);//第一字元開始位置
lcd.print("waiting....."); }
}
}
結果:
學習網址:https://crazymaker.com.tw/esp32-connect-to-wifi-network/
語法 | WIFI模式 | 功能 |
---|---|---|
WiFi.mode(WIFI_AP) | Access Point (AP) | ESP32可以讓其他設備透過wifi接入(就像家裡的wifi基地台,可供手機連線)。 |
WiFi.mode(WIFI_STA) | Station(STA) | 無線終端模式,也就是讓ESP32可以連接上其他的熱點(就像手機一樣,可以連上家裡wifi)。 |
WiFi.mode(WIFI_AP_STA) | AP+STA | 將ESP32設置成兩個模式並存。 |
WiFi.mode(WIFI_OFF); | OFF | 關閉wifi |
檔案資料夾:WIFI_ESP32。
#include<WiFi.h>
const char ssid[]="Ray's Galaxy A52s 5G"; //修改為你家的WiFi網路名稱
const char pwd[]="xadr7782"; //修改為你家的WiFi密碼
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA); //設置WiFi模式
WiFi.begin(ssid,pwd);
Serial.print("WiFi connecting");
//當WiFi連線時會回傳WL_CONNECTED,因此跳出迴圈時代表已成功連線
while(WiFi.status()!=WL_CONNECTED){
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.print("IP位址:");
Serial.println(WiFi.localIP()); //讀取IP位址
Serial.print("WiFi RSSI:");
Serial.println(WiFi.RSSI()); //讀取WiFi強度
}
void loop() {
}
結果:
利用NODE-RED的Dashboard做出一個有按鈕的頁面,透過按紐我們可以啟動LED並在'LED'狀態欄裡顯示當下狀態。
Dashboard頁面:
按下後 STM32與LCD:
學習參考網址:https://youyouyou.pixnet.net/blog/post/120275911-第十篇-esp32-wifi網路連線(pm2.5顯示器)