用OpenCV进行图像分割--进阶篇

1. 引言

大家好,我的图像处理爱好者们! 在上一篇幅中,我们简单介绍了图像分割领域中的基础知识,包含基于固定阈值的分割和基于OSTU的分割算法。这一次,我们将通过介绍基于色度的分割来进一步巩固大家的基础知识。

闲话少说,我们直接开始吧!

2. RG-色度空间

基于色度的分割是指对每个像素的RGB值进行归一化处理,使我们的分割与光照条件无关。在开始之前,首先让我们讨论一下RG色度空间。它是一种二维的颜色表示,可以从我们的颜色中去除强度值,与标准的RGB空间的转化关系如下:

有的同学要问了,这里没有b, 实质上上述公式中, r 代表R在RGB中的占比,g代表G在RGB中的占比,剩下的 b 则是 1−r−g。

可视化出的结果图如下:

一般来说,我们可以RG色度空间应用到我们基础的图像分割任务中,我们接下来通过示例进行相关说明。

3. 导入样例图像

按照惯例,我们首先来导入本样例所需示例图像,代码如下:

cpp 复制代码
# Import the necessary libraries
from skimage.io import imread, imshow
import matplotlib.colors as colors
from skimage.color import rgb2gray
import matplotlib.pyplot as plt
import numpy as np
# Display the original image
original_image = imread('plants.jpg')
plt.figure(figsize=(20,20))
plt.imshow(original_image)
plt.title('Original Image', fontsize=20, weight='bold')
plt.show()

得到结果如下:

4. 转到RG色度空间

接着我们可以使用以下代码,实现原图到RG色度空间,代码如下:

cpp 复制代码
original_image_R = original_image[:,:,0]*1.0/original_image.sum(axis=2)
original_image_G = original_image[:,:,1]*1.0/original_image.sum(axis=2)

plt.figure(figsize=(20,20))
plt.scatter(original_image_R.flatten(),original_image_G.flatten())
plt.xlim(0,1)
plt.ylim(0,1);

结果如下:

5. 选择模板图像

这里我们选择一块绿色植物,作为我们的模板图像,代码如下:

cpp 复制代码
patch = original_image[3200:3300,2800:2900,:]
plt.figure(figsize=(10,10))
plt.imshow(patch)
plt.title('Reference Patch for Green', fontsize=20, weight='bold')
plt.axis('off');

结果如下:

接着,我们可以得到此模板图像的RG色度:

cpp 复制代码
patch_R = patch[:,:,0]*1.0/patch.sum(axis=2)
patch_G = patch[:,:,1]*1.0/patch.sum(axis=2)

plt.figure(figsize=(10,10))
plt.scatter(patch_R.flatten(),patch_G.flatten())
plt.xlim(0,1)
plt.ylim(0,1);

结果如下:

6. 计算高斯分布

接着我们需要做的事就是计算我们模板图像的高斯分布,来找到我们感兴趣的颜色。因此,我们用以下代码计算模板图像R通道的平均值和方差,如下:

cpp 复制代码
std_patch_R = np.std(patch_R.flatten())
mean_patch_R = np.mean(patch_R.flatten())

我们来可视化下R通道计算出来的结果,代码如下:

cpp 复制代码
def gaussian(p,mean,std):
    return np.exp(-(p-mean)**2/(2*std**2))*(1/(std*((2*np.pi)**0.5)))
x = np.linspace(0,1)
y = gaussian(x,mean_patch_R,std_patch_R)
plt.plot(x,y);

画图如下:

这种分布为我们提供了使用R通道选择某种颜色作为图像表示的概率。我们实际上可以通过使用以下方法来利用该信息来分割我们的图像:

cpp 复制代码
prob_R = gaussian(original_image_R,mean_patch_R,std_patch_R)
plt.imshow(prob_R);

结果如下:

7. 分割图像

上面只是使用了RG-色度空间的R通道进行分割的结果,同时我们类比计算G通道的分割结果,

代码如下:

cpp 复制代码
std_patch_G = np.std(patch_G.flatten())
mean_patch_G = np.mean(patch_G.flatten())
prob_G = gaussian(original_image_G,mean_patch_G,std_patch_G)
plt.imshow(prob_G);

结果如下:

最后,我们考虑的两个通道是独立概率,我们可以简单地将掩码相乘:

cpp 复制代码
prob=prob_R * prob_G
plt.imshow(prob)

达到最终结果如下:

8. 总结

通过上述分析,我们一步一步实现了利用RG-色度空间来分割绿色植物的目标,并针对每一步骤都进行了相应的讲解和代码示例,您学废了嘛!

相关推荐
春末的南方城市2 小时前
FLUX的ID保持项目也来了! 字节开源PuLID-FLUX-v0.9.0,开启一致性风格写真新纪元!
人工智能·计算机视觉·stable diffusion·aigc·图像生成
jndingxin2 小时前
OpenCV视频I/O(14)创建和写入视频文件的类:VideoWriter介绍
人工智能·opencv·音视频
sp_fyf_20242 小时前
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-02
人工智能·神经网络·算法·计算机视觉·语言模型·自然语言处理·数据挖掘
FL16238631295 小时前
[C++]使用纯opencv部署yolov11旋转框目标检测
opencv·yolo·目标检测
Funny_AI_LAB7 小时前
MetaAI最新开源Llama3.2亮点及使用指南
算法·计算机视觉·语言模型·llama·facebook
方世恩8 小时前
【进阶OpenCV】 (5)--指纹验证
人工智能·opencv·目标检测·计算机视觉
_.Switch8 小时前
Python机器学习:自然语言处理、计算机视觉与强化学习
python·机器学习·计算机视觉·自然语言处理·架构·tensorflow·scikit-learn
FL16238631298 小时前
[C++]使用纯opencv部署yolov11-pose姿态估计onnx模型
c++·opencv·yolo
A_lvvx8 小时前
OpenCV透视变换
人工智能·opencv·计算机视觉
鲸~屿9 小时前
计算机视觉 第十章OpenCV
人工智能·opencv·计算机视觉