0
点赞
收藏
分享

微信扫一扫

Python-OpenCV分割图像查枸杞的个数


图像分割算法有分水岭算法、斑点计数算法、霍夫圆/椭圆算法、轮廓检测算法等。在本文中,本例使用了轮廓检测和分水岭算法。

Python-OpenCV分割图像查枸杞的个数_python


第一步导入依赖

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分割图像查枸杞的个数_opencv_02

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

show(s)

Python-OpenCV分割图像查枸杞的个数_深度学习_03

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

show(thr)

Python-OpenCV分割图像查枸杞的个数_计算机视觉_04

blur = cv2.medianBlur(thr, 5)

show(blur)

Python-OpenCV分割图像查枸杞的个数_深度学习_05


现在我们使用轮廓检测,在我们“模糊”的图像中找到枸杞。为了去除小的和无关紧要的轮廓,我们只选择那些面积大于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))

Python-OpenCV分割图像查枸杞的个数_深度学习_06


现在我们使用分水岭算法来分离相互接触的枸杞(如果有的话)。

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)

show(copy2)


Python-OpenCV分割图像查枸杞的个数_python_07

完整代码:

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)

#preprocessing the image

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

show(hsv)

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)

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

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)

show(copy2)

输出的结果如下:

Python-OpenCV分割图像查枸杞的个数_算法_08


参照:​​https://www.toutiao.com/i6824878001772036620/​​


举报

相关推荐

0 条评论