OpenCV是一個巨大的開源庫,廣泛用于計算機視覺,人工智能和圖像處理領(lǐng)域。它在現(xiàn)實世界中的典型應(yīng)用是人臉識別,物體檢測,人類活動識別,物體跟蹤等。
現(xiàn)在,假設(shè)我們只需要從整個輸入幀中檢測到一個對象。因此,代替處理整個框架,如果可以在框架中定義一個子區(qū)域并將其視為要應(yīng)用處理的新框架,該怎么辦。我們要完成一下三個步驟:
?定義興趣區(qū)
?在ROI中檢測輪廓
?閾值檢測輪廓輪廓線
什么是ROI?
簡而言之,我們感興趣的對象所在的幀內(nèi)的子區(qū)域稱為感興趣區(qū)域(ROI)。
我們?nèi)绾味xROI?
在輸入幀中定義ROI的過程稱為ROI分割。
在“ ROI細(xì)分”中,(此處)我們選擇框架中的特定區(qū)域,并以矩形方法提供其尺寸,以便它將在框架上繪制矩形的ROI。
(輸出)藍(lán)色矩形覆蓋的區(qū)域是我們的投資回報率
現(xiàn)在,如果您也想綁定感興趣的對象,那么我們可以通過在ROI中找到輪廓來實現(xiàn)。
什么是輪廓?
輪廓線是表示或說是限制對象形狀的輪廓。
如何在框架中找到輪廓?
對我而言,在將ROI框架設(shè)為閾值后,找到輪廓效果最佳。因此,要找到輪廓,手上的問題是-
什么是閾值?
閾值不過是圖像分割的一種簡單形式。這是將灰度或rgb圖像轉(zhuǎn)換為二進制圖像的過程。例如
(這是RGB幀)
(這是二進制閾值幀)
因此,在對rgb幀進行閾值處理后,程序很容易找到輪廓,因為由于ROI中感興趣對象的顏色將是黑色(在簡單的二進制脫粒中)或白色(在如上所述的反向二進制脫粒中),因此分割(將背景與前景即我們的對象分開)將很容易完成。
在對框架進行閾值處理并檢測到輪廓之后,我們應(yīng)用凸包技術(shù)對圍繞對象點的緊密擬合凸邊界進行設(shè)置。實施此步驟后,框架應(yīng)如下所示-
我們可以做的另一件事是,我們可以遮蓋ROI以僅顯示被檢測到的輪廓本身覆蓋的對象。再次-
什么是圖像MASK?
圖像MASK是隱藏圖像的某些部分并顯示某些部分的過程。這是圖像編輯的非破壞性過程。在大多數(shù)情況下,它使您可以在以后根據(jù)需要調(diào)整和調(diào)整遮罩。通常,它是一種有效且更具創(chuàng)意的圖像處理方式。
因此,基本上在這里我們將掩蓋ROI的背景。為此,首先我們將修復(fù)ROI的背景。然后,在固定背景之后,我們將從框架中減去背景,并用wewant背景(這里是一個簡單的黑色框架)替換它。
實施上述技術(shù),我們應(yīng)該得到如下輸出:
(背景被遮罩以僅捕獲對象)
這是所說明技術(shù)的理想實現(xiàn)的完整代碼。
import cv2
import numpy as np
import copy
import math
x=0.5 # start point/total width
y=0.8 # start point/total width
threshold = 60 # BINARY threshold
blurValue = 7 # GaussianBlur parameter
bgSubThreshold = 50
learningRate = 0
# variables
isBgCaptured = 0 # whether the background captured
def removeBG(frame): #Subtracting the background
fgmask = bgModel.apply(frame,learningRate=learningRate)
kernel = np.ones((3, 3), np.uint8)
fgmask = cv2.erode(fgmask, kernel, iterations=1)
res = cv2.bitwise_and(frame, frame, mask=fgmask)
return res
# Camera
camera = cv2.VideoCapture(0)
camera.set(10,200)
while camera.isOpened():
ret, frame = camera.read()
frame = cv2.bilateralFilter(frame, 5, 50, 100) # smoothening filter
frame = cv2.flip(frame, 1) # flip the frame horizontally
cv2.rectangle(frame, (int(x * frame.shape[1]), 0),
(frame.shape[1], int(y * frame.shape[0])), (255, 0, 0), 2) #drawing ROI
cv2.imshow('original', frame)
# Main operation
if isBgCaptured == 1: # this part wont run until background captured
img = removeBG(frame)
img = img[0:int(y * frame.shape[0]),
int(x * frame.shape[1]):frame.shape[1]] # clip the ROI
cv2.imshow('mask', img)
# convert the image into binary image
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (blurValue, blurValue), 0)
cv2.imshow('blur', blur)
ret, thresh = cv2.threshold(blur, threshold, 255, cv2.THRESH_BINARY) #thresholding the frame
cv2.imshow('ori', thresh)
# get the coutours
thresh1 = copy.deepcopy(thresh)
contours, hierarchy = cv2.findContours(thresh1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #detecting contours
length = len(contours)
maxArea = -1
if length > 0:
for i in range(length): # find the biggest contour (according to area)
temp = contours[i]
area = cv2.contourArea(temp)
if area > maxArea:
maxArea = area
ci = i
res = contours[ci]
hull = cv2.convexHull(res) #applying convex hull technique
drawing = np.zeros(img.shape, np.uint8)
cv2.drawContours(drawing, [res], 0, (0, 255, 0), 2) #drawing contours
cv2.drawContours(drawing, [hull], 0, (0, 0, 255), 3) #drawing convex hull
cv2.imshow('output', drawing)
# Keyboard OP
k = cv2.waitKey(10)
if k == 27:
camera.release()
cv2.destroyAllWindows()
break
elif k == ord('b'): # press 'b' to capture the background
bgModel = cv2.createBackgroundSubtractorMOG2(0, bgSubThreshold)
isBgCaptured = 1
print( 'Background Captured')
elif k == ord('r'): # press 'r' to reset the background
bgModel = None
isBgCaptured = 0
print('ResetBackGround')
審核編輯 :李倩
-
人臉識別
+關(guān)注
關(guān)注
76文章
4014瀏覽量
82084 -
OpenCV
+關(guān)注
關(guān)注
31文章
635瀏覽量
41420
原文標(biāo)題:基于OpenCV的區(qū)域分割、輪廓檢測和閾值處理
文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論