资讯专栏INFORMATION COLUMN

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

Gu_Yan / 3053人阅读

摘要:使用,进行基本的图像处理提取红色圆圈轮廓并绘制效果图源码写这篇博客源于博友的提问,想提取图片中的红色圆圈坐标,并绘制封闭的轮廓。还是使用一系列图像处理,得到了比较理想的结果。

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

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


看到这个首先有几个解决思路:

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

一个一个尝试,霍夫圆不是很理想,调整了参数,也没有全部提取到,只提取到了部分。
HSV色彩空间提取红色,因为对红色的HSV范围设置的不够合理,效果也不是很好。
还是使用一系列图像处理,得到了比较理想的结果。

1. 效果图

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

可以看到右图中,轮廓被用闭合的绿色轮廓连接起来。

检测过程1——原图 VS 剪裁后图如下:

  • 裁剪后图:忽略边界坐标轴对轮廓提取的影响;

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

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

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

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

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

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

绘制检测到的轮廓的组成点为蓝色空心圆形,绘制轮廓为绿色矩形。

检测结果——裁剪后图检测效果图 VS 原图直接检测效果图对比:

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

2. 源码

# 提取圆圈的轮廓,并绘制import cv2import imutilsimport 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 = 75height = 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] += width    cc[:, :, 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)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/118780.html

相关文章

  • opencv python 图像轮廓/检测轮廓/绘制轮廓

    摘要:绘制所有轮廓,传递要绘制图像中的所有轮廓,,,,要绘制单个轮廓,比如第个轮廓,,,,但大多数情况下,绘制第个轮廓,以下方法将非常有用,,,,代码 Contours : Getting Started 轮廓 简单地解释为连接所有连续点(沿着边界)的曲线,具有相同的颜色或强度. 轮廓是形状分析和物体检测和识别的有用工具 NOTE 为获得更好的准确性,请使用二值图,在找到轮廓之前,应用阈...

    caikeal 评论0 收藏0
  • python 图像处理:一福变五福

    摘要:某宝一年一度的集五福活动更是成为每年的必备活动。今年再来对福字做文章,演示下如何用的图像处理功能,把一幅福字图片转出种不同的效果最图像处理最常用的两个模块是和,这里我们选择。轮廓福使用了自带的图像轮廓提取功能。 快过年了,各种互联网产品都出来撒红包。某宝一年一度的集五福(shua hou)活动更是成为每年的必备活动。虽然到最后每人大概也就分个两块钱,但作为一个全民话题,大多数人还是愿意...

    JinB 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<