1. cv2.cvtcolor(img, cv2.COLOR_BGR2GRAY) # 將彩色圖轉換為灰度圖
參數說明: img表示輸入的圖片, cv2.COLOR_BGR2GRAY表示顏色的變換形式
2. cv2.findContours(img,mode, method) # 找出圖中的輪廓值,得到的輪廓值都是嵌套格式的
參數說明:img表示輸入的圖片,mode表示輪廓檢索模式,通常都使用RETR_TREE找出所有的輪廓值,method表示輪廓逼近方法,使用NONE表示所有輪廓都顯示
3. cv2.drawCountours(img, contours, -1, (0, 0, 255), 2) # 畫出圖片中的輪廓值,也可以用來畫輪廓的近似值
參數說明:img表示輸入的需要畫的圖片, contours表示輪廓值,-1表示輪廓的索引,(0, 0, 255)表示顏色, 2表示線條粗細
4. cv2.contourArea(cnt, True) # 計算輪廓的面積
參數說明:cnt為輸入的單個輪廓值
5. cv2.arcLength(cnt, True) # 計算輪廓的周長
參數說明:cnt為輸入的單個輪廓值
6. cv2.aprroxPolyDP(cnt, epsilon, True) # 用於獲得輪廓的近似值,使用cv2.drawCountors進行畫圖操作
參數說明:cnt為輸入的輪廓值, epsilon為閾值T,通常使用輪廓的周長作為閾值,True表示的是輪廓是閉合的
7. x, y, w, h = cv2.boudingrect(cnt) # 獲得外接矩形
參數說明:x,y, w, h 分別表示外接矩形的x軸和y軸的坐標,以及矩形的寬和高, cnt表示輸入的輪廓值
8 cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) # 根據坐標在圖像上畫出矩形
參數說明: img表示傳入的圖片, (x, y)表示左上角的位置, (x+w, y+h)表示加上右下角的位置,(0, 255, 0)表示顏色,2表示線條的粗細
9. (x, y), radius = cv2.minEnclosingCircle(cnt) # 獲得外接圓的位置信息
參數說明: (x, y)表示外接圓的圓心,radius表示外接圓的半徑, cnt表示輸入的輪廓
10. cv2.Cricle(img, center, radius, (0, 255, 0), 2) # 根據坐標在圖上畫出圓
參數說明:img表示需要畫的圖片,center表示圓的中心點,radius表示圓的半徑, (0, 255, 0)表示顏色, 2表示線條的粗細
輪廓檢測:輪廓檢測相較於canny邊緣檢測,輪廓檢測的線條要更少一些,在opencv中,使用的函數是cv2.findCountor進行輪廓檢測
上圖是輪廓檢測過程中所使用的方法,一般我們使用mode RETR_TREE檢測出所有的輪廓值, 對於method方法的區別在一種把邊緣都檢測出來,一種壓縮在拐點位置
1.輪廓檢測與畫圖:
代碼:
第一步:載入圖片
第二步:使用cv2.cvtcolor() 將圖片轉換為灰度圖
第三步: 使用cv2.threshold將圖片做二值化轉換
第四步: 使用cv2.findContours 找出圖片的輪廓值
第五步:使用cv2.drawContours在圖片上畫上輪廓
第六步: 使用cv2.imshow 完成畫圖操作
import cv2 import numpy as np def cv_show(img, name): cv2.imshow(name, img) cv2.waitKey(0) cv2.destroyAllWindows() # 第一步讀入圖片 img = cv2.imread('car.png') # 第二步:對圖片做灰度變化 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 第三步:對圖片做二值變化 ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 第四步:獲得圖片的輪廓值 Binary, contours, h = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) # 第五步:在圖片中畫出圖片的輪廓值 draw_img = img.copy() ret = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2) # 第六步:畫出帶有輪廓的原始圖片 cv_show(ret, 'ret')
2. 輪廓的周長和面積
使用cv2.findCountor獲得的輪廓contours是一個嵌套的類型,即我們可以通過cnt = contours獲得第一個物體的輪廓值
代碼:
第一步:載入圖片,做灰度值和二值化處理,並使用cv2.findCountor找出輪廓值,使用cv2.drawCountors畫出第一個圖像的輪廓
第二步:通過索引取出第一個輪廓值cnt,使用cv2.ContourArea()計算輪廓的面積
第三步:使用cv2.arcLength 獲得輪廓的周長
# 使用另外一個圖進行輪廓的測試 # 第一步:載入圖片,灰度化和二值化處理,使用cv2.findContours找出輪廓, 使用cv2.drawContours進行畫圖操作 img = cv2.imread('contours.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) binary, contours, h = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) draw_img = img.copy() # 參數說明,draw_img 需要作圖的原始圖像, contours表示輪廓, 0表示輪廓索引, (0, 0, 255)表示顏色, 2表示線條粗細 ret = cv2.drawContours(draw_img, contours, 0, (0, 0, 255), 2) cv_show(ret, 'ret') # 取出單個的輪廓值 cnt = contours[0] # 第二步:計算輪廓的面積 area = cv2.contourArea(cnt) # 第三步: 計算輪廓的周長 length= cv2.arcLength(cnt, True) print(area, length)
3. 輪廓近似(RDP), 假設存在一個曲線A, B,在曲線上存在一個C點,離AB線段的距離最遠,記為d1, 如果d1 < T(自己設定的閾值), 將AB線段作為AB曲線的替代,否者連接AC和BC, 計算AC線段上的D點離AB距離最遠,記為d2,如果d2 < T,則使用AC線段替代AC曲線,否者繼續連接划分
代碼:
第一步:讀取圖片,灰度化和二值化,使用cv2.findcontours找出輪廓
第二步:使用輪廓索引提取第一個輪廓值
第三步:使用cv2.arcLength即輪廓周長的倍數作為閾值,閾值越小,輪廓與輪廓的越近似
第四步:使用cv2.approxPolyDP(cnt, epilison)
第五步:使用cv2.drawContours進行畫圖操作
import cv2 import numpy as np def cv_show(img, name): cv2.imshow(name, img) cv2.waitKey(0) cv2.destroyAllWindows() # 第一步讀入圖片 img = cv2.imread('car.png') # 第二步:對圖片做灰度變化 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 第三步:對圖片做二值變化 ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 第四步:獲得圖片的輪廓值 Binary, contours, h = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) # 第五步:在圖片中畫出圖片的輪廓值 draw_img = img.copy() ret = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2) # 第六步:畫出帶有輪廓的原始圖片 cv_show(ret, 'ret') # 使用另外一個圖進行輪廓的測試 # 第一步:載入圖片,灰度化和二值化處理,使用cv2.findContours找出輪廓, 使用cv2.drawContours進行畫圖操作 img = cv2.imread('contours.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) binary, contours, h = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) draw_img = img.copy() # 參數說明,draw_img 需要作圖的原始圖像, contours表示輪廓, 0表示輪廓索引, (0, 0, 255)表示顏色, 2表示線條粗細 ret = cv2.drawContours(draw_img, contours, 0, (0, 0, 255), 2) cv_show(ret, 'ret') # 取出單個的輪廓值 cnt = contours[0] # 第二步:計算輪廓的面積 area = cv2.contourArea(cnt) # 第三步: 計算輪廓的周長 length= cv2.arcLength(cnt, True) print(area, length) # 輪廓近似 img = cv2.imread('contours2.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) Binary, contours, h = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) cnt = contours[0] # 使用周長的倍數作為閾值,閾值越小,圖像的輪廓近似與輪廓越近似 epsilon = 0.1 * cv2.arcLength(cnt, True) approx = cv2.approxPolyDP(cnt, epsilon, True) draw_img = img.copy() ret = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2) cv_show(ret, 'ret')
4. 外接矩形和外接圓
外接矩形: 使用cv2.boudingrect(cnt)獲得輪廓的外接矩形,使用cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), 2)畫出矩陣的輪廓
外接圓: 使用cv2.minEnclosingCircle(cnt)獲得輪廓的外接圓,使用cv2.circle(ret, centers, radius, (0, 0, 255), 2)畫出圓的輪廓
代碼:
第一步:載入圖片,灰度化,二值化,使用cv2.findCountors找出圖像的輪廓,使用輪廓索引獲得第一個輪廓cnt
第二步:使用cv2.boundingrect(cnt) ,獲得輪廓的x,y,w, h (x, y)表示左上角的坐標,w為寬,h為長
第三步: 使用cv2.rectangle 繪制外接的輪廓
第四步: 使用cv2.minEnclosingCircle(cnt), 獲得center和radius,即圓心點的坐標和圓的半徑
第五步: 使用cv2.circle(img, center, radius, (0, 0, 255), 2) 繪制圓心的外接輪廓
# 外接矩陣 img = cv2.imread('contours.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) res, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) binary, contours, h = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) cnt = contours[0] x, y, w, h = cv2.boundingRect(cnt) ret = cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), 2) cv_show(ret, 'ret') print('矩形面積 / 外接矩形面積', cv2.contourArea(cnt) / (w*h)) # 外接圓
(x, y), radius = cv2.minEnclosingCircle(cnt) center = (int(x), int(y)) radius = int(radius) ret = cv2.circle(ret, center, radius, (0, 255, 0), 2) cv_show(ret, 'ret')