opencv计算机视觉学习笔记七
?
第八章 目標(biāo)跟蹤
?
1檢測(cè)目標(biāo)的移動(dòng)
基本的運(yùn)動(dòng)檢測(cè),示例代碼如下:
import cv2 import numpy as np# 捕獲攝像頭圖像 camera = cv2.VideoCapture(0) # es = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10, 10)) kernel = np.ones((5, 5), np.uint8) background = Nonewhile (True):ret, frame = camera.read()# 將第一幀設(shè)為圖像的背景if background is None:# 轉(zhuǎn)換顏色空間background = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 高斯模糊background = cv2.GaussianBlur(background, (21, 21), 0)continue# 轉(zhuǎn)換顏色空間并作模糊處理gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)gray_frame = cv2.GaussianBlur(gray_frame, (21, 21), 0)# 取得差分圖diff = cv2.absdiff(background, gray_frame)diff = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY)[1]# 膨脹diff = cv2.dilate(diff, es, iterations=2)# 得到圖像中目標(biāo)的輪廓image, cnts, hierarchy = cv2.findContours(diff.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)for c in cnts:if cv2.contourArea(c) < 1500:continue# 計(jì)算矩形邊框(x, y, w, h) = cv2.boundingRect(c)# 繪制矩形cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)# 顯示圖像cv2.imshow('contours', frame)cv2.imshow('dif', diff)if cv2.waitKey(int(1000 / 12)) & 0xFF == ord('q'):break cv2.destroyAllWindows() camera.release()?
?
運(yùn)行結(jié)果如下:
?
2背景分割器 knn mog2和GMG
Opencv3有三種背景分割器
K-nearest(knn)
Mixture of Gaussians(MOG2)
Geometric multigid(GMC)
?
backgroundSubtractor用于分割前景和背景
示例代碼如下:
import cv2 import numpy as npcv2.ocl.setUseOpenCL(False)cap = cv2.VideoCapture(0) mog = cv2.createBackgroundSubtractorMOG2()while (True):ret, frame = cap.read()fgmask = mog.apply(frame)cv2.imshow('frame', fgmask)if cv2.waitKey(30) & 0xFF == ord('q'):breakcap.release() cv2.destroyAllWindows()?
運(yùn)行結(jié)果如下:
?
使用backgroundSubtractorKNN來實(shí)現(xiàn)運(yùn)動(dòng)檢測(cè)
示例代碼如下:
import cv2cv2.ocl.setUseOpenCL(False)bs = cv2.createBackgroundSubtractorKNN(detectShadows=True) # 讀取本地視頻 camera = cv2.VideoCapture('../traffic.flv')while (True):ret, frame = camera.read()fgmask = bs.apply(frame.copy())# 設(shè)置閾值th = cv2.threshold(fgmask,? # 源圖像244,? # 閾值255,? # 最大值cv2.THRESH_BINARY)[1]? # 閾值類型# 膨脹dilated = cv2.dilate(th,? # 源圖像cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)),? # 內(nèi)核iterations=2)? # 腐蝕次數(shù)# 查找圖像中的目標(biāo)輪廓image, contours, hier = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)for c in contours:if cv2.contourArea(c) > 1600:(x, y, w, h) = cv2.boundingRect(c)cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2)cv2.imshow('mog', fgmask)? # 分割前景與背景cv2.imshow('thresh', th)? #cv2.imshow('detection', frame)? # 運(yùn)動(dòng)檢測(cè)結(jié)果if cv2.waitKey(30) & 0xFF == 27:break camera.release() cv2.destroyAllWindows()?
?
?
?
運(yùn)行結(jié)果如下:
?
?均值漂移meanShift
示例代碼如下:
import cv2 import numpy as np# 取得攝像頭圖像 cap = cv2.VideoCapture(0) ret, frame = cap.read()# 設(shè)置跟蹤窗體大小 r, h, c, w = 10, 200, 10, 200 track_window = (c, r, w, h)# 提取roi roi = frame[r:r + h, c:c + w] # 轉(zhuǎn)換顏色空間 hsv_roi = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # 根據(jù)閾值構(gòu)建掩碼 mask = cv2.inRange(hsv_roi, np.array((100., 30., 32.)), np.array((180., 120., 255.)))# 計(jì)算roi圖形的彩色直方圖 roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0, 180]) cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX) # 指定停止條件 term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)while (True):ret, frame = cap.read()if ret == True:# 更換顏色空間hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)# histogram back projection calculation 直方圖反向投影dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)# 均值漂移ret, track_window = cv2.meanShift(dst, track_window, term_crit)# 繪制矩形顯示圖像x, y, w, h = track_windowimg2 = cv2.rectangle(frame, (x, y), (x + w, y + h), 255, 2)cv2.imshow('img2', img2)# esc退出if cv2.waitKey(60) & 0xFF == 27:breakelse:break cv2.destroyAllWindows() cap.release()?
運(yùn)行結(jié)果如下:
?
?
彩色直方圖
?
calHist函數(shù)
函數(shù)原型:
def calcHist(images, #源圖像 ????????????? channels, #通道列表 ?????????????? mask,#可選的掩碼 ????????????? histSize, #每個(gè)維度下直方圖數(shù)組的大小 ?????????????? ranges,#每一個(gè)維度下直方圖bin的上下界的數(shù)組 ????????????? hist=None,#輸出直方圖是一個(gè)[]維稠密度的數(shù)組 ????????????? accumulate=None)#累計(jì)標(biāo)志?
?
Camshift
示例代碼如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time??? : 2016/12/15 16:48 # @Author? : Retacn # @Site??? : camshift實(shí)現(xiàn)物體跟蹤 # @File??? : camshift.py # @Software: PyCharm __author__ = "retacn" __copyright__ = "property of mankind." __license__ = "CN" __version__ = "0.0.1" __maintainer__ = "retacn" __email__ = "zhenhuayue@sina.com" __status__ = "Development"import cv2 import numpy as np# 取得攝像頭圖像 cap = cv2.VideoCapture(0) ret, frame = cap.read()# 設(shè)置跟蹤窗體大小 r, h, c, w = 300, 200, 400, 300 track_window = (c, r, w, h)# 提取roi roi = frame[r:r + h, c:c + w] # 轉(zhuǎn)換顏色空間 hsv_roi = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # 根據(jù)閾值構(gòu)建掩碼 mask = cv2.inRange(hsv_roi, np.array((100., 30., 32.)), np.array((180., 120., 255.)))# 計(jì)算roi圖形的彩色直方圖 roi_hist = cv2.calcHist([hsv_roi], [0], mask, [180], [0, 180]) cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX) # 指定停止條件 term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)while (True):ret, frame = cap.read()if ret == True:# 更換顏色空間hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)# histogram back projection calculation 直方圖反向投影dst = cv2.calcBackProject([hsv], [0], roi_hist, [0, 180], 1)# 均值漂移ret, track_window = cv2.CamShift(dst, track_window, term_crit)# 繪制矩形顯示圖像pts = cv2.boxPoints(ret)pts = np.int0(pts)img2 = cv2.polylines(frame, [pts], True, 255, 2)cv2.imshow('img2', img2)# esc退出if cv2.waitKey(60) & 0xFF == 27:breakelse:break cv2.destroyAllWindows() cap.release()?
運(yùn)行結(jié)果如下:
?
4 卡爾曼濾波器
函數(shù)原型為:
def KalmanFilter(dynamParams=None,#狀態(tài)的維度 ????????????? measureParams=None, #測(cè)量的維度 ?????????????? controlParams=None,#控制的維度 ????????????? type=None)#矩陣的類型?
示例代碼如下:
import cv2 import numpy as np# 創(chuàng)建空幀 frame = np.zeros((800, 800, 3), np.uint8)# 測(cè)量坐標(biāo) last_measurement = current_measurement = np.array((2, 1), np.float32) # 鼠標(biāo)運(yùn)動(dòng)預(yù)測(cè) last_prediction = current_predication = np.zeros((2, 1), np.float32)def mousemove(event, x, y, s, p):# 設(shè)置全局變量global frame, measurements, current_measurement, last_measurement, current_predication, last_predictionlast_prediction = current_predicationlast_measurement = current_measurementcurrent_measurement = np.array([[np.float32(x)], [np.float32(y)]])kalman.correct(current_measurement)current_predication = kalman.predict()# 實(shí)際移動(dòng)起始點(diǎn)lmx, lmy = last_measurement[0], last_measurement[1]cmx, cmy = current_measurement[0], current_measurement[1]# 預(yù)測(cè)線起止點(diǎn)lpx, lpy = last_prediction[0], last_prediction[1]cpx, cpy = current_predication[0], current_predication[1]# 繪制連線cv2.line(frame, (lmx, lmy), (cmx, cmy), (0, 100, 0))? # 綠色cv2.line(frame, (lpx, lpy), (cpx, cpy), (0, 0, 200))? # 紅色# 創(chuàng)建窗體 cv2.namedWindow('mouse_detection') # 注冊(cè)鼠標(biāo)事件的回調(diào)函數(shù) cv2.setMouseCallback('mouse_detection', mousemove)# 卡爾曼濾波器 kalman = cv2.KalmanFilter(4, 2) kalman.measurementMatrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0]], np.float32) kalman.transitionMatrix = np.array([[1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32) kalman.processNoiseCov = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32) * 0.03while (True):cv2.imshow('mouse_detection', frame)if cv2.waitKey(30) & 0xFF == 27:breakcv2.destroyAllWindows()?
?
運(yùn)行結(jié)果如下:
一個(gè)基于行人跟蹤的例子
示例代碼如下:
import cv2 import numpy as np import os.path as path import argparsefont = cv2.FONT_HERSHEY_SIMPLEXparser = argparse.ArgumentParser() parser.add_argument("-a", "--algorithm",help="m (or nothing) for meanShift and c for camshift") args = vars(parser.parse_args())# 計(jì)算矩陣中心(行人位置) def center(points):x = (points[0][0] + points[1][0] + points[2][0] + points[3][0]) / 4y = (points[0][1] + points[1][1] + points[2][1] + points[3][1]) / 4# print(np.array([np.float32(x), np.float32(y)], np.float32))# [ 588.?? 257.5]return np.array([np.float32(x), np.float32(y)], np.float32)# 行人 class Pedestrian():def __init__(self, id, frame, track_window):self.id = int(id)? # 行人idx, y, w, h = track_window? # 跟蹤窗體self.track_window = track_window# 更換顏色空間self.roi = cv2.cvtColor(frame[y:y + h, x:x + w], cv2.COLOR_BGR2HSV)# 計(jì)算roi圖形的彩色直方圖roi_hist = cv2.calcHist([self.roi], [0], None, [16], [0, 180])self.roi_hist = cv2.normalize(roi_hist, roi_hist, 0, 255, cv2.NORM_MINMAX)# 設(shè)置卡爾曼濾波器self.kalman = cv2.KalmanFilter(4, 2)self.kalman.measurementMatrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0]], np.float32)self.kalman.transitionMatrix = np.array([[1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32)self.kalman.processNoiseCov = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]],np.float32) * 0.03# 測(cè)量坐標(biāo)self.measurement = np.array((2, 1), np.float32)# 鼠標(biāo)運(yùn)動(dòng)預(yù)測(cè)self.predication = np.zeros((2, 1), np.float32)# 指定停止條件self.term_crit = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1)self.center = Noneself.update(frame)def __del__(self):print('Pedestrian %d destroyed' % self.id)# 更新圖像幀def update(self, frame):# 更換顏色空間hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)# histogram back projection calculation 直方圖反向投影back_project = cv2.calcBackProject([hsv], [0], self.roi_hist, [0, 180], 1)# camshiftif args.get('algorithm') == 'c':ret, self.track_window = cv2.CamShift(back_project, self.track_window, self.term_crit)# 繪制跟蹤框pts = cv2.boxPoints(ret)pts = np.int0(pts)self.center = center(pts)cv2.polylines(frame, [pts], True, 255, 1)# 均值漂移if not args.get('algorithm') or args.get('algorithm') == 'm':ret, self.track_window = cv2.meanShift(back_project, self.track_window, self.term_crit)# 繪制跟蹤框x, y, w, h = self.track_windowself.center = center([[x, y], [x + w, y], [x, y + h], [x + w, y + h]])cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2)self.kalman.correct(self.center)prediction = self.kalman.predict()cv2.circle(frame, (int(prediction[0]), int(prediction[1])), 4, (0, 255, 0), -1)# 計(jì)數(shù)器cv2.putText(frame, 'ID: %d --> %s' % (self.id, self.center), (11, (self.id + 1) * 25 + 1), font, 0.6, (0, 0, 0),1, cv2.LINE_AA)# 跟蹤窗口坐標(biāo)cv2.putText(frame, 'ID: %d --> %s' % (self.id, self.center), (10, (self.id + 1) * 25), font, 0.6, (0, 255, 0),1, cv2.LINE_AA)def main():# 加載視頻# camera = cv2.VideoCapture('../movie.mpg')# camera = cv2.VideoCapture('../traffic.flv')camera = cv2.VideoCapture('../768x576.avi')# 初始化背景分割器history = 20bs = cv2.createBackgroundSubtractorKNN(detectShadows=True)# 創(chuàng)建顯示主窗口cv2.namedWindow('surveillance')pedestrians = {}? # 行人字典firstFrame = Trueframes = 0fourcc = cv2.VideoWriter_fourcc(*'XVID')out = cv2.VideoWriter('../output.avi', fourcc, 20.0, (640, 480))while (True):print('----------------------frmae %d----------------' % frames)grabbed, frane = camera.read()if (grabbed is False):print("failed to grab frame")breakret, frame = camera.read()fgmask = bs.apply(frame)if frames < history:frames += 1continue# 設(shè)置閾值th = cv2.threshold(fgmask.copy(), 127, 255, cv2.THRESH_BINARY)[1]# 腐蝕th = cv2.erode(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3)), iterations=2)# 膨脹dilated = cv2.dilate(th, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (8, 3)), iterations=2)# 查找輪廓image, contours, hier = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)counter = 0for c in contours:if cv2.contourArea(c) > 500:# 邊界數(shù)組(x, y, w, h) = cv2.boundingRect(c)# 繪制矩形cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 1)if firstFrame is True:pedestrians[counter] = Pedestrian(counter, frame, (x, y, w, h))counter += 1# 更新幀內(nèi)容for i, p in pedestrians.items():p.update(frame)# false 只跟蹤已有的行人# firstFrame = TruefirstFrame = Falseframes += 1# 顯示cv2.imshow('surveillance', frame)out.write(frame)if cv2.waitKey(120) & 0xFF == 27:? # esc退出breakout.release()camera.release()if __name__ == "__main__":main()?
?
運(yùn)行結(jié)果如下:
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/retacn-yue/p/6194151.html
總結(jié)
以上是生活随笔為你收集整理的opencv计算机视觉学习笔记七的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 白衣服被火锅油弄到发黄怎么办?
- 下一篇: Bootstrap的全局css样式部分