From:4 Image Segmentation Techniques in OpenCV Python - 2021.09.07

图像分割

图像分割任务是,将图像分割或分区到多个区域,且具有相同特性的像素被划分到相同区域.

图像分割有两种形式,

  • 局部分割(Local segmentation) - 关注于图像的特定区域
  • 全局分割(Global segmentation)- 关注于图像的全部区域

图像分割技术

[1] - 不连续性检测(Discontinuity detection)

基于 discontinuity,将图像划分为不同区域. 边缘检测的用武之地.

由于强度而产生的边缘不连续性被识别,并用于建立区域边界,如,直方图过滤(Histogram filtering) 和轮廓检测(contour detection).

[2] - 相似性检测(Similarity detection)

基于相似性(resemblance)将图像划分为不同区域.

阈值化(Thresholding)、区域扩展(area expansion)、区域拆分和合并(region splitting and merging)等,都属于该类.

根据既定规则,将图片话费为一组具有可区分特征的集群(cluster),如,Kmeans、颜色检测/分类.

[3] - 神经网络方法

这里主要基于 OpenCV 和 Scikit-learn 实现四种图像分割:

  • 基于 K-means
  • 基于 Contour Detection
  • 基于 Thresholding
  • 基于 Color Masking

测试例示图片,

基于 K-means 图像分割

import matplotlib as plt import numpy as np import cv2 path = 'image.jpg' img = cv2.imread(path) img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB) twoDimage = img.reshape((-1,3)) twoDimage = np.float32(twoDimage) criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) K = 2 attempts=10 #Kmeans ret,label,center=cv2.kmeans(twoDimage,K,None,criteria,attempts,cv2.KMEANS_PP_CENTERS) center = np.uint8(center) res = center[label.flatten()] result_image = res.reshape((img.shape))

输出如:

基于轮廓检测(Contour Detection)

import cv2 import matplotlib.pyplot as plt import numpy as np path = 'image.jpg' img = cv2.imread(path) img = cv2.resize(img,(256,256)) #图像预处理 gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY) _,thresh = cv2.threshold(gray, np.mean(gray), 255, cv2.THRESH_BINARY_INV) edges = cv2.dilate(cv2.Canny(thresh,0,255),None) #轮廓检测 cnt = sorted(cv2.findContours(edges, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[-2], key=cv2.contourArea)[-1] #轮廓检测与排序 mask = np.zeros((256,256), np.uint8) masked = cv2.drawContours(mask, [cnt],-1, 255, -1) #区域分割 dst = cv2.bitwise_and(img, img, mask=mask) segmented = cv2.cvtColor(dst, cv2.COLOR_BGR2RGB)

输出如:

基于阈值(Thresholding)

import numpy as np import matplotlib.pyplot as plt from skimage.filters import threshold_otsu import cv2 path ='image.jpg' img = cv2.imread(path) img_rgb=cv2.cvtColor(img,cv2.COLOR_BGR2RGB) img_gray=cv2.cvtColor(img_rgb,cv2.COLOR_RGB2GRAY) def filter_image(image, mask): r = image[:,:,0] * mask g = image[:,:,1] * mask b = image[:,:,2] * mask return np.dstack([r,g,b]) thresh = threshold_otsu(img_gray) #找阈值 img_otsu = img_gray < thresh filtered = filter_image(img, img_otsu)

输出如:

基于颜色掩码(color mask)

import cv2 path ='image.jpg' img = cv2.imread(path) rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) hsv_img = cv2.cvtColor(rgb_img, cv2.COLOR_RGB2HSV) #定义HSV颜色区间范围 #blue light_blue = (90, 70, 50) dark_blue = (128, 255, 255) #green # light_green = (40, 40, 40) # dark_greek = (70, 255, 255) mask = cv2.inRange(hsv_img, light_blue, dark_blue) result = cv2.bitwise_and(img, img, mask=mask)

输出如,

Last modification:December 14th, 2021 at 01:12 pm