主頁 >  其他 > 【2020 電設G題 影像題解】

【2020 電設G題 影像題解】

2020-10-18 21:55:16 其他

目錄

  • 1、題目要求
  • 2、解題
    • 一、系統方案
    • 1.1 技術路線
    • 1.2 系統結構
    • 1.3 方案論證比較
    • 二、理論分析與計算
    • 2.1 物體形狀的測量方法
    • 2.2 物體尺寸的測量方法
    • 三、誤差分析
  • 3、影像代碼

1、題目要求

在這里插入圖片描述
在這里插入圖片描述

2、解題

本設計采用STM32F103ZET單片機作為主處理器,設計了非接觸物體尺寸形態測量系統,包括核心板模塊、主板降壓及管腳設計模塊、鍵盤輸入模塊、影像處理模塊、激光測距模塊、LCD彩屏模塊、蜂鳴器模塊、led燈模塊、以及機械模型構成,系統采用OpenMV4 H7 Cam攝像頭、STM32單片機、舵機構成倍訓反饋電路,根據激光測距反饋回的資訊,以及影像處理后反饋,控制舵機對方向及角度進行處理使攝像頭和激光對準識別物,利用影像的處理來判斷識別物的形狀和尺寸,再利用激光測距模塊測量出測量頭中心點與被測目標之間的距離,該系統具有良好的性能,且具有很好的穩定性,

一、系統方案

1.1 技術路線

本系統采用Open mv、云臺構成倍訓回路系統,其中Open mv獲得的位置資訊反饋到單片機,單片機根據位置資訊控制云臺轉向,達到目標之后,通過單片機控制激光測距模塊進行距離的測量和通過 Open mv進行影像的處理來判斷識別物的形狀及尺寸,

1.2 系統結構

在這里插入圖片描述
總體結構分為3個部分:輸入輸出的顯示板、主控板、電源,其他模塊通過介面與主控板相連,各個模塊協調,共同非接觸物體尺寸形態測量的任務,

1.3 方案論證比較

1.3.1 機械結構的選擇
本系統設計中,由于攝像頭要尋找目標,所以位置會受到多方面因素影響,因此機械結構對此次設計也起著重要作用,
方案一:采用步進電機+舵機的云臺設計
步進電機的優點是步數可以精確控制,但是啟動頻率過高或負載過大易出現失步或堵轉的現象,造成作業不夠穩定,并且在慢速轉動時速度不夠平緩,不利于激光模塊以及攝像頭的穩定性
方案二:采用舵機+舵機的云臺設計
此次使用的為數字舵機,打角范圍約在300°,通過調控占空比改變舵機角度,更為精準,同時相比步進電機而言,更為穩定,對整體的結構穩定性更為有保障,能夠滿足轉向與平衡要求,
基于上述分析,本設計選擇方案二,
1.3.2測距模塊模塊的選擇
題目要求測量出測量頭中心點與被測目標之間的距離,所有測距模塊的選取決定了測量資料的準確性,
方案一:紅外測距模塊
紅外測距模塊是用紅外線為介質的測量系統,測量范圍廣,回應時間短,價格便宜,接線簡單,體積小便于安裝和使用,但市面上常見的紅外測距模塊大多都在1.5米距離內比較準確,但題目的最遠要求是3米,
方案二:激光測距模塊
激光測距模塊精度高,測速快,解析度高,測量距離遠(本設計采用的可達到40米),足以滿足題目3米的要求,是一款穩定、精準、偏室內應用的模塊,價格偏貴,
基于上述分析,本設計選擇方案二,
1.3.3 舵機供電的選擇
方案一:線性電源驅動,線性電源由于沒有采用開關器件,理論上不會產生任何開關噪聲,輸出電源非常干凈,但線性電源的效率極低,大電流時發熱嚴重,嚴重影響電源穩定性,線性電源普遍帶負載能力較弱,受輸入電壓的影響較大,本題中,舵機有時候需要瞬間大幅度運動,需要極大的功率支持,若使用線性電源會大大地降低系統的可靠性,
方案二:開關電源驅動,開關電源效率高,能夠驅動大功率器件,且輸出穩定不會收到輸入電壓的干擾,但由于其作業特點,輸出電壓中會含有一定頻率的噪聲,但可以在輸出端加旁路電容在一定程度上抑制噪聲,使其并不會對舵機正常作業造成影響,
因此根據本題中舵機的大功率需求,我們決定采用方案二,
1.3.4 顯示方案的選擇
方案一:OLED顯示屏模塊
OLED顯示螢屏可視角度大,功耗低,厚度薄,體積小,溫度范圍廣,結構及制程簡單等特點,比較適合小系統,但現成的OLED模塊的尺寸比較偏小,其次顏色比較單一,
方案二:LCD彩屏模塊
LCD彩屏模塊解析度較高,尺寸比較大,并且是彩色的,所以看起來比較清楚,本設計采用的STM32核心板上有LCD彩屏模塊所對應的FPC介面,連接起來比較方便,
基于上述分析,本設計選擇方案二,

二、理論分析與計算

2.1 物體形狀的測量方法

已知物體分為兩大類,一類是純色塊物體,另一類為球類物體
純色塊物體我們選擇先用LAB色域進行閾值分割,利用連通域演算法,獲取每張圖中每個連通域的面積、密度比、圓形度等引數,由于每個形狀的連通域在這些特征的分布不同,可以進行多分類操作,在后續測驗中我們又發現由于光照的影響,連通域的形變程度較嚴重,圓形與方形容易產生混淆,于是又加入了霍夫圓變換,先判斷圓再去對三角形與正方形進行二分類,這樣效果較好,
球類物體我們仍然選擇通過色域特征限制以及霍夫圓變換進行特征篩選,其中排球以及黑白足球由于顏色的不均勻導致兩種方法都出現比較嚴重的漏判,后來選擇利用連通域的篩選,確定不同色塊的位置組合,再通過聚類演算法,找出色塊密度最大的區域,進行框定,

2.2 物體尺寸的測量方法

通過激光測距獲取距離,由于不同色塊的連通域像素數目并不一致,使用邊長為40厘米的不同顏色的目標板進行標定,假設連通域像素個數與目標物體的實際面積在同一距離下呈現線性關系,所以只需要擬合出線性函式的系數k與距離的映射關系即可,這里我們用二次函式擬合曲線,結果如下:
2.2.1 影像連通域面積與現實面積的映射函式
在這里插入圖片描述
Matlab擬合曲線圖:
藍色塊映射函式: 紅色塊映射函式: 綠色塊映射函式:
在這里插入圖片描述
計算好面積系數k之后,利用k和連通域面積計算得出真實的物體面積,然后根據幾何物體的形狀(三角形、圓形、正方形)用不同的面積公式反算出邊長,
在這里插入圖片描述

三、誤差分析

3.1識別誤差
原因:不同的光照下,對物塊的分割效果有較大差異,容易將背景中雜物誤識別為目標物體;不同的角度下,球體的表面特征有較大差異,容易出現球類漏判
改進措施:采用對光照魯棒性更高的分割演算法;采用對角度魯棒性更高的分類演算法;對于有限分類的任務,可考慮使用小型的神經網路訓練
3.2尺寸誤差
原因:公式為近似擬合,采樣資料不夠多且密集;計算尺寸所需要的變數之一:物塊像素個數,會隨著光照影響、角度影響而呈現幾十的上下浮動,
改進措施:多次采集資料,擬合公式;在公式的因變數中加入場景平均灰度值、角度值
3.3距離誤差
原因:傳感器精度有限;由于是懸掛,被測物體可能會前后飄動,
改進措施:采用更加精準的采樣儀器;在物體背面進行固定

3、影像代碼

#2020 年 TI 杯大學生電子設計競賽非接觸物體尺寸形態測量(G 題) openmv測驗代碼
# author:DYY
# school:HDU
import sensor, image, time
import math
from pyb import UART
import json
import ustruct
sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.RGB565) # or sensor.RGB565  565
sensor.set_framesize(sensor.QQVGA) # or sensor.QVGA (or others)
sensor.skip_frames(50)             #跳過50frame,使新設定生效,并自動調節白平衡
sensor.set_auto_gain(False)         #關閉自動自動增益,默認開啟的,在顏色識別中,一定要關閉白平衡,
sensor.set_auto_whitebal(False)     #關閉白平衡,白平衡是默認開啟的,在顏色識別中,一定要關閉白平衡,



#引數初始化
fps_cnt=0
fps_cnt_set=10000
show_fps_set=15
target_x=0
target_y=0
shape = 0
graylight_x=0
graylight_y=0
distance=0
PI=3.14159
#防誤判變數
now_length = 0
last_length = 0
exist_times = 0
sum_length = 0
last_center_X = 0
last_center_Y = 0

tri_times=0
rect_times=0
circle_times=0
xy_times=0
xy_not_times=0
mode='A'
class Circle:
    def __init__(self):  #_init_(self),主要給類初始化一些屬性,物件創建時自動呼叫該方法執行
        self.left_pixelsLimit = 3000
        self.right_pixelsLimit = 50000
        self.left_SolidtyLimit = 0.78
        self.right_SolidtyLimit = 0.85
        self.left_RoundnessLimit = 0.98
        self.right_RoundnessLimit = 1
class Triangle:
    def __init__(self):  #_init_(self),主要給類初始化一些屬性,物件創建時自動呼叫該方法執行
        self.left_pixelsLimit = 140
        self.right_pixelsLimit = 1300
        self.left_SolidtyLimit = 0.4
        self.right_SolidtyLimit = 0.86
        self.left_RoundnessLimit = 0.5
        self.right_RoundnessLimit = 0.99
class Rectangle:
    def __init__(self):  #_init_(self),主要給類初始化一些屬性,物件創建時自動呼叫該方法執行
        self.left_pixelsLimit = 380
        self.right_pixelsLimit = 2300
        self.left_SolidtyLimit = 0.8
        self.right_SolidtyLimit = 1
        self.left_RoundnessLimit = 0.58
        self.right_RoundnessLimit = 1

MyCircle = Circle()
MyTriangle = Triangle()
MyRectangle = Rectangle()

#激光閾值
graylight_thred=(230,255)

#色塊閾值
#(88,-79,81)
green_threshold = (5,88,-73,-18,9,59)  #(57,95,-80,-20,-25,32)
red_threshold = (5,91,17,124,-30,70)   #(21,71,56,124,38,114)
blue_threshold = (5,70,-54,105,-80,-14)   #(20,73,-46,112,-128,-31)

football_threshold = (0,99,-66,118,16,127)
white_black_football_threshold= (0,27,-127,127,-127,127)
vollyball_threshold = (0,99,-66,118,25,127)
vollyball_threshold_blue = (0,80,-20,37,30,70)
basketball_threshold = (0,99,14,127,7,64)
#獲取激光坐標函式
def get_graylight(grayMat,paint):
   #global real_exist_times
   #mask1=grayMat.binary([graylight_thred])
   #計算連通域
   center_X=0
   center_Y=0
   for blob in grayMat.find_blobs([graylight_thred], pixels_threshold=0, area_threshold=0, merge=True, margin=0):
    pixels=blob.pixels()
    Roundness= blob.roundness()
    '''if(fps_cnt%show_fps_set==0):
        print("圓形度",Roundness)
        print("像素個數",pixels)'''
    #光亮像素過大或者圓形度過小視作無
    if pixels>=60 :
        center_X=0
        center_Y=0
    else:
        center_X=blob.cx()
        center_Y=blob.cy()
        #paint.draw_circle(center_X,center_Y,4, color =0, thickness = 3, fill = True)
   return (center_X,center_Y)
#獲取形狀、目標像素長度、目標中心坐標函式
def get_shapeANDcolor(srcImg,color_thred):
   center_X=0
   center_Y=0
   shape = 0
   target_length=0
   for blob in srcImg.find_blobs([color_thred], pixels_threshold=10, area_threshold=20, merge=True, margin=0):
    pixels=blob.pixels()       #獲取像素個數,用來判斷大小
    print(pixels)
    #首先用像素限制掉雜點
    if(pixels >=MyTriangle.left_pixelsLimit):
        Roundness= blob.roundness()#獲取連通域圓形度
        Solidty = blob.solidity()  #獲取連通域與它最小外接矩形的密度比
        if(fps_cnt%show_fps_set==0):
            print("pixels",pixels)
            print("Roundness",Roundness)
            print("Solidty",Solidty)
        #條件限制
        if(pixels<=MyTriangle.right_pixelsLimit and Solidty>=MyTriangle.left_SolidtyLimit and Solidty<=MyTriangle.right_SolidtyLimit and Roundness>=MyTriangle.left_RoundnessLimit and Roundness<=MyTriangle.right_RoundnessLimit):
            srcImg.draw_rectangle(blob[0:4],color = (255, 0, 0)) #用矩形標記出目標顏色區域
            srcImg.draw_cross(blob[5], blob[6]) #在目標顏色區域的中心畫十字形標記
            center_X=blob.cx()
            center_Y=blob.cy()
            shape = 1
            target_length = pixels
        elif(pixels<=MyRectangle.right_pixelsLimit and Solidty>=MyRectangle.left_SolidtyLimit and Solidty<=MyRectangle.right_SolidtyLimit and Roundness>=MyRectangle.left_RoundnessLimit and Roundness<=MyRectangle.right_RoundnessLimit):
            #srcImg.draw_rectangle(blob[0:4],color = (0, 255, 0)) #用矩形標記出目標顏色區域
            #srcImg.draw_cross(blob[5], blob[6]) #在目標顏色區域的中心畫十字形標記
            center_X=blob.cx()
            center_Y=blob.cy()
            shape = 3
            target_length =pixels
        else:
            center_X=0
            center_Y=0
            shape = 0
            target_length = 0
   return (shape,center_X,center_Y,target_length)
#獲取最大可能色塊函式
def get_maxsize_color(srcImg):
   R_MAXpixels=0
   G_MAXpixels=0
   B_MAXpixels=0
   #尋找red最大連通域
   for blob in srcImg.find_blobs([red_threshold], pixels_threshold=10, area_threshold=20, merge=True, margin=0):
       pixels=blob.pixels()       #獲取像素個數,用來判斷大小
       R_MAXpixels = max(pixels,R_MAXpixels)
   #尋找green最大連通域
   for blob in srcImg.find_blobs([green_threshold], pixels_threshold=10, area_threshold=20, merge=True, margin=0):
       pixels=blob.pixels()       #獲取像素個數,用來判斷大小
       G_MAXpixels = max(pixels,G_MAXpixels)
   #尋找blue最大連通域
   for blob in srcImg.find_blobs([blue_threshold], pixels_threshold=10, area_threshold=20, merge=True, margin=0):
       pixels=blob.pixels()       #獲取像素個數,用來判斷大小
       B_MAXpixels = max(pixels,B_MAXpixels)
   maxpixels=max(R_MAXpixels,G_MAXpixels,B_MAXpixels)
   if(R_MAXpixels==maxpixels):
       return red_threshold
   elif(G_MAXpixels==maxpixels):
       return green_threshold
   else:
       return blue_threshold
#獲取背景板左右邊界函式
def get_leftANDrightLINE(srcImg,center_X,center_Y):
    grayimg =srcimg.to_grayscale()
    canny_thred=13
    cannyimg=grayimg.find_edges(image.EDGE_CANNY, threshold=(canny_thred,canny_thred*2))
    cannyimg.dilate(1)
    centerx = center_X
    centery = center_Y
    flag =0
    right_x = 160
    left_x = 0
    for i in range(centerx,cannyimg.width()-1):
        if(cannyimg.get_pixel(i,centery)==0 and cannyimg.get_pixel(i + 1,centery)==255):
            flag+=1
            if(flag == 1):
                right_x =  i
                break
    flag =0
    for i in range(centerx,1,-1):
        if(cannyimg.get_pixel(i,centery)==0 and cannyimg.get_pixel(i - 1,centery)==255):
            flag+=1
            if(flag == 1):
                left_x =  i
                break
    if(fps_cnt%show_fps_set==0):
        print(right_x)
        print(left_x)
    return (left_x,right_x)

#防誤判函式,目標的尺寸,并且將值限制在30到40之間
def Prevent_misslength(now_length,last_length):
    global exist_times
    global sum_length
    if last_length==0 and now_length==0:
        sum_length=0
    if abs(last_length-now_length)<=7 and now_length!=0 and last_length!=0:
        sum_length+=now_length
        exist_times+=1
    else:
        sum_length=0
        exist_times=0
    if(exist_times!=0):
        result=sum_length/exist_times
        if(result>=40):
            result=40
        elif(result<=30):
            result=30
        return result
    else:
        return 0
#防誤判函式,中心坐標
def Prevent_misstarget(point1_X,point1_Y,lastpoint1_X,lastpoint1_Y):
    global xy_times
    global xy_not_times
    if point1_X==0 and point1_Y==0:
        xy_not_times+=1
    if point1_X==0 and point1_Y==0 and lastpoint1_X!=0 and lastpoint1_Y!=0:
        point1_X=lastpoint1_X
        point1_Y=lastpoint1_Y
    if lastpoint1_X!=0 and lastpoint1_Y!=0 and (abs(lastpoint1_X-point1_X)>=20 or abs(lastpoint1_Y-point1_Y)>=20):
        point1_X=lastpoint1_X
        point1_Y=lastpoint1_Y
    if xy_not_times>=10:
        point1_X=0
        point1_Y=0
        xy_not_times=0
    return point1_X,point1_Y

#白色足球檢測函式
def detect_whiteANDblack_football(srcimg):
    img_new = srcimg.copy()
    binimg=img_new.binary([white_black_football_threshold])
    listX = []
    listY = []
    point_nums=0
    for blob in binimg.find_blobs([(1,255)], pixels_threshold=5, area_threshold=5, merge=True, margin=2):
        pixels=blob.pixels()       #獲取像素個數,用來判斷大小
        Solidity = blob.solidity()
        #if(pixels>=4 and pixels<=48):
            #print(Solidity)
            #print(blob.w()/blob.h())
        #print(pixels)
        if(pixels>=4 and pixels<=48 and Solidity>=0.75  and 0.8<=blob.w()/blob.h()<=1.3 and 20<=blob.cy()<=100):
            listX.append(blob.cx())
            listY.append(blob.cy())
            #srcimg.draw_rectangle(blob[0:4], color = (255, 0, 0)) #用矩形標記出目標顏色區域
            #srcimg.draw_cross(blob[5], blob[6]) #在目標顏色區域的中心畫十字形標記
    mean_X=0
    mean_Y=0
    if(len(listX)>=2):
        #求密度最大的點
        while(len(listX)>1):
            #求mean_x,mean_y
            mean_X = Get_Average(listX)
            mean_Y = Get_Average(listY)
            #找到點集中距離mean_X,mean_Y最大的點,并將它去除
            max_distance=0
            distance=0
            max_i=0
            for i in range(len(listX)):
                distance = (listX[i]-mean_X)*(listX[i]-mean_X)+(listY[i]-mean_Y)*(listY[i]-mean_Y)
                if distance>=max_distance:
                   max_i=i
            del listX[max_i]
            del listY[max_i]
        #剩下點是球點
        mean_X = Get_Average(listX)
        mean_Y = Get_Average(listY)
    #srcimg.draw_circle(mean_X,mean_Y,10, color = (255, 0, 0))
    return (mean_X,mean_Y,len(listX))

#獲取平均數
def Get_Average(list):
   sum = 0
   for item in list:
      sum += item
   if(len(list)==0):
    return 0
   return int(sum/len(list))
#模型為簡化后的模型
def get_real_length(pixels,distance,color):
   reallength = 0
   if(color==1):
       #藍色k
       #0.3001   -2.0901    4.0956
       ratio = 0.3001 * distance * distance -2.0901 * distance +4.0956
       reallength = pixels/ratio
       #reallength =reallength*0.8
   elif(color==2):
       #紅色k
       #0.4336   -2.8160    5.1373
       ratio = 0.4336 * distance * distance -2.8160 * distance +5.1373
       reallength = pixels/ratio
       #reallength =reallength*1.105
   elif(color==3):
       #綠色k
       #0.4364   -2.8062    5.0621
       ratio = 0.4364 * distance * distance -2.8062 * distance +5.0621
       reallength = pixels/ratio
       #reallength =reallength*0.99
   else:
       reallength=0
   return reallength
#初始化時鐘
clock = time.clock() # Tracks FPS.
uart = UART(3,115200)   #定義串口3變數
#設定串口
uart.init(115200, bits=8, parity=None, stop=0) # init with given parameters

uart1=UART(1,38400)

#我們要傳送的資料有:目標大小、形狀、幾何中心坐標 以及回車
def sending_data(length,shape,cx,cy,dis1,dis2,color):    #發送函式
    global uart
    data = ustruct.pack("<bbbbbbbbb",
                   length,
                   shape,
                   cx,
                   cy,
                   dis1,
                   dis2,
                   color,
                   0x0D,
                   0x0A)
    uart.write(data)
#主要接受的是模式
def recive_data():   #接收函式
    global uart
    global mode
    if uart.any():
        #接收位元組串
        #tmp_data = uart.readline()
        #接收字串
        tmp_data = uart.readline().decode()
        #如果想把回車換行去除掉,
        #tmp_data = uart.readline().decode().strip()
        #將形式為D=0.604m,90#的字串轉換為float型別的資料
        #new_data = tmp_data[2,7]
        #print(tmp_data)
        #獲取mode編號
        length = len(tmp_data)
        if( 2<=length<=4 and  tmp_data[0]=='Q'):
            mode = tmp_data[length-1]
            #print(mode)
    return mode
def recive_distance():   #接收函式
    global uart1
    global distance
    if uart1.any():
        tmp_data = uart1.readline().decode()
        #print(tmp_data)
        if len(tmp_data)>=6 and tmp_data[0]=='D' and tmp_data[1]=='=' and tmp_data[2]>='0' and tmp_data[2]<='9'and tmp_data[4]>='0' and tmp_data[4]<='9'and tmp_data[5]>='0' and tmp_data[5]<='9':
            distance=int(tmp_data[2])+int(tmp_data[4])*0.1+int(tmp_data[5])*0.01
            #distance=int(distance*100)
            print(distance)
    return distance
#影像回圈
while(True):
    clock.tick() # Track elapsed milliseconds between snapshots().
    #【step 1:】獲取去畸變彩圖,這里采用的無畸變攝像頭
    srcimg = sensor.snapshot()#.lens_corr(strength = 1.8, zoom = 1.0)
    fps_cnt=fps_cnt+1
    #flag=0時沒有圓
    flag=0
    #初始化引數
    now_length = 0
    circle_r=0
    circle_x=0
    circle_y=0
    center_X=0
    center_Y=0
    shape=0
    #left_line = 0
    #right_line = 160
    target_length = 0
    #黑白足球黑塊初始化
    black_nums=0
    color_flag=0        #藍1 紅2 綠3
    distance = recive_distance()
    mode = recive_data()
    #mode='C'
    real_target_length=0
    #flag_football=0:檢測黃色足球 flag_football=1:檢測黑白足球
    flag_football = 1
    #mode1是球類檢測
    #mode0是幾何物體檢測
    #print(mode)
    target_pixels=0
    if(mode == 'A' or mode == 'B'):
        #觀察是否有圓
        for c in srcimg.find_circles(threshold = 2700, x_margin = 10, y_margin = 10, r_margin = 10,r_min = 5, r_max = 30, r_step = 2):
           area = (c.x()-c.r(), c.y()-c.r(), 2*c.r(), 2*c.r())
           #area為識別到的圓的區域,即圓的外接矩形框
           statistics = srcimg.get_statistics(roi=area)#像素顏色統計
           #print(statistics)
           if(-73<statistics.a_mode()<-18 and 9<statistics.b_mode()<59):
            color_flag = 3
           elif(17<statistics.a_mode()<124 and -30<statistics.b_mode()<70):
            color_flag = 2
           elif(-54<statistics.a_mode()<105 and -80<statistics.b_mode()<-14):
            color_flag = 1
           if 1<=color_flag<=3:
               #找到最大的圓作為我們的目標圓
               flag = 1
               if(c.r()>=circle_r):
                   circle_r = c.r()
                   circle_x = c.x()
                   circle_y = c.y()
                   #if(fps_cnt%show_fps_set==0):
                       #print(c)
           #srcimg.draw_circle(circle_x,circle_y,circle_r, color = (255, 0, 0))
        #為圓
        if(flag == 1 ):
           center_X = circle_x
           center_Y = circle_y
           target_pixels = PI*circle_r*circle_r
           shape = 2
        #不為圓,進行其他檢測
        else:
           #首先確定色塊顏色
           color_thred = get_maxsize_color(srcimg)
           if(color_thred==green_threshold):
            color_flag = 3
           elif(color_thred==blue_threshold):
            color_flag = 1
           elif(color_thred==red_threshold):
            color_flag = 2
           #print(color_thred)
           #color_thred=red_threshold
           #在該色域中尋找特征,然后得到形狀和中心坐標
           (shape,center_X,center_Y,target_pixels) = get_shapeANDcolor(srcimg,color_thred)
    else:
        #先找籃球
        ball_pixels = 0
        for blob in srcimg.find_blobs([basketball_threshold], pixels_threshold=10, area_threshold=20, merge=True, margin=2):
            pixels=blob.pixels()       #獲取像素個數,用來判斷大小
            #print(pixels)
            #print(blob.w()/blob.h())
            #print(blob.h())
            if(pixels>=200 and pixels<=780 and 0.87<=blob.w()/blob.h()<=1.15 and 12<=blob.w()<=40 and 12<=blob.h()<=40 and 20<=blob.cy()<=100):
                if(pixels>=ball_pixels):
                    ball_pixels=pixels
                    srcimg.draw_rectangle(blob[0:4]) #用矩形標記出目標顏色區域
                    #srcimg.draw_cross(blob[5], blob[6]) #在目標顏色區域的中心畫十字形標記
                    shape=4
                    center_X = blob.cx()
                    center_Y = blob.cy()
        ball_pixels=0
        if(shape==0):
            #再找足球
            #if(mode=='C'):
                #第一種,純黃足球
            for blob in srcimg.find_blobs([vollyball_threshold], pixels_threshold=10, area_threshold=20, merge=True, margin=2):
                pixels=blob.pixels()       #獲取像素個數,用來判斷大小
                Roundness = blob.roundness()
                #print(pixels)
                #print(Roundness)
                #print(pixels)
                if(pixels>=120 and pixels<=600 and Roundness>=0.75 and 3<=blob.w()<=40 and 3<=blob.h()<=40 and 20<=blob.cy()<=100):
                    if(pixels>=ball_pixels):
                        srcimg.draw_rectangle(blob[0:4]) #用矩形標記出目標顏色區域
                        #srcimg.draw_cross(blob[5], blob[6]) #在目標顏色區域的中心畫十字形標記
                        shape=5
                        center_X = blob.cx()
                        center_Y = blob.cy()
            #else:
            if(shape==0):
                #第二種,黑白足球
                (center_X,center_Y,black_nums) = detect_whiteANDblack_football(srcimg)
                if(center_X!=0 and center_Y!=0):
                    shape=5
        ball_pixels=0
        if(shape==0 and black_nums<=2):
            img_new = srcimg.copy()
            binimg=img_new.binary([vollyball_threshold,vollyball_threshold_blue])
            dilateimg = binimg.dilate(3)
            dilateimg = binimg.erode(2)
            #再找排球
            for blob in dilateimg.find_blobs([(1,255)], pixels_threshold=10, area_threshold=20, merge=True, margin=2):
                pixels=blob.pixels()       #獲取像素個數,用來判斷大小
                #print(pixels)
                #print(blob.w()/blob.h())
                #print(pixels))
                if(pixels>=110 and pixels<=500 and 3<=blob.w()<=40 and 3<=blob.h()<=40 and 0.7<=blob.w()/blob.h()<=1.3 and 20<=blob.cy()<=100 and 20<=blob.cx()<=140):
                    if(pixels>=ball_pixels):
                        srcimg.draw_rectangle(blob[0:4], color = (255, 0, 0)) #用矩形標記出目標顏色區域
                        #srcimg.draw_cross(blob[5], blob[6]) #在目標顏色區域的中心畫十字形標記
                        shape=6
                        center_X = blob.cx()
                        center_Y = blob.cy()
        #else:
            #print("NONE")

    #計算尺寸
    if(mode != 'C'):
        real_target_length = get_real_length(target_pixels,distance,color_flag)
        if(shape == 1):
            real_target_length = math.sqrt(real_target_length*2.31)
        elif(shape == 2):
            real_target_length = math.sqrt(real_target_length*1.273)
        elif(shape == 3):
            real_target_length = math.sqrt(real_target_length)
        #形狀防誤判
    #shapeList 對應:無形狀、三角形、圓形、正方形、籃球、足球、排球
    srcimg.draw_cross(80, 60,color = (0, 0, 0))
    shape_result=shape
    shapeList = [0,0,0,0,0,0,0]
    shapeList[shape]+=1
    if(fps_cnt%5==0):
        shape_result=shapeList.index(max(shapeList))
        shapeList = [0,0,0,0,0,0,0]
        #中心防誤判措施
        #(center_X,center_Y)=Prevent_misstarget(center_X,center_Y,last_center_X,last_center_Y)
        srcimg.draw_cross(center_X, center_Y)
        #srcimg.draw_cross(center_X,center_Y,color = (0, 255, 0))
        print(shape)
        #print(center_X,center_Y)
        #print(real_target_length)
        sending_data(int(real_target_length),shape_result,center_X,center_Y,int(distance),int(distance*100%100),color_flag)
        last_center_X = center_X
        last_center_Y = center_Y

分工:
硬體電路:苗百百
控制以及選單:下沙百人斬
影像:吊歪歪

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/178902.html

標籤:其他

上一篇:楊明翰的英國碩士留學攻略V0.1

下一篇:2020年保研歷程匯總(計算機專業)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more