溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Python+OpenCV如何實(shí)現(xiàn)基于顏色的目標(biāo)識(shí)別

發(fā)布時(shí)間:2022-01-05 19:01:41 來源:億速云 閱讀:509 作者:柒染 欄目:開發(fā)技術(shù)

這篇文章給大家介紹Python+OpenCV如何實(shí)現(xiàn)基于顏色的目標(biāo)識(shí)別,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

任務(wù)

讓攝像頭識(shí)別到視野范圍內(nèi)的氣球并返回每個(gè)氣球的中心點(diǎn)坐標(biāo)。

Python+OpenCV如何實(shí)現(xiàn)基于顏色的目標(biāo)識(shí)別

因?yàn)閳?chǎng)地固定,背景單一,所以省下來很多操作和處理。于是就有兩種解決思路:第一種是基于氣球形狀做輪廓提取,只要是閉合橢圓或圓形形就認(rèn)為是目標(biāo)物體;第二種是基于氣球顏色,只要符合目標(biāo)物體的顏色就認(rèn)為是目標(biāo)物體。

因?yàn)閿z像頭是裝在四足機(jī)器人(它的任務(wù)是去扎氣球)身上的,所以它如果移動(dòng)到攝像頭視野范圍內(nèi)氣球不成閉合橢圓或圓形的時(shí)候就無法識(shí)別了,再加上場(chǎng)地?zé)艄舛a(chǎn)生的陰影的問題,在初步實(shí)踐中發(fā)現(xiàn)經(jīng)過圖像處理的氣球不一定是閉合球形的。所以這種方法被我否決了。

于是我就采用了第二種方法,實(shí)現(xiàn)思路大概如下:

首先對(duì)圖像進(jìn)行形態(tài)學(xué)處理,具體為將讀入的灰度圖進(jìn)行一次濾波操作,將圖像轉(zhuǎn)化成HSV圖,然后進(jìn)行腐蝕操作。接著就對(duì)目標(biāo)顏色進(jìn)行識(shí)別和提取。然后提取圖像的輪廓,過濾掉輪廓圍成面積較小的物體后將剩余物體視為目標(biāo)。接下來就繪制目標(biāo)的外接矩形(不必要,用于調(diào)試。當(dāng)然也為了帥氣的視覺效果)。最后計(jì)算目標(biāo)的中心點(diǎn),返回中心點(diǎn),并繪制在圖上。

話不多說我們來看一下具體的代碼實(shí)現(xiàn)吧

主要代碼

import cv2
#import matplotlib.pyplot as plt
import numpy as np

#定義一個(gè)展示圖片的函數(shù)
def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

#定義一個(gè)形態(tài)學(xué)處理的函數(shù)
def good_thresh_img(img):
    gs_frame = cv2.GaussianBlur(img, (5, 5), 0)                     #高斯濾波
    hsv = cv2.cvtColor(gs_frame, cv2.COLOR_BGR2HSV)                 # 轉(zhuǎn)化成HSV圖像
    erode_hsv = cv2.erode(hsv, None, iterations=2)
    return erode_hsv

#定義一個(gè)識(shí)別目標(biāo)顏色并處理的函數(shù)
def select_color_img(target_color,img):
        for i in target_color:
            mask=cv2.inRange(erode_hsv,color_dist[i]['Lower'],color_dist[i]['Upper'])
            if(i==target_color[0]):
                inRange_hsv=cv2.bitwise_and(erode_hsv,erode_hsv,mask = mask)
                cv_show('res',inRange_hsv)#不必要,用于調(diào)試
            else:
                inRange_hsv1=cv2.bitwise_and(erode_hsv,erode_hsv,mask = mask)
                cv_show('res1',inRange_hsv1)#不必要,用于調(diào)試
                inRange_hsv=cv2.add(inRange_hsv,inRange_hsv1)
                cv_show('res2',inRange_hsv)#不必要,用于調(diào)試
        return  inRange_hsv

#定義一個(gè)提取輪廓的函數(shù)
def extract_contour(img):
    inRange_gray = cv2.cvtColor(final_inRange_hsv,cv2.COLOR_BGR2GRAY)
    contours,hierarchy = cv2.findContours(inRange_gray,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
    return contours
    
#定義一個(gè)尋找目標(biāo)并繪制外接矩形的函數(shù)
def find_target(contours,draw_img):
    for c in contours:

        if cv2.contourArea(c) < 2000:             #過濾掉較面積小的物體
            continue
        else:
            target_list.append(c)               #將面積較大的物體視為目標(biāo)并存入目標(biāo)列表
    for i in target_list:                       #繪制目標(biāo)外接矩形
        rect = cv2.minAreaRect(i)
        box = cv2.boxPoints(rect)
        cv2.drawContours(draw_img, [np.int0(box)], -1, (0, 255, 255), 2)
    return draw_img

#定義一個(gè)繪制中心點(diǎn)坐標(biāo)的函數(shù)
def draw_center(target_list,draw_img):
    for  c in target_list:
        M = cv2.moments(c)                   #計(jì)算中心點(diǎn)的x、y坐標(biāo)
        center_x = int(M['m10']/M['m00'])
        center_y = int(M['m01']/M['m00'])
        print('center_x:',center_x)          #打?。ǚ祷兀┲行狞c(diǎn)的x、y坐標(biāo)
        print('center_y:',center_y)
    
        cv2.circle(draw_img,(center_x,center_y),7,128,-1)#繪制中心點(diǎn)
        str1 = '(' + str(center_x)+ ',' +str(center_y) +')' #把坐標(biāo)轉(zhuǎn)化為字符串
        cv2.putText(draw_img,str1,(center_x-50,center_y+40),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,0),2,cv2.LINE_AA)#繪制坐標(biāo)點(diǎn)位
    
    return draw_img

###主函數(shù)部分
#創(chuàng)建顏色字典
color_dist = {'red': {'Lower': np.array([0, 60, 60]), 'Upper': np.array([6, 255, 255])},
              'yellow': {'Lower': np.array([15, 160, 50]), 'Upper': np.array([35, 255, 255])},
              'green': {'Lower': np.array([50, 50, 50]), 'Upper': np.array([130, 255, 255])},
              }
#目標(biāo)顏色
target_color = ['green','yellow']
#創(chuàng)建目標(biāo)列表
target_list=[]

img = cv2.imread(r'D:lesson\balloom.jpg',cv2.COLOR_BGR2RGB)       #讀入圖像(直接讀入灰度圖)
draw_img = img.copy()                             #為保護(hù)原圖像不被更改而copy了一份,下面對(duì)圖像的修改都是對(duì)這個(gè)副本進(jìn)行的
erode_hsv = good_thresh_img(img)
final_inRange_hsv = select_color_img(target_color,erode_hsv)
contours = extract_contour(final_inRange_hsv)
draw_img = find_target(contours,draw_img)
final_img = draw_center(target_list,draw_img)

cv_show('final_img',final_img)

效果展示

顏色提取效果:

Python+OpenCV如何實(shí)現(xiàn)基于顏色的目標(biāo)識(shí)別

Python+OpenCV如何實(shí)現(xiàn)基于顏色的目標(biāo)識(shí)別

Python+OpenCV如何實(shí)現(xiàn)基于顏色的目標(biāo)識(shí)別

繪制外接矩形及中心點(diǎn)的效果:

Python+OpenCV如何實(shí)現(xiàn)基于顏色的目標(biāo)識(shí)別

Python+OpenCV如何實(shí)現(xiàn)基于顏色的目標(biāo)識(shí)別

關(guān)于Python+OpenCV如何實(shí)現(xiàn)基于顏色的目標(biāo)識(shí)別就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI