OpenCV的一些影象處理演算法
阿新 • • 發佈:2021-02-03
OpenCV的一些影象處理演算法
訓練完電賽滾球題,剛比完資料賽,總結一下用到的一些影象處理演算法
(寫到後面覺得好長,資料賽的寫在另一篇部落格https://blog.csdn.net/qq_45615475/article/details/112860120)
閾值提取
#定義各類顏色閾值範圍 import numpy as np #黑色 lower_black=np.array([0,0,0]) upper_black=np.array([180,255,46]) #灰色 lower_gray=np.array([0,0,46]) upper_gray=np.array([180,43,220]) #白色 lower_white=np.array([0,0,221]) upper_white=np.array([180,30,255]) #紅色 lower_red1=np.array([0,43,46]) upper_red1=np.array([10,255,255]) lower_red2=np.array([156,43,46]) upper_red2=np.array([180,255,255]) #橙色 lower_orange=np.array([11,43,46]) upper_orange=np.array([25,255,255]) #黃色 lower_yellow=np.array([26,43,46]) upper_yellow=np.array([34,255,255]) #青色 lower_qin=np.array([78,43,46]) upper_qin=np.array([99,255,255]) #藍色 lower_blue=np.array([100,43,46]) upper_blue=np.array([124,255,255]) #紫色 lower_purple=np.array([125,43,46]) upper_purple=np.array([155,255,255])
img_path='Test/Test1.png'
img=cv2.imread(img_path)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)#轉換為HSV空間
mask = cv2.inRange(hsv, lower_red, upper_red)#根據閾值提取紅色,想提取其他顏色就改為對應閾值即可
二值化
gray_img = cv2.cvtColor(cropped, cv2.COLOR_BGRA2GRAY)#影象灰度化 ret,thresh = cv2.threshold(gray_img,80,255,cv2.THRESH_BINARY)#需要設定提取閾值
霍夫圓檢測
小球識別一開始用的方案,但太耗時,最後還是直接色塊檢測
lower = np.array([0, 0, 0]) # 設定顏色的閾值下限
upper = np.array([120, 120, 120]) # 設定顏色的閾值上限
# 消除噪聲
mask = cv2.inRange(hsv, lower, upper) # 設定掩膜取值範圍
#bila = cv2.bilateralFilter(mask, 10, 200, 200) # 雙邊濾波消除噪聲
#opening = cv2.morphologyEx(bila, cv2.MORPH_OPEN, kernel) # 形態學開運算
#closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel) # 形態學開運算
#edges = cv2.Canny(closing, 50, 100) # 邊緣識別
edges = cv2.Canny(mask, 50, 100) # 邊緣識別
circles = cv2.HoughCircles(
edges, cv2.cv.CV_HOUGH_GRADIENT, 1, 100, param1=100, param2=10, minRadius=10, maxRadius=500)
if circles is not None: # 如果識別出圓
for circle in circles[0]:
# 獲取圓的座標與半徑
x = int(circle[0])
y = int(circle[1])
r = int(circle[2])
cv2.circle(frame, (x, y), r, (0, 0, 255), 3) # 標記圓
cv2.circle(frame, (x, y), 3, (255, 255, 0), -1) # 標記圓心
text = 'x: '+str(x)+' y: '+str(y)
cv2.putText(frame, text, (10, 30), font, 1, (0, 255, 0), 2) # 顯示圓心位置
else:
# 如果識別不出,顯示圓心不存在
cv2.putText(frame, 'x: None y: None', (10, 30), font, 1, (0, 255, 0), 2)
#輸入影象,輸出畫圓的影象
def Get_Circles(frame):
gray = cv2.cvtColor(frame, cv2.COLOR_BGRA2GRAY)
img = cv2.medianBlur(gray, 7)
circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 50, param1=100, param2=30, minRadius=70, maxRadius=200)#霍夫圓檢測
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0, :]: # 在圖片上畫圓和圓心
cv2.circle(frame, (i[0], i[1]), i[2], (0, 255, 0), 2)
cv2.circle(frame, (i[0], i[1]), 2, (0, 0, 255), 3)
return frame
#找紅球
def Get_Red_Circles(frame):
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, lower_red, upper_red)
res = cv2.bitwise_and(frame, frame, mask=mask)
gray = cv2.cvtColor(res, cv2.COLOR_BGRA2GRAY)
img = cv2.medianBlur(gray, 7)
circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 50, param1=100, param2=30, minRadius=70, maxRadius=200)#霍夫圓檢測
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0, :]: # 在圖片上畫圓和圓心
cv2.circle(frame, (i[0], i[1]), i[2], (0, 255, 0), 2)
cv2.circle(frame, (i[0], i[1]), 2, (0, 0, 255), 3)
return frame
色塊檢測
cnts = cv2.findContours(thresh1.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] #輪廓檢測
#如果存在輪廓
if len(cnts) > 0:
#找到面積最大的輪廓
c = max(cnts, key = cv2.contourArea)
#確定面積最大的輪廓的外接圓
((center_x, center_y), radius) = cv2.minEnclosingCircle(c)
#計算輪廓的矩
# M = cv2.moments(c)
#計算質心
cv2.circle(frame, (int(center_x), int(center_y)), int(radius), (0, 255, 255), 2)
cv2.circle(frame, None, 5, (0, 0, 255), -1)
print('紅色色塊的中心座標',(int(center_x),int(center_y)))
#通過二值化和色塊檢測得到小球座標
lower_red=np.array([156,43,46])
upper_red=np.array([180,255,255])
def Binary_Get_Ball(frame,show,area,thr):
cropped = frame[area[0]:area[1], area[2]:area[3]] #(上,下)(左,右)
gray_img = cv2.cvtColor(cropped, cv2.COLOR_BGRA2GRAY)#影象灰度化
ret,thresh=cv2.threshold(gray_img,thr[0],thr[1],cv2.THRESH_BINARY)
thresh=255-thresh
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2] #輪廓檢測
#如果存在輪廓
if len(cnts) > 0:
#找到面積最大的輪廓
c = max(cnts, key = cv2.contourArea)
#確定面積最大的輪廓的外接圓
((center_x, center_y), radius) = cv2.minEnclosingCircle(c)
if (show==True):
cv2.circle(cropped, (int(center_x), int(center_y)), int(radius), (0, 255, 255), 2)
cv2.circle(cropped, None, 5, (0, 0, 255), -1)
print('紅色色塊的中心座標',(int(center_x),int(center_y)))
else:
center_x=0
center_y=0
radius=0
return center_x,center_y,radius,cropped
電賽滾球題最終方案
可見我另一篇文章https://blog.csdn.net/qq_45615475/article/details/112859548
形態學開運算/閉運算
好像有以下程式碼可以執行
opening = cv2.morphologyEx(bila, cv2.MORPH_OPEN, kernel) # 形態學開運算
closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel) # 形態學閉運算
但我一般都是直接膨脹腐蝕(閉運算)或者腐蝕膨脹(開運算)看每一步的效果效果
#iterations為整數,可調,越大效果越強
no_img1 = cv2.dilate(no_img1, None, iterations=1)#膨脹
no_img1 = cv2.erode(no_img1, None, iterations=1)#腐蝕
濾波
雙邊濾波消除噪聲
bila = cv2.bilateralFilter(mask, 10, 200, 200) # 雙邊濾波消除噪聲 #
高斯濾波
中值模糊
img = cv.medianBlur(gay_img, 7) # 進行中值模糊,去噪點
edges = cv2.Canny(closing, 50, 100) # 邊緣識別
影象變換
gay_img = cv.cvtColor(planets, cv.COLOR_BGRA2GRAY)#影象灰度化
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)#轉換為HSV空間
透視變換
def PersTrans(frame,Center,frame_points): #透視變換,輸入為影象
rows,cols,channel = frame.shape
src_points = np.float32([Center[0],Center[1],Center[2],Center[3]])
dst_points = np.float32([[0,0],[cols-1,0],[0,rows-1],[cols-1,rows-1]])
projective_martix = cv2.getPerspectiveTransform(src_points,dst_points)
projective_image = cv2.warpPerspective(frame,projective_martix,(cols,rows))
return projective_image,projective_martix
影象擷取部分
cropped = img[30:440, 140:540] #(上,下)(左,右)