• 方案介紹
  • 附件下載
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

3.6.5-解決紅色閾值調(diào)整過寬問題-openmv+STM32串口通信

03/22 08:25
922
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

聯(lián)系方式.txt

共1個(gè)文件

**非常詳細(xì)的視頻和文字教程,講解常見的openmv教程包括 巡線、物體識(shí)別、圓環(huán)識(shí)別、閾值自動(dòng)獲取等。非常適合學(xué)習(xí)openmv、K210、K230等項(xiàng)目
視頻合集鏈接在


openmv教程合集 openmv入門到項(xiàng)目開發(fā) openmv和STM32通信 openmv和opencv區(qū)別 openmv巡線 openmv數(shù)字識(shí)別教程LCD

tb:主頁鏈接:https://shop415231378.taobao.com/

在這里插入圖片描述

在這里插入圖片描述

'red':   (15, 50, 30, 70, 20, 70),  # 紅色的LAB顏色范圍
import sensor, image, time
from ulab import numpy as np

#教程作者:好家伙VCC
#歡迎交流群QQ: 771027961 作者郵箱: 1930299709@qq.com
#更多教程B站主頁:[好家伙VCC的個(gè)人空間-好家伙VCC個(gè)人主頁-嗶哩嗶哩視頻](https://space.bilibili.com/434192043)
#淘寶主頁鏈接:[首頁-好家伙VCC-淘寶網(wǎng)](https://shop415231378.taobao.com)
#更多嵌入式手把手教程-盡在好家伙VCC
# ******************** 參數(shù)配置 ********************
# 顏色閾值配置(LAB格式)
color_thresholds = {
    'red':   (15, 50, 30, 70, 20, 70),  # 紅色的LAB顏色范圍
    'green': (0, 100, -128, -10, 0, 127),  # 綠色的LAB顏色范圍
    'blue':  (0, 100, -128, 127, -128, -10)  # 藍(lán)色的LAB顏色范圍
}

# 霍夫變換參數(shù)
HOUGH_THRESHOLD = 2000   # 圓形檢測(cè)的靈敏度,值越高要求邊緣越明顯
MIN_RADIUS = 10          # 檢測(cè)的最小半徑
MAX_RADIUS = 50          # 檢測(cè)的最大半徑

# 卡爾曼濾波參數(shù)
TS = 1/60                # 幀時(shí)間(假設(shè)幀率為60fps)

# 初始化攝像頭
sensor.reset()  # 重置攝像頭
sensor.set_pixformat(sensor.RGB565)  # 設(shè)置像素格式為RGB565
sensor.set_framesize(sensor.QQVGA)  # 設(shè)置分辨率為QQVGA(160x120)
sensor.set_vflip(True)  # 垂直翻轉(zhuǎn)圖像
sensor.set_hmirror(True)  # 水平翻轉(zhuǎn)圖像
sensor.set_auto_gain(False)  # 關(guān)閉自動(dòng)增益
sensor.set_auto_whitebal(False)  # 關(guān)閉自動(dòng)白平衡
clock = time.clock()  # 創(chuàng)建時(shí)鐘對(duì)象用于計(jì)算幀率

# ******************** 卡爾曼濾波器類 ********************
class KalmanFilter:
    def __init__(self, initial_state):
        # 狀態(tài)轉(zhuǎn)移矩陣
        self.A = np.array([
            [1, 0, 0, 0, TS, 0],  # 位置和速度的狀態(tài)轉(zhuǎn)移
            [0, 1, 0, 0, 0, TS],
            [0, 0, 1, 0, 0, 0],
            [0, 0, 0, 1, 0, 0],
            [0, 0, 0, 0, 1, 0],
            [0, 0, 0, 0, 0, 1]
        ])
        # 觀測(cè)矩陣
        self.C = np.eye(6)  # 單位矩陣,表示狀態(tài)和觀測(cè)值直接對(duì)應(yīng)
        # 過程噪聲協(xié)方差矩陣
        self.Q = np.diag([1e-6]*6)  # 過程噪聲較小
        # 觀測(cè)噪聲協(xié)方差矩陣
        self.R = np.diag([1e-6]*6)  # 觀測(cè)噪聲較小
        # 初始狀態(tài)
        self.x_hat = initial_state  # 初始狀態(tài)估計(jì)值
        self.p = np.diag([10]*6)  # 初始誤差協(xié)方差矩陣

    def update(self, Z):
        # 預(yù)測(cè)步驟
        x_hat_minus = np.dot(self.A, self.x_hat)  # 預(yù)測(cè)狀態(tài)
        p_minus = np.dot(self.A, np.dot(self.p, self.A.T)) + self.Q  # 預(yù)測(cè)誤差協(xié)方差

        # 更新步驟
        S = np.dot(self.C, np.dot(p_minus, self.C.T)) + self.R  # 計(jì)算卡爾曼增益的分母
        S_inv = np.linalg.inv(S + 1e-4*np.eye(6))  # 計(jì)算逆矩陣,加入正則化項(xiàng)避免奇異矩陣
        K = np.dot(np.dot(p_minus, self.C.T), S_inv)  # 計(jì)算卡爾曼增益
        self.x_hat = x_hat_minus + np.dot(K, (Z - np.dot(self.C, x_hat_minus)))  # 更新狀態(tài)估計(jì)
        self.p = np.dot((np.eye(6) - np.dot(K, self.C)), p_minus)  # 更新誤差協(xié)方差
        return self.x_hat

# 初始化三個(gè)卡爾曼濾波器(分別對(duì)應(yīng)紅、綠、藍(lán))
kf_red = KalmanFilter(np.array([80, 60, 30, 30, 2, 2]))  # 紅色濾波器的初始狀態(tài)
kf_green = KalmanFilter(np.array([80, 60, 30, 30, 2, 2]))  # 綠色濾波器的初始狀態(tài)
kf_blue = KalmanFilter(np.array([80, 60, 30, 30, 2, 2]))  # 藍(lán)色濾波器的初始狀態(tài)

# ******************** 主循環(huán) ********************
while True:
    clock.tick()  # 記錄當(dāng)前幀的時(shí)間
    img = sensor.snapshot().lens_corr(1.8)  # 獲取圖像并校正鏡頭畸變
    # ===== 在畫幅中心繪制小圓環(huán)標(biāo)志 =====
    img.draw_circle(80, 60, 5, color=(0, 0, 0), thickness=1)  # 黑色小圓環(huán),半徑5像素
    # 分別處理紅、綠、藍(lán)三種顏色
    for color, threshold in color_thresholds.items():
        # 第一步:顏色閾值分割,找到當(dāng)前顏色的區(qū)域
        blobs = img.find_blobs([threshold], merge=True, margin=10)  # 查找當(dāng)前顏色的區(qū)域
        
        if blobs:
            # 取最大的色塊
            largest_blob = max(blobs, key=lambda b: b.area())  # 找到面積最大的當(dāng)前顏色區(qū)域
            # 繪制當(dāng)前顏色的矩形框
            if color == 'red':
                rect_color = (255, 0, 0)  # 紅色
            elif color == 'green':
                rect_color = (0, 255, 0)  # 綠色
            else:
                rect_color = (0, 0, 255)  # 藍(lán)色
            img.draw_rectangle(largest_blob.rect(), color=rect_color)  # 繪制矩形框

            # 第二步:在當(dāng)前顏色的區(qū)域內(nèi)檢測(cè)圓形
            roi = (largest_blob.x(), largest_blob.y(), largest_blob.w(), largest_blob.h())  # 定義檢測(cè)區(qū)域
            circles = img.find_circles(
                threshold=HOUGH_THRESHOLD,  # 圓形檢測(cè)的靈敏度
                x_margin=10,  # 圓心x坐標(biāo)的誤差范圍
                y_margin=10,  # 圓心y坐標(biāo)的誤差范圍
                r_margin=10,  # 半徑的誤差范圍
                r_min=MIN_RADIUS,  # 最小半徑
                r_max=MAX_RADIUS,  # 最大半徑
                roi=roi  # 限制檢測(cè)區(qū)域?yàn)楫?dāng)前顏色區(qū)域
            )

            if circles:
                # 篩選同心圓:取半徑最大的圓(假設(shè)最外層是目標(biāo))
                valid_circles = []
                for c in circles:
                    # 檢查是否在色塊中心附近
                    if abs(c.x() - largest_blob.cx()) < 15 and abs(c.y() - largest_blob.cy()) < 15:
                        valid_circles.append(c)
                
                if valid_circles:
                    target = max(valid_circles, key=lambda c: c.r())  # 找到半徑最大的圓
                    x, y, r = target.x(), target.y(), target.r()  # 獲取圓心坐標(biāo)和半徑
                    # 繪制檢測(cè)到的圓環(huán)
                    img.draw_circle(x, y, r, color=(0, 255, 0))  # 綠色圓環(huán)

                    # 更新卡爾曼濾波器
                    Z = np.array([x, y, 2*r, 2*r, 0, 0])  # 構(gòu)造觀測(cè)值:[x, y, w, h, dx, dy]
                    if color == 'red':
                        state = kf_red.update(Z)  # 更新紅色濾波器
                    elif color == 'green':
                        state = kf_green.update(Z)  # 更新綠色濾波器
                    else:
                        state = kf_blue.update(Z)  # 更新藍(lán)色濾波器
                    # 輸出卡爾曼濾波預(yù)測(cè)的圓心坐標(biāo)
                    print("卡爾曼預(yù)測(cè)坐標(biāo): X={}, Y={}, R={}".format(int(state[0]), int(state[1]), int(state[2]/2)))    
                    # 繪制預(yù)測(cè)結(jié)果
                    pred_x = int(state[0])  # 預(yù)測(cè)的圓心x坐標(biāo)
                    pred_y = int(state[1])  # 預(yù)測(cè)的圓心y坐標(biāo)
                    pred_r = int(state[2]/2)  # 預(yù)測(cè)的半徑

                    # 約束圓心在當(dāng)前顏色的區(qū)域內(nèi)
                    blob_x, blob_y, blob_w, blob_h = largest_blob.rect()  # 獲取當(dāng)前顏色區(qū)域的邊界
                    pred_x = max(blob_x, min(blob_x + blob_w, pred_x))  # 約束x坐標(biāo)在當(dāng)前顏色區(qū)域內(nèi)
                    pred_y = max(blob_y, min(blob_y + blob_h, pred_y))  # 約束y坐標(biāo)在當(dāng)前顏色區(qū)域內(nèi)
                    pred_r = min(pred_r, min(blob_w, blob_h) // 2)  # 約束半徑不超過當(dāng)前顏色區(qū)域大小

                    # 繪制預(yù)測(cè)的圓心和圓環(huán)
                    img.draw_cross(pred_x, pred_y, color=rect_color)  # 紅色、綠色或藍(lán)色十字標(biāo)記圓心
                    img.draw_circle(pred_x, pred_y, pred_r, color=(255, 255, 0))  # 黃色圓環(huán)

    # 打印幀率
    print("FPS:", clock.fps())  # 輸出當(dāng)前幀率

這樣就不會(huì)誤識(shí)別了
在這里插入圖片描述

 

  • 聯(lián)系方式.txt
    下載

相關(guān)推薦

方案定制

去合作
方案開發(fā)定制化,2000+方案商即時(shí)響應(yīng)!