機器學習進階-圖像金字塔與輪廓檢測-輪廓檢測 1.cv2.cvtColor(圖像顏色轉換) 2.cv2.findContours(找出圖像的輪廓) 3.cv2.drawContours(畫出圖像輪廓) 4.cv2.contourArea(輪廓面積) 5.cv2.arcLength(輪廓周長) 6.cv2.aprroxPloyDP(獲得輪廓近似) 7.cv2.boudingrect(外接圓)..


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')


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM