天天看點

Python-OpenCV分割圖像查枸杞的個數

圖像分割算法有分水嶺算法、斑點計數算法、霍夫圓/橢圓算法、輪廓檢測算法等。在本文中,本例使用了輪廓檢測和分水嶺算法。

Python-OpenCV分割圖像查枸杞的個數

第一步導入依賴

from __future__ import print_function

import numpy as np

import cv2

import matplotlib.pyplot as plt

from skimage import io

from skimage.morphology import watershed

from skimage.feature import peak_local_max

from scipy import ndimage

建立可視化圖像函數:

def show(img):

   plt.imshow(img)

   plt.show()

讀取圖像

#load

fp = "1.jpg"

img = cv2.imread(fp)

show(img)

print(img.shape)

對圖像進行預處理。步驟包括:

HSV,這是人眼感覺的顔色模型。

門檻值技術,通過標明的門檻值像素強度将圖像轉換為二值圖像(即隻有2個像素值(0或255))。

模糊圖像,以删除圖像中不必要的斑點。

#preprocessing the image

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

show(hsv)

Python-OpenCV分割圖像查枸杞的個數

現在我們使用輪廓檢測,在我們“模糊”的圖像中找到枸杞。為了去除小的和無關緊要的輪廓,我們隻選擇那些面積大于2000的輪廓(任意值,是超參數)。

contours, hierarchy = cv2.findContours(blur,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

copy2 = img.copy()

count = []

for x in contours:

   area = cv2.contourArea(x)

   if area > 2000 :

       count.append(x)

cv2.drawContours(copy2, count, -1, (255,0,0), 3)

show(copy2)

print("number of lemons found via contour detection = ", len(count))

完整代碼:

h, s, v = cv2.split(hsv)

show(s)

_, thr = cv2.threshold(s, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

show(thr)

blur = cv2.medianBlur(thr, 5)

show(blur)

copy3 = img.copy()

D = ndimage.distance_transform_edt(thr)

localMax = peak_local_max(D, indices=False, min_distance=300,

  labels=thr)

markers = ndimage.label(localMax, structure=np.ones((3, 3)))[0]

labels = watershed(-D, markers, mask=thr)

ws = len(np.unique(labels)) -1

copy3[labels == -1] = [255,0,0]

print("no. of lemons found via watershed algorithm = ", ws)

ans = int((len(count) + len(np.unique(labels)) -1) / 2)

print("number of lemon segments detected = ", ans)