我的编程空间,编程开发者的网络收藏夹
学习永远不晚

python 图像处理——图像分割及经典案例篇之基于颜色的图像分割

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

python 图像处理——图像分割及经典案例篇之基于颜色的图像分割

前言
作者在第一部分向大家介绍了图像处理的基础知识,第二部分介绍了图像运算和图像增强,接下来第三部分我们将详细讲解图像分割及图像处理经典案例,该部分属于高阶图像处理知识,能进一步加深我们的理解和实践能力。图像分割是将图像分成若干具有独特性质的区域并提取感兴趣目标的技术和过程,它是图像处理和图像分析的关键步骤。主要分为基于阈值的分割方法、基于区域的分割方法、基于边缘的分割方法和基于特定理论的分割方法。这篇文章将详细讲解基于颜色的图像分割方法。

一、基于颜色的图像分割

颜色分割是图像处理中的一种重要技术,它可以将图像中的不同颜色分割出来,用于目标检测、图像识别等应用场景。

颜色分割的算法原理比较简单,它通常基于颜色空间的变换来实现。常用的颜色空间有RGB、HSV、LAB等,其中HSV颜色空间比较适合颜色分割任务。HSV颜色空间将颜色分成三个通道:色调(Hue)、饱和度(Saturation)和亮度(Value)。

  • 色调:表示颜色的种类或类型,例如红色、蓝色、绿色等。
  • 饱和度:表示颜色的纯度,越饱和的颜色越鲜艳,反之亦然。
  • 亮度:指颜色的明暗程度。在颜色中,亮度越高,颜色就越明亮;亮度越低,颜色就越暗淡。

颜色分割的基本思路是通过阈值来分割不同颜色的像素。具体地,我们可以将图像从RGB颜色空间转换到HSV颜色空间,然后选择合适的阈值(通常是色调、饱和度、亮度的最大值最小值),将图像分成黑白两部分。

在opencv hsv颜色空间中

  • 色调(Hue)的最大值是179度,最小值是0度,代表了颜色在色轮上的位置。

  • 饱和度(Saturation)的最大值是255,最小值是0,代表了颜色的纯度和灰度。

  • 亮度(Brightness)的最大值是255,最小值是0,代表了颜色的明暗程度。

实现步骤
基于上述算法原理,我们可以进行如下步骤来实现颜色分割:

  1. 将图像从RGB颜色空间转换到HSV颜色空间。
  2. 分别计算色调、饱和度、亮度的最大值和最小值
  3. 设置阈值,将图像分割成黑白两部分。
  4. 使用形态学操作去除噪点,得到最终的分割结果。

本文利用OpenCV中的cv2.inRange()函数,对图像中目标进行基于颜色的分割。

mask = cv2.inRange(class="lazy" data-src, lowerb, upperb[, dst])

— class="lazy" data-src 参数是输入图像,可以是单通道或多通道的,数据类型为 np.uint8
— mask是输出图像,为单通道图像(二值图像),数据类型和输入图像相同
—lowerb 是指定的下限,类型为 Scalar,可以是单个值或者一个包含多个值的元组或列表
—upperb 是指定的上限,类型为 Scalar,可以是单个值或者一个包含多个值的元组或列表

注:
mask代表了与指定颜色范围匹配的像素点的位置信息,即在指定颜色范围内的像素点在二值图像中对应的像素值为255,不在指定颜色范围内的像素点在二值图像中对应的像素值为0。因此,通过使用这个掩膜,我们可以选择性地对图像进行操作,只对指定颜色范围内的像素点进行处理,而不影响其他像素点

下面是基于上述算法原理实现简单的颜色分割代码(掩码自己给定范围):

import cv2import numpy as np# 读入图片img = cv2.imread( "C:/Users/Administrator/Desktop/flower.png")# 转换颜色空间hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)# 定义绿色范围lower_green = np.array([40, 50, 50])upper_green = np.array([90, 255, 255])# 定义黄色范围lower_yellow = np.array([15, 50, 50])upper_yellow = np.array([40, 255, 255])# 根据颜色范围创建掩码mask_green = cv2.inRange(hsv, lower_green, upper_green)mask_yellow = cv2.inRange(hsv, lower_yellow, upper_yellow)# 合并掩码mask = cv2.bitwise_or(mask_green, mask_yellow)# 应用掩码result = cv2.bitwise_and(img, img, mask=mask)# 显示结果cv2.imshow('result', result)cv2.waitKey(0)cv2.destroyAllWindows()

运行结果如图1-1所示,图中较好的分割出了向日葵,但草地部分也被分割了出来
在这里插入图片描述
以下是一些常见颜色的HSV范围:

红色:(0, 70, 50) - (10, 255, 255) 或者 (170, 70, 50) - (179, 255, 255)

橙色:(10, 70, 50) - (25, 255, 255)

黄色:(25, 70, 50) - (35, 255, 255)

绿色:(35, 70, 50) - (85, 255, 255)

青色:(85, 70, 50) - (100, 255, 255)

蓝色:(100, 70, 50) - (130, 255, 255)

紫色:(130, 70, 50) - (170, 255, 255)

白色:(0, 0, 221) - (180, 30, 255)

黑色: (0, 0, 0) - (180, 255, 30)

二、通过观察直方图确定颜色取值范围

当要分割的颜色目标在图像中无较大干扰时,可以通过观察色调(Hue)分量的直方图来确定颜色目标的取值范围,以作为我们分割的界限标准。

代码示例如下:

import cv2import numpy as npfrom matplotlib import pyplot as plt#通过OpenCV读取图片信息img = cv2.imread("C:/Users/Administrator/Desktop/scenery.jpg")# BGR图转为HSVhsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)# 提取hsv中H通道数据h = hsv[:, :, 0].ravel()# 直方图显示plt.hist(h, 180, [0, 180])plt.show()

得到直方图,如图2-1所示:
在这里插入图片描述
根据上诉所说的常见颜色的HSV范围,直方图中30到70部分出现了大量数据,由此可以确定绿色的H分量上下限为30-70,SV的界限可以根据上诉所提的HSV范围先大致设置,具体可以在提取掩模的时候调整确定

下面通过HSV的绿色界限生成mask掩模。代码如下:

import cv2import numpy as npfrom matplotlib import pyplot as plt#通过OpenCV读取图片信息img = cv2.imread("C:/Users/Administrator/Desktop/scenery.jpg")hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)# HSV 的下界限lower_red = np.array([35,70,50])# HSV 的上界限upper_red = np.array([70,255,255])# 通过上下限提取范围内的掩模maskmask = cv2.inRange(hsv, lower_red, upper_red)img =  cv2.resize(img,(500,500))mask = cv2.resize(mask,(500,500))cv2.imshow("img", img)cv2.imshow("mask", mask)cv2.waitKey(0)cv2.destroyAllWindows()

运行结果如图2-2所示
在这里插入图片描述

可以发现,草地的大体轮廓已被提取出来,但在场地上存在许多黑点,这是因为大部分黑点处于暗处,我们可以通过降低V值的下限来滤除掉,在这里V值下限由原来的50调整为15

效果如下:
在这里插入图片描述
此时有些黑点已经无法通过V的调整来去除了,我们可以采用膨胀、腐蚀等手段来消除独立的白点或黑点。

消除黑点代码如下:

import cv2import numpy as npfrom matplotlib import pyplot as plt#通过OpenCV读取图片信息img = cv2.imread("C:/Users/Administrator/Desktop/scenery.jpg")hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)# HSV 的下界限lower_green = np.array([35,70,15])# HSV 的上界限upper_green = np.array([70,255,255])# 通过上下限提取范围内的掩模maskmask = cv2.inRange(hsv, lower_green, upper_green)# 定义结构元素kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 35))# 图像闭运算mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=2)img =  cv2.resize(img,(500,500))mask = cv2.resize(mask,(500,500))cv2.imshow("img", img)cv2.imshow("mask", mask)cv2.waitKey(0)cv2.destroyAllWindows()

效果如图2-3所示
在这里插入图片描述
可以看到黑色的点被消除了,然后我们再使用cv2.bitwise_and()把原图与mask进行位与抠出草地的图片:
在这里插入图片描述

颜色替换

通过上面的操作我们已经可以准确的分割出我们指定的颜色了,在次基础上就可以对他的颜色进行更改了,比如改成黄色,这个同样也是要在HSV颜色空间操作的,不过这次就不需要对mask进行闭运算了。

在这里使用createTrackbar函数对hsv进行进行调整

cv2.createTrackbar(trackbarName, windowName, value, count, onChange)

  • trackbarName:可拖动条的名称,字符串类型。
  • windowName:可拖动条所在的窗口名称,字符串类型。
  • value:可拖动条的默认值,整型。
  • count:可拖动条的最大值,整型。
  • onChange:当可拖动条的值发生变化时调用的回调函数,函数类型。

代码如下:

import cv2import numpy as npdef nothing(x):    pass#通过OpenCV读取图片信息img = cv2.imread("C:/Users/Administrator/Desktop/scenery.jpg")img = cv2.resize(img,(500,500))cv2.namedWindow('img',cv2.WINDOW_NORMAL)cv2.imshow("img", img)# HSV 的下界限lower_green = np.array([35,70,15])# HSV 的上界限upper_green = np.array([70,255,255])cv2.namedWindow('img2',cv2.WINDOW_NORMAL)cv2.createTrackbar('H','img2',140,180,nothing)cv2.createTrackbar('S','img2',100,180,nothing)cv2.createTrackbar('V','img2',117,180,nothing)rows,cols,channels = img.shapewhile(1):    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)    mask = cv2.inRange(hsv, lower_green, upper_green)    #将制定像素点的数据设置为0, 要注意的是这三个参数对应的值是Blue, Green, Red。    h = cv2.getTrackbarPos('H', 'img2')    s = cv2.getTrackbarPos('S', 'img2')    v = cv2.getTrackbarPos('V', 'img2')    for r in range(rows):        for c in range(cols):            if mask[r, c] == 255:                hsv.itemset((r, c, 0), hsv.item(r, c, 0) -h)                hsv.itemset((r, c, 1), hsv.item(r, c, 1) +90-s)                hsv.itemset((r, c, 2), hsv.item(r, c, 2) +90-v)    img2 = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)    #将图像进行输出,使用show()也是可以显示的。    img = cv2.resize(img, (500, 500))    cv2.imshow("img2", img2)    k = cv2.waitKey(1)&0xFF    if k == 27: #esc exit        break#cv2.waitKey(0)cv2.destroyAllWindows()

在这里插入图片描述

三、总结

本篇博客介绍了如何使用Python与OpenCV进行颜色分割,其中使用了HSV颜色空间和阈值分割的算法。实现颜色分割的步骤包括:读取图像文件、转换颜色空间、计算阈值、分割图像、去除噪点等。通过实例的代码,我们可以更加深入地了解颜色分割的实现过程。

来源地址:https://blog.csdn.net/weixin_44598554/article/details/130627957

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

python 图像处理——图像分割及经典案例篇之基于颜色的图像分割

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python经典案例之图像漫水填充分割详解

图像分割是将图像分成若干具有独特性质的区域并提取感兴趣目标的技术和过程,这篇文章将详细讲解漫水填充分割应用,感兴趣的小伙伴可以了解一下
2023-01-28

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录