學習筆記(28):一學即懂的計算機視覺(第一季)-灰度閾值分割實戰演練

立即學習:https://edu.csdn.net/course/play/26281/327086?utm_source=blogtoedu

基於邊緣輪廓的分割:

在邊緣檢測的基礎上,基於閉合邊緣構建分割後的結果。邊緣檢測在二值化圖像上進行。

OpenCV相關函數:

mode參數說明:

CV.RETR_EXTERNAL:只檢測最外圍輪廓,包含在外圍輪廓內的內圍輪廓被忽略;

CV.RETR_LIST:檢測所有的輪廓,包括內圍、外圍輪廓,但是檢測到的輪廓不建立等級關係,彼此之間獨立,沒有等級關係,這就意味着這個檢索模式下不存在父輪廓或內嵌輪廓,所以hierarchy向量內所有元素的第3、第4個分量都會被置爲-1,具體下文會講到;

CV.RETR_CCOMP: 檢測所有的輪廓,但所有輪廓只建立兩個等級關係,外圍爲頂層,若外圍內的內圍輪廓還包含了其他的輪廓信息,則內圍內的所有輪廓均歸屬於頂層;

CV.RETR_TREE: 檢測所有輪廓,所有輪廓建立一個等級樹結構。外層輪廓包含內層輪廓,內層輪廓還可以繼續包含內嵌輪廓。

 method定義輪廓的近似方法,參數說明:

CV.CHAIN_APPROX_NONE:保存物體邊界上所有連續的輪廓點到contours向量內;

CV.CHAIN_APPROX_SIMPLE:僅保存輪廓的拐點信息,把所有輪廓拐點處的點保存入contours向量內,拐點與拐點之間直線段上的信息點不予保留;

CV.CHAIN_APPROX_TC89_L1:使用teh-Chinl chain 近似算法;

CV.CHAIN_APPROX_TC89_KCOS:使用teh-Chinl chain 近似算法。

閾值化:

cv.threshold(img, thresh, maxval, type[, dst])

參數說明:

img:原圖像。

thresh:進行分類的閾值。

maxval:是高於(低於)閾值時賦予的新值。

type:選擇的方法,具體定義如下:

 下面是實現代碼(ppt上findContours返回值應該是三個,少了圖像值):

import cv2 as cv
import matplotlib.pyplot as plt
import copy

filename="d:/Rice.png"
image = cv.imread(filename)
gray=cv.cvtColor(image, cv.COLOR_BGR2GRAY)
#使用大津算法灰度閾值化
thr,bw = cv.threshold(gray, 0, 0xff, cv.THRESH_OTSU)
print("threshold is ", thr)

#畫出灰度直方圖
plt.hist(gray.ravel(), 256, [0,256])
plt.show()

#預處理-形態學開運算
element = cv.getStructuringElement(cv.MORPH_CROSS, (3,3))
bw = cv.morphologyEx(bw, cv.MORPH_OPEN, element)
#拷貝一份
seg = copy.deepcopy(bw)
#計算輪廓
final, cnts, hier = cv.findContours(seg, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
count = 0
#遍歷所有區域,並去除面積過小的
for i in range(len(cnts), 0, -1):
    c = cnts[i-1]
    area = cv.contourArea(c)
    if area < 10:
        continue;
    count = count + 1
    #print("blob", i, " : ", area)
    
    #區域畫框並標記
    x,y,w,h = cv.boundingRect(c)
    cv.rectangle(image, (x,y), (x+w, y+h), (0,0,0xff), 1)
    cv.putText(image, str(count), (x,y), cv.FONT_HERSHEY_PLAIN, 0.5, (0, 0xff, 0))
print("米粒數量:", count)
cv.imshow("原圖", image)
cv.imshow("閾值化圖", bw)
cv.waitKey()
cv.destroyAllWindows()

結果如圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章