使用Python,OpenCV进行基本的图像处理——提取红色圆圈轮廓并绘制

news/2024/9/20 16:45:28

使用Python,OpenCV进行基本的图像处理——提取红色圆圈轮廓并绘制

    • 1. 效果图
      • 1.1 形态学图像处理效果图
      • 1.2 转换HSV色彩空间提取
    • 2. 源码
      • 2.1 形态学图像处理提取源码
      • 2.2 转换HSV色彩空间提取源码

写这篇博客源于博友的提问,想提取图片中的红色圆圈坐标,并绘制封闭的轮廓。

在这里插入图片描述
看到这个首先有几个解决思路:

1. 霍夫圆提取
2. 圆圈均是红色,可以转换HSV色彩空间提取
3. 应用一系列图像处理:灰度图、形态学操作、阈值化进行简单提取

一个一个尝试,霍夫圆不是很理想,调整了参数,也没有全部提取到,只提取到了部分。
本文将演示2,3俩种提取方法:
HSV色彩空间提取红色,需要对红色的HSV范围设置合理,才可以有比较好的提取效果。
使用一系列形态学图像处理,得到了比较理想的结果。

1. 效果图

1.1 形态学图像处理效果图

检测原始图 VS 效果图如下:

可以看到右图中,轮廓被用闭合的绿色轮廓连接起来。
在这里插入图片描述
检测过程1——原图 VS 剪裁后图如下:

  • 裁剪后图:忽略边界坐标轴对轮廓提取的影响;
    在这里插入图片描述

检测过程2—— 灰度图 VS 白帽图 VS 梯度图 VS 形态学闭合图如下:

  • 灰度图:忽略色彩影响;
  • 白帽图:从较暗的背景中提取较亮的区域
  • 梯度图:计算Schaar梯度图,使用梯度来检测图像中的边缘,更好的在图像中找到对象的轮廓和边缘线;
  • 形态学闭合图:矩形框形态学闭合操作,以帮助闭合轮廓间小的缝隙

在这里插入图片描述

检测过程3——形态学闭合图 VS 二值化图1 VS 阈值化图2 如下:

  • 二值化图:使得图像以白色前景和黑色背景呈现,以便于轮廓提取
  • 阈值化图:方形框形态学闭合操作,以二次帮助闭合小的缝隙

在这里插入图片描述

识别过程3——轮廓过滤图 VS 提取最终效果图 如下:

轮廓过滤图:根据面积只保留够大的轮廓图(截取完的图片只包含俩个轮廓,无需过滤,用原始图则需要过滤)
最终效果图:俩个大的轮廓被成功提取

绘制检测到的轮廓的组成点为蓝色空心圆形,绘制轮廓为绿色矩形。
在这里插入图片描述
检测结果——裁剪后图检测效果图 VS 原图直接检测效果图对比:

可以看到当直接使用原图进行上述检测,坐标轴边界会有干扰,结果中会检测出多余的轮廓。
在这里插入图片描述

1.2 转换HSV色彩空间提取

对红色的HSV空间设置合理后,发现转换HSV色彩空间提取的效果图也挺好。

原始图 VS 提取后绘制轮廓效果图如下:
在这里插入图片描述
检测过程图1:HSV图 VS HSV提取红色Mask图:
在这里插入图片描述
检测过程图2:轮廓膨胀图 VS 轮廓腐蚀图:
在这里插入图片描述

2. 源码

2.1 形态学图像处理提取源码

# 提取圆圈的轮廓,并绘制
import cv2
import imutils
import numpy as np# 初始化矩形和方形结构内核
# 在图像上滑动它来进行(卷积)操作,如模糊、锐化、边缘检测或其他图像处理操作。
# 使用矩形函数作为Top-hat形态学运算符,使用方形函数作为闭合运算。
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))# 加载输入图像,转换为灰度图
origin = cv2.imread('images/circle.png')
image = origin.copy()
width = 75
height = 34# # 只截取有轮廓的区域,避免坐标轴线等干扰
image = image[height:369, width:512]
cv2.imshow("origin", origin)
cv2.imshow("crop", image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("gray", gray)# 执行形态学操作
# 应用tophat(白帽)形态学操作以在暗的背景中提取出亮的区域
# Top hat操作在深色背景(即信用卡号)下显示浅色区域
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)
cv2.imshow("tophat", tophat)# 计算Scharr梯度,计算梯度值
# 在白色礼帽上,计算x方向的Scharr梯度,然后缩放到范围[0, 255]
gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)
gradX = np.absolute(gradX)
(minVal, maxVal) = (np.min(gradX), np.max(gradX))
# 最小/最大归一化, 由float转换gradX到uint8范围[0-255]
gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))
gradX = gradX.astype("uint8")
cv2.imshow("gradient", gradX)# 使用矩形框应用闭合操作以帮助闭合信用卡数字之间的小的缝隙
# 应用Otsu's阈值方法二值化图像
gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)
cv2.imshow("morphologyEx", gradX)
thresh = cv2.threshold(gradX, 0, 255,cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv2.imshow("thresh1", thresh)# 在二值化图像上,应用二次闭合操作
# 再一次方形框形态学操作,帮助闭合小的的缝隙
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel)
cv2.imshow("thresh2", thresh)# 阈值图像中查找轮廓,然后初始化数字位置列表
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
print(len(cnts))img = image.copy()
# 遍历轮廓
for (i, c) in enumerate(cnts):area = cv2.contourArea(c)print(i, area)# 根据面积过滤掉不符合的轮廓if (area < 4000):continue# print(' c: ', type(c), c.shape, c[0], type([c]))cc = c.copy()cc[:, :, 0] += widthcc[:, :, 1] += height# print('cc: ', type(cc), cc.shape, cc[0])for coor in c:# 在轮廓的每个小圆上绘制蓝色圆圈cv2.circle(img, (coor[0][0],coor[0][1]),5, (255, 0, 0), 1)cv2.drawContours(origin, [cc], -1, (0, 255, 0), 2)cv2.drawContours(image, [c], -1, (0, 255, 0), 2)cv2.imshow("origin res", origin)
cv2.imshow("img res", img)
cv2.imshow("image res", image)
cv2.imwrite("images/crop_circle_extract.jpg",image)
cv2.waitKey(0)

2.2 转换HSV色彩空间提取源码

# 将图像从一种颜色空间转换为另一种颜色空间,例如 BGR、RGB、Gray、HSV 等。
# 创建一个应用程序来提取视频中的彩色对象
# OpenCV 中有超过 150 种颜色空间转换方法可用,本文只介绍最经典的2中:BGR、HSV及互转from collections import dequeimport cv2
import imutils# 遍历查看所有颜色空间
flags = [i for i in dir(cv2) if i.startswith('COLOR_')]
print(flags)
print(len(flags))# 对于 HSV,色调范围为 [0,179],饱和度范围为 [0,255],值范围为 [0,255]。不同的软件使用不同的尺度。因此,如果您将 OpenCV 值与它们进行比较,则需要对这些范围进行归一化。
# 对象跟踪,可以使用HSV来提取彩色对象。这是最简单的对象追踪,找到物体的质心,就可以绘制轨迹来追踪物体;
import cv2
import numpy as nporigin = cv2.imread('images/circle.png')
frame = origin.copy()
origin1 = origin.copy()
cv2.imshow("origin", frame)  # 转换BGR为HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
cv2.imshow("hsv", hsv)# 定义绿色的HSV空间值
# lower_blue = np.array([29, 86, 6])
# upper_blue = np.array([64, 255, 255])# 定义红色的HSV空间值
lower_red = np.array([-30, 43, 46])
upper_red = np.array([30, 255, 255])# 阈值化图像,只获取红色
mask = cv2.inRange(hsv, lower_red, upper_red)
cv2.imshow("mask hsv", mask)
mask = cv2.dilate(mask, None, iterations=3)
cv2.imshow("mask dilate", mask)
mask = cv2.erode(mask, None, iterations=2)
cv2.imshow("mask erode", mask)# 寻找mask中的轮廓,并初始化球当前的中心(x,y)
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
print('cnts: ', len(cnts))
center = Nonepts = deque(maxlen=500)
# 发现至少一个轮廓继续处理
if len(cnts) > 0:for c in cnts:# 计算最小外接圆,质心((x, y), radius) = cv2.minEnclosingCircle(c)M = cv2.moments(c)center = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))pts.appendleft(center)# 绘制轮廓cv2.drawContours(frame, [c], -1, (0, 255, 0), 2)# 在帧上绘制红色球的外接圆及中心# cv2.circle(frame, (int(x), int(y)), int(radius),#            (0, 255, 0), -1)# cv2.circle(frame, (int(x), int(y)), 2,#            (255, 255, 0), 2)
cv2.imshow("Res", frame)
cv2.waitKey(0)# 如何找到HSV空间值呢?
# 比如要寻找绿色,可以找到BGR(0,255,0) ,转换为HSV,然后取[ H-10,S,V]为下限 -- [ H+10,S,V]为上限;
green = np.uint8([[[0, 255, 0]]])
hsv_green = cv2.cvtColor(green, cv2.COLOR_BGR2HSV)
print(hsv_green)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pgtn.cn/news/17755.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

PyTorch框架:(6)图像识别实战常用模块解读

1、TorchVision 官网&#xff1a;torchvision — Torchvision 0.10.0 documentation 在torchvision这个模块当中&#xff0c;包含了很多后续需要的功能&#xff1a; 需要自己安装这个模块pip install torchvision。安装完之后我们就可以使用这里边的三大核心模块了。 &…

Java 使用itextPdf7操作pdf,写入照片这一篇就够了

Java 使用itextPdf7操作pdf&#xff0c;写入照片这一篇就够了1. 效果图1.1 M*N列图片&#xff08;无边界&有边界&#xff09;1.2 图片重叠1.3 文字背景图片1.4 图片与文字相邻 & 图片文字Rowspan样式1.5 一个单元格多图片 & 多图片文本内容1.6 单元格中文本图片位置…

Flash气泡回弹效果

好久没有碰过Flash了&#xff0c;今天温习一下AS3.0&#xff0c;做了一个回弹效果&#xff0c;气泡回弹本想着怎么可以定义气泡的不同颜色&#xff0c;这样可以做出更绚丽的效果&#xff0c;或者更进步一&#xff0c;气泡和气泡直接回弹&#xff0c;想了老半天没有想出来&#…

Computer Vision Tasks

Computer Vision Tasks: 图像分类、目标检测、语义分割、实例分割&#xff1b; 只有目标检测和实例分割是实现了实例级别的识别的&#xff0c;就是把每一个单独的物体拎出来识别的&#xff1b;目标检测是画框框&#xff0c;而实例分割是抠图。 实例识别&#xff1a;就是把图片…

如何在OpenCV中为InRange阈值选择颜色的最佳HSV值

如何在OpenCV中为InRange阈值选择颜色的最佳HSV值 1. 效果图2. 源码参考之前的博客介绍了如何使用Python,OpenCV通过HSV颜色空间转换检测对象,并进行轨迹追踪。怎么选定合适的HSV颜色阈值范围非常非常非常的重要。 这篇博客将介绍如何在OpenCV中为InRange阈值选择颜色的最佳…

使用pycharm将自己项目代码上传github(保姆教程)

1、梳理一下Git、github和gitee这三个之间的关系&#xff1a; 1.1、Github 首先从我们最熟悉的github来说&#xff0c;他其实是一个代码托管平台&#xff0c;我们可以在他的里面新建很多的仓库&#xff0c;有强迫症的我理解就是一个仓库是一个自己的项目代码&#xff0c;这些…

基于openCV的项目实战1:信用卡数字识别

目的:识别信用卡卡号; 方法:基于模板匹配; 模板匹配思想:拿4和左边模板进行一一匹配,算一下平方项的差异,恰好4和左边模板中的4差异最小,所以就知道当前的数字是4; 具体步骤: 第一步:找到与你当前非常接近的一个模板; 第二步:把模板中每一个数字单独拿出来,…

使用Python,EoN模拟网络中的疾病扩散模型,并结合matplotlib绘图

使用Python,EoN模拟网络中的疾病扩散模型,并结合matplotlib绘图 1. EoN是什么2. 安装3. 效果图4. 源代码4.1 源码4.2 源码参考写这篇博客源于博友的提问,好奇EoN是什么,然后安装研究了一下~。 1. EoN是什么 EoN:使用python模拟网络中的疾病扩散模型 这本教科书为网络