Python+OpenCV實(shí)現(xiàn)基于顏色的目標(biāo)識(shí)別
學(xué)習(xí)了一點(diǎn)opencv的知識(shí)于是找了個(gè)小項(xiàng)目來實(shí)踐一下。這里先說明一下,我的實(shí)現(xiàn)方法不見得是最好的(因?yàn)檫@只是一個(gè)用于練習(xí)的項(xiàng)目)僅作參考,也歡迎各位大佬指正。
任務(wù)
讓攝像頭識(shí)別到視野范圍內(nèi)的氣球并返回每個(gè)氣球的中心點(diǎn)坐標(biāo)。
因?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)
效果展示
顏色提取效果:
繪制外接矩形及中心點(diǎn)的效果:
到此這篇關(guān)于Python+OpenCV實(shí)現(xiàn)基于顏色的目標(biāo)識(shí)別的文章就介紹到這了,更多相關(guān)Python OpenCV基于顏色的目標(biāo)識(shí)別內(nèi)容請(qǐng)搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。