《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测

本专栏主要介绍如果通过OpenCv-Python进行图像处理,通过原理理解OpenCv-Python的函数处理原型,在具体情况中,针对不同的图像进行不同等级的、不同方法的处理,以达到对图像进行去噪、锐化等一系列的操作。同时,希望观看本专栏的小伙伴可以理解到OpenCv进行图像处理的强大哦,如有转载,请注明出处(原文链接和作者署名),感谢各位小伙伴啦!

前文参考:
《OpenCv视觉之眼》Python图像处理一 :Opencv-python的简介及Python环境搭建
《OpenCv视觉之眼》Python图像处理二 :Opencv图像读取、显示、保存基本函数原型及使用
《OpenCv视觉之眼》Python图像处理三 :Opencv图像属性、ROI区域获取及通道处理
《OpenCv视觉之眼》Python图像处理四 :Opencv图像灰度处理的四种方法及原理
《OpenCv视觉之眼》Python图像处理五 :Opencv图像去噪处理之均值滤波、方框滤波、中值滤波和高斯滤波
《OpenCv视觉之眼》Python图像处理六 :Opencv图像傅里叶变换和傅里叶逆变换原理及实现
《OpenCv视觉之眼》Python图像处理七 :Opencv图像处理之高通滤波和低通滤波原理及构造
《OpenCv视觉之眼》Python图像处理八 :Opencv图像处理之图像阈值化处理原理及函数
《OpenCv视觉之眼》Python图像处理九 :Opencv图像形态学处理之图像腐蚀与膨胀原理及方法
《OpenCv视觉之眼》Python图像处理十 :Opencv图像形态学处理之开运算、闭运算和梯度运算原理及方法
《OpenCv视觉之眼》Python图像处理十一 :Opencv图像形态学处理之顶帽运算与黑帽运算
《OpenCv视觉之眼》Python图像处理十二 :Opencv图像轮廓提取之基于一阶导数的Roberts算法、Prewitt算法及Sobel算法
《OpenCv视觉之眼》Python图像处理十三 :Opencv图像轮廓提取之基于二阶导数的Laplacian算法和LOG算法
《OpenCv视觉之眼》Python图像处理十四 :Opencv图像轮廓提取之Scharr算法和Canny算法
《OpenCv视觉之眼》Python图像处理十五 :Opencv图像处理之图像缩放、旋转和平移原理及实现

上次博客我们结束了OpenCV图像处理的基本步骤,包括图像灰度处理、图像滤波去噪、图像阈值化、图像形态学处理、图像轮廓提取等,这是在现实OpenCV对一张图像进行处理的一般步骤,例如我们要识别图像中的人脸,图像中的硬币、图像中的车牌或者是提取图像中的某个物体,以上步骤都是我们必须通过调整参数而需要使用的;上次博客结束了以上步骤,接下来该系列的讲解主要针对图像目的操作,也就是项目实战,你也可以理解为通过《OpenCV视觉之眼》识别图像中的物体。

本次博客,林君学长主要介绍如何通过OpenCV图像处理库对图像中的硬币进行检测识别,大家主要理解硬币检测的过程中对图像处理的过程,每一步过程代表什么含义,怎么对步骤中所用到的函数通过参数调节达到我们预期的目标

图像处理实战1:对图像中的硬币进行检测,在终端打印出硬币个数,并在原图上画出识别到的硬币的轮廓

[Python图像处理十六]:Opencv项目实战之图像中的硬币检测

  • 一、图像硬币检测
    • 1、图像硬币检测步骤
    • 2、硬币检测完整代码(暂未调参数)
  • 二、函数参数调节
    • 1、对滤波去噪的参数调节
    • 2、对二进制阈值参数进行调节
    • 3、Canny算法轮廓提取的参数调节
  • 三、最终代码及检测结果展示
    • 1、最终完整代码(已调解参数)
    • 2、检测结果

一、图像硬币检测

对图像中的硬币检测针对的不是一张图像,而是一类图像,通过OpenCV对图像进行识别有优势也有缺点,对于一类图像,OpenCV编写的识别算法可能只对一张图像有效,而针对这一类型的其他图像,可能得到的结果不是预期的效果,这是OpenCV对图像识别的缺点,不比神经网络训练一下针对一类图像都可以进行识别;但优点是对图像识别的速度快、开源代码,比神经网络进行模型训练容易理解;以上的优点和缺点在下面的操作中是可以体现的,一起学习吧!

1、图像硬币检测步骤

图像硬币检测步骤一般情况分为以下8个步骤,如下所示:

注意:以下步骤所用的函数参数是随便进行设置的,因此,图像可能达不到预期要求,后面通过参数进行调节

1)、硬币图像数据准备

《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测_第1张图片 《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测_第2张图片

2)、导入OpenCV-Python库读取图像,并进行泛洪处理(背景填充)

#导入函数库
import cv2
import numpy as np
#读取一张硬币图像
img=cv2.imread("coins2.jpg")
#对图像进行泛洪处理
h, w = img.shape[:2] #获取图像的长和宽
mask = np.zeros((h+2, w+2), np.uint8)#进行图像填充
cv2.floodFill(img, mask, (w-1,h-1), (255,255,255), (2,2,2),(3,3,3),8) 

《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测_第3张图片
3)、图像灰度处理

#图像灰度化
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测_第4张图片
4)、对硬币图像进行滤波图像平滑,这里选择高斯滤波

#通过高斯滤波对图像进行模糊处理,可以理解为对图像硬币去噪
blur=cv2.GaussianBlur(gray,(29,29),1,1)#这里可以用中值滤波,具体视对图像效果选择

《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测_第5张图片

5)、对滤波去噪后的图像进行阈值化处理,将轮廓与周围无用信息分开

#通过二进制阈值化对图像进行阈值化处理,将硬币轮廓与周围噪声区分开来
ret,thresh1=cv2.threshold(blur,127,255,cv2.THRESH_BINARY)

《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测_第6张图片

6)、图像形态学处理,通过闭运算,去除图像内部噪声

#进行闭运算,去除图像内部噪声
#设置卷积核
kernel = np.ones((7,7), np.uint8)
close=cv2.morphologyEx(thresh1, cv2.MORPH_CLOSE, kernel)

《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测_第7张图片

7)、利用Canny算法提取轮廓

#利用canny算法对图像进行轮廓提取
Canny = cv2.Canny(close, 50, 150)
#显示图像轮廓提取图像
cv2.imshow("Canny",Canny)
#等待键盘键值关闭
cv2.waitKey(0)

《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测_第8张图片

如果图像轮廓在进行阈值化后已经很清晰,该步骤可以省略

8)、提取轮廓线条,并在终端打印硬币个数,最后将轮廓线条画在原图上

#在提取出的轮廓图像中找出轮廓线条
(cnts1,_) =cv2.findContours(Canny,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#在终端打印出硬币个数
print("图像中的硬币共有:",len(cnts1),"个")
#将硬币轮廓线条画在原图
coins1 = img.copy()
cv2.drawContours(coins1, cnts1, -1, (0,255,0), 2)
#显示在原图上面检测出来的硬币
cv2.imshow("coins",coins1)
#等待键盘键值关闭
cv2.waitKey(0)

《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测_第9张图片
findContours()函数原型:(cnts1,_) =cv2.findContours(img,a,b)

  • cnts1:轮廓结果数组
  • img:输入图像
  • a:轮廓检索方式
  • b:轮廓近似方法
  • a的参数可选择如下:
    《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测_第10张图片
  • b的参数可选择如下:
    《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测_第11张图片

drawContours()函数原型:cv2.drawContours(img, cnts1, indnx, color, size)

  • img:需要绘制的图像
  • cnts1:需要绘制的轮廓,上面的cv2.findContours()函数得到
  • indnx:轮廓的索引(当设置为-1时,绘制所有轮廓)
  • color:画笔颜色,例如(0,255,0)
  • size:画笔大小,例如2

再次声明:以上函数参数暂未进行调整,因此不少我们预期的图像,后面我们会进行参数调整的哦!

2、硬币检测完整代码(暂未调参数)

'''
    项目实战一:OpenCV图像硬币检测
'''
#导入函数库
import cv2
import numpy as np
#读取一张硬币图像
img=cv2.imread("coins2.jpg")
#低通滤波处理
#对图像进行泛洪处理
h, w = img.shape[:2] #获取图像的长和宽
mask = np.zeros((h+2, w+2), np.uint8)#进行图像填充
cv2.floodFill(img, mask, (w-1,h-1), (255,255,255), (2,2,2),(3,3,3),8) 
#图像灰度化
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#通过高斯滤波对图像进行模糊处理,可以理解为对图像硬币去噪
blur=cv2.cv2.GaussianBlur(gray,(29,29),0,0)#这里可以用中值滤波,具体视对图像效果选择
cv2.imshow("blur",blur)
cv2.waitKey(0)
#通过二进制阈值化对图像进行阈值化处理,将硬币轮廓与周围噪声区分开来
ret,thresh1=cv2.threshold(blur,127,255,cv2.THRESH_BINARY)
cv2.imshow("thresh1",thresh1)
cv2.waitKey(0)
#进行闭运算,去除图像内部噪声
kernel = np.ones((7,7), np.uint8)#设置卷积核
close=cv2.morphologyEx(thresh1, cv2.MORPH_CLOSE, kernel)#闭运算
cv2.imshow("close",close)
cv2.waitKey(0)
#利用canny算法对图像进行轮廓提取
Canny = cv2.Canny(close, 20, 150)
#显示图像轮廓提取图像
cv2.imshow("Canny",Canny)
#等待键盘键值关闭
cv2.waitKey(0)
#在提取出的轮廓图像中找出轮廓线条
(cnts1,_) =cv2.findContours(Canny,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#在终端打印出硬币个数
print("图像中的硬币共有:",len(cnts1),"个")
#将硬币轮廓线条画在原图
coins1 = img.copy()
cv2.drawContours(coins1, cnts1, -1, (0,255,0), 2)
#显示在原图上面检测出来的硬币
cv2.imshow("coins",coins1)
#等待键盘键值关闭
cv2.waitKey(0)

接下来,我们通过调节以上代码中的相关参数,进行图像预期处理,如下步骤

二、函数参数调节

在以上运用到的函数进行参数调节的过程中,我们主要通过滤波去噪参数和Canny算法参数,通过调节以上参数进行图像预期处理

1、对滤波去噪的参数调节

1)、观察以上阈值化后的图像轮廓,可以发现,图像轮廓不完整,因此,高斯滤波核过大,导致图像轮廓丢失,因此,我们将高斯滤波核尺寸缩小,至于尺寸的调节,可以观察到至少包含所有硬币轮廓,调节后如下:

blur=cv2.GaussianBlur(gray,(17,17),1,1)#这里可以用中值滤波,具体视对图像效果选择

2、对二进制阈值参数进行调节

1)、在很多时候,图像不完整是由于二进制阈值化参数阈值设置过低,将低模糊后的低像素值设置为白色了,可以将阈值调大一点

ret,thresh1=cv2.threshold(blur,177,255,cv2.THRESH_BINARY)

2)、图像阈值化之后,会紧跟形态学处理,一般我们会运用形态学处理将图像内部的白色间隙去掉,使得全部为黑色形状,这样在进行Canny算法提取的时候才不会出现多余的轮廓,因此,需要调节闭运算的卷积核,自己适当调整

kernel = np.ones((7,7), np.uint8)#设置卷积核

3、Canny算法轮廓提取的参数调节

Canny算法是边缘检测的优质算法,但前提是我们得设置好上下阈值,因为最后是通过双阈值方式得到最终轮廓,因此,选择上下阈值时非常重要的,不同的图像对应不同的上下阈值,这也是前面我们说到的缺点,对同类其他图像进行处理需要多次调解参数,具体调解到提取完美的轮廓为止,如下所示:

Canny = cv2.Canny(close, 20, 150)

三、最终代码及检测结果展示

1、最终完整代码(已调解参数)

'''
    项目实战一:OpenCV图像硬币检测
'''
#导入函数库
import cv2
import numpy as np
#读取一张硬币图像
img=cv2.imread("coins2.jpg")
#低通滤波处理
#对图像进行泛洪处理
h, w = img.shape[:2] #获取图像的长和宽
mask = np.zeros((h+2, w+2), np.uint8)#进行图像填充
cv2.floodFill(img, mask, (w-1,h-1), (255,255,255), (2,2,2),(3,3,3),8) 
#图像灰度化
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#通过高斯滤波对图像进行模糊处理,可以理解为对图像硬币去噪
blur=cv2.cv2.GaussianBlur(gray,(17,17),0,0)#这里可以用中值滤波,具体视对图像效果选择
#通过二进制阈值化对图像进行阈值化处理,将硬币轮廓与周围噪声区分开来
ret,thresh1=cv2.threshold(blur,177,255,cv2.THRESH_BINARY)
#进行闭运算,去除图像内部噪声
kernel = np.ones((7,7), np.uint8)#设置卷积核
close=cv2.morphologyEx(thresh1, cv2.MORPH_CLOSE, kernel)#闭运算
#利用canny算法对图像进行轮廓提取
Canny = cv2.Canny(close, 20, 150)
#显示图像轮廓提取图像
cv2.imshow("Canny",Canny)
#在提取出的轮廓图像中找出轮廓线条
(cnts1,_) =cv2.findContours(Canny,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#在终端打印出硬币个数
print("图像中的硬币共有:",len(cnts1),"个")
#将硬币轮廓线条画在原图
coins1 = img.copy()
cv2.drawContours(coins1, cnts1, -1, (0,255,0), 2)
#显示在原图上面检测出来的硬币
cv2.imshow("coins",coins1)
#等待键盘键值关闭
cv2.waitKey(0)

2、检测结果

1)、图像结果
《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测_第12张图片
2)、终端检测结果
《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测_第13张图片

3)、缺点展示
如果我们通过以上的参数再去检测其他硬币图像,我们可以发现效果非常不明显,如下所示:
《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测_第14张图片
在这里插入图片描述
因此,对于同类的不同图像,我们需要再次调解上面所讲得参数!

以上就是本次博客的全部内容,遇到问题的小伙伴记得留言评论,学长看到会为大家进行解答的,这个学长不太冷!

你生活在别人的眼神里,就迷失在自己的心路上。你永远无法满足所有人,不必为了取悦这个世界而扭曲自己。

陈一月的又一天编程岁月^ _ ^

你可能感兴趣的:(Opencv视觉之眼,opencv,python,《OpenCV视觉之眼》,OpenCV硬币检测,python图像处理)