樹莓派利用OpenCV的影像跟蹤、人臉識別等

專注的阿熊發表於2022-06-29

import sys

import cv2

import math

import time

import threading

import numpy as np

import HiwonderSDK.yaml_handle as yaml_handle

if sys.version_info.major == 2:

     print('Please run this program with python3!')

     sys.exit(0)

range_rgb = {

     'red':   (0, 0, 255),

     'blue':  (255, 0, 0),

     'green': (0, 255, 0),

     'black': (0, 0, 0),

     'white': (255, 255, 255)}

__target_color = ('red', 'green', 'blue')

lab_data = yaml_handle.get_yaml_data(yaml_handle.lab_file_path)

# 找出面積最大的輪廓

# 引數為要比較的輪廓的列表

def getAreaMaxContour(contours):

     contour_area_temp = 0

     contour_area_max = 0

     area_max_contour = None

     for c in contours:  # 歷遍所有輪廓

         contour_area_temp = math.fabs(cv2.contourArea(c))  # 計算輪廓面積

         if contour_area_temp > contour_area_max:

             contour_area_max = contour_area_temp

             if contour_area_temp > 300:  # 只有在面積大於 300 時,最大面積的輪廓才是有效的,以過濾干擾

                 area_max_contour = c

     return area_max_contour, contour_area_max  # 返回最大的輪廓

detect_color = None

color_list = []

start_pick_up = False

size = (640, 480)

def run(img):

     global rect

     global detect_color

     global start_pick_up

     global color_list

     img_copy = img.copy()

     frame_resize = cv2.resize(img_copy, size, interpolation=cv2.INTER_NEAREST)

     frame_gb = cv2.GaussianBlur(frame_resize, (3, 3), 3)

     frame_lab = cv2.cvtColor(frame_gb, cv2.COLOR_BGR2LAB)  # 將影像轉換到 LAB 空間

     color_area_max = None

     max_area = 0

     areaMaxContour_max = 0

     if not start_pick_up:

         for i in lab_data:

             if i in __target_color:

                 frame_mask = cv2.inRange(frame_lab,

                                              (lab_data[i]['min'][0],

                                               lab_data[i]['min'][1],

                                               lab_data[i]['min'][2]),

                                              (lab_data[i]['max'][0],

                                               lab_data[i]['max'][1],

                                               lab_data[i]['max'][2]))  # 對原影像和掩模進行位運算

                 opened = cv2.morphologyEx(frame_mask, cv2.MORPH_OPEN, np.ones((3, 3), np.uint8))  # 開運算

                 closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, np.ones((3, 3), np.uint8))  # 閉運算

                 contours =跟單網gendan5.com cv2.findContours(closed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2]  # 找出輪廓

                 areaMaxContour, area_max = getAreaMaxContour(contours)  # 找出最大輪廓

                 if areaMaxContour is not None:

                     if area_max > max_area:  # 找最大面積

                         max_area = area_max

                         color_area_max = i

                         areaMaxContour_max = areaMaxContour

         if max_area > 500:  # 有找到最大面積

             rect = cv2.minAreaRect(areaMaxContour_max)

             box = np.int0(cv2.boxPoints(rect))

             y = int((box[1][0]-box[0][0])/2+box[0][0])

             x = int((box[2][1]-box[0][1])/2+box[0][1])

             print('X:',x,'Y:',y) # 列印座標

             cv2.drawContours(img, [box], -1, range_rgb[color_area_max], 2)

             if not start_pick_up:

                 if color_area_max == 'red':  # 紅色最大

                     color = 1

                 elif color_area_max == 'green':  # 綠色最大

                     color = 2

                 elif color_area_max == 'blue':  # 藍色最大

                     color = 3

                 else:

                     color = 0

                 color_list.append(color)

                 if len(color_list) == 3:  # 多次判斷

                     # 取平均值

                     color = int(round(np.mean(np.array(color_list))))

                     color_list = []

                     if color == 1:

                         detect_color = 'red'

                     elif color == 2:

                         detect_color = 'green'

                     elif color == 3:

                         detect_color = 'blue'

                     else:

                         detect_color = 'None'

##    cv2.putText(img, "Color: " + detect_color, (10, img.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.65, detect_color, 2)

     return img

if __name__ == '__main__':

     cap = cv2.VideoCapture(-1) # 讀取攝像頭

     __target_color = ('red',)

     while True:

         ret, img = cap.read()

         if ret:

             frame = img.copy()

             Frame = run(frame)           

             cv2.imshow('Frame', Frame)

             key = cv2.waitKey(1)

             if key == 27:

                 break

         else:

             time.sleep(0.01)

     cv2.destroyAllWindows()


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946337/viewspace-2903329/,如需轉載,請註明出處,否則將追究法律責任。

相關文章