《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视觉之眼》Python图像处理十六:Opencv项目实战之图像中的硬币检测

上次博客介绍了图像的轮廓提取,并且通过参数调节得到我们预期的图像最后绘制在原图上,是对OpenCV各种库函数的基本运用,也为后面更加深入层次的项目实战做准备,为基于OpenCV的人工智能识别做准备。上次博客需要掌握的便是对参数调节方式和思维模式。

本次博客,我们将在上次的基础上更新一点难度,除了将图像轮廓提取出来,并且需要将图像上的物体标注出来,同时截取出该物体,在后续的模型训练中,例如人脸识别的模型训练,在大多数时候我们只单单要人脸不需要人脸之外的其他东西,因此,我们需要将图像中的人脸截取出来然后进行模型训练,本次博客,便是为之后打下基础,一起学习吧!

图像处理实战二:之图像中的物体识别并截取(以图像中的蜜蜂为例)

一、Opencv图像处理实战二

1、图像物体识别截取步骤

对于图像中的物体识别的基本步骤和上次博客所讲解的基本步骤一致,包括数据准备、图像泛洪、灰度、高斯去噪、阈值化、形态学、边缘提取处理;唯一不同的是对边缘提取之后,是需要我们自己加一个框在轮廓上面,而不是直接将轮廓线条画在原图
1)、数据准备,以蜜蜂为例
在这里插入图片描述
2)、图像读取并泛洪处理
对于图像泛洪处理需要调节泛洪参数,如下的(3,3,3)和(4,4,4),根据图像泛洪的效果自己设定

#对图像进行泛洪处理
h, w = img1.shape[:2] #获取图像的长和宽
mask = np.zeros((h+2, w+2), np.uint8)#设置掩码,进行图像填充
cv2.floodFill(img1, mask, (w-1,h-1), (255,255,255), (3,3,3),(4,4,4),8) #对图像进行泛洪,去背景化

在这里插入图片描述
2)、图像灰度化

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

在这里插入图片描述
3)、高斯滤波去噪,参数如下代码设置

设置为17x17的高斯核,是通过不断观察后续图像效果得到的结果,因此,对参数的设计,是需要结合完整代码对图像的处理效果而做调整。

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

在这里插入图片描述
4)、阈值化处理,将图像与噪声分类成0和255两种颜色

梯度图像中不大于177的任何像素都设置为0(黑色)。 否则,像素设置为255(白色)。

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

在这里插入图片描述
5)、图像形态学处理,去除图像内部噪声,如果图像内部无噪声,即图像阈值化后物体全黑,则可以省略该步骤

图像轮廓内部有噪声点一般通过闭运算进行处理,外部有噪声点一般通过开运算进行处理

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

在这里插入图片描述
6)、Canny算法进行图像轮廓提取,识别出图像中蜜蜂的轮廓线条

#利用canny算法对图像进行轮廓提取
Canny = cv2.Canny(close, 20, 150)

在这里插入图片描述
6)、提取出轮廓线条,并在原图绘制包含物体的最小矩形框

#在提取出的轮廓图像中找出轮廓线条,并在原图上面画出矩阵框
(cnts1,_) =cv2.findContours(Canny,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
c = sorted(cnts1, key=cv2.contourArea, reverse=True)[0]
# 计算最大轮廓的旋转边界框
rect = cv2.minAreaRect(c)
#box里保存的是绿色矩形区域四个顶点的坐标(从边界框中提取出顶点坐标)
box = np.int0(cv2.boxPoints(rect))
#将box的顶点坐标绘制在图中并连接线条
cv2.drawContours(img, [box], -1, (0, 255, 0), 3)

在这里插入图片描述

cv2.minAreaRect()函数:
主要求得包含点集最小面积的矩形,这个矩形是可以有偏转角度的,可以与图像的边界不平行,在文章后面步骤部分会讲解

7)、将图像中的矩形框中的图像进行裁剪,形成图像最大特征

#对图像进行裁剪,在顶点坐标中找到(x,y)的最大值和最小值做差得到轮廓图像的矩形区域
Xs = [i[0] for i in box]
Ys = [i[1] for i in box]
x1 = min(Xs)
x2 = max(Xs)
y1 = min(Ys)
y2 = max(Ys)
hight = y2 - y1
width = x2 - x1
newImg = img[y1:y1+hight, x1:x1+width]

在这里插入图片描述

box里保存的是绿色矩形区域四个顶点的坐标。按照图中四个顶点坐标位置裁剪昆虫图像。找出四个顶点的x,y坐标的最大最小值。
新图像的高=maxY-minY,宽=maxX-minX

2、图像物体识别截取完整代码

1)、图像处理实战二完整代码

'''
    OpenCV物体识别与裁剪
'''
#导入函数库
import cv2
import numpy as np
#读取图像
img=cv2.imread("bear.jpg")
#将原图进行复制,进行泛洪处理
img1=img.copy()
#对图像进行泛洪处理
h, w = img1.shape[:2] #获取图像的长和宽
mask = np.zeros((h+2, w+2), np.uint8)#设置掩码,进行图像填充
cv2.floodFill(img1, mask, (w-1,h-1), (255,255,255), (3,3,3),(4,4,4),8) #对图像进行泛洪,去背景化
#图像灰度化
gray=cv2.cvtColor(img1,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)
#在提取出的轮廓图像中找出轮廓线条,并在原图上面画出矩阵框
(cnts1,_) =cv2.findContours(Canny,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
c = sorted(cnts1, key=cv2.contourArea, reverse=True)[0]
# 计算最大轮廓的旋转边界框
rect = cv2.minAreaRect(c)
#box里保存的是绿色矩形区域四个顶点的坐标(从边界框中提取出顶点坐标)
box = np.int0(cv2.boxPoints(rect))
#将box的顶点坐标绘制在图中并连接线条
cv2.drawContours(img, [box], -1, (0, 255, 0), 3)
cv2.imshow("recognition",img)
#对图像进行裁剪,在顶点坐标中找到(x,y)的最大值和最小值做差得到轮廓图像的矩形区域
Xs = [i[0] for i in box]
Ys = [i[1] for i in box]
x1 = min(Xs)
x2 = max(Xs)
y1 = min(Ys)
y2 = max(Ys)
hight = y2 - y1
width = x2 - x1
newImg = img[y1:y1+hight, x1:x1+width]
cv2.imshow("Tailoring",newImg)
cv2.waitKey(0)

2)、运行结果
在这里插入图片描述

3、代码中新函数介绍

1)、图像泛洪函数原型:cv2.floodFill(img,mask,seed,newvalue(BGR),(a,b,c),(a1,b1,c1),flag)

  • img:需要泛洪处理的目标图像
  • mask:掩码层,使用掩码可以规定是在哪个区域使用该算法,如果是对于完整图像都要使用,则掩码层大小为原图行数+2,列数+2.是一个二维的0矩阵,边缘一圈会在使用算法是置为1。而只有对于掩码层上对应为0的位置才能泛洪,所以掩码层初始化为0矩阵【dtype:np.uint8】
  • seed:泛洪算法的种子点,也是根据该点的像素判断决定和其相近颜色的像素点,是否被泛洪处理
  • newvalue(BGR):对于泛洪区域新赋的值(B,G,R)例如白色(255,255,255)
  • (a,b,c):是相对于seed种子点像素可以往下的像素值,即seed(B0,G0,R0),泛洪区域下界为(B0-a,G0-b,R0-c)
  • (a1,b1,c1):是相对于seed种子点像素可以往上的像素值,即seed(B0,G0,R0),泛洪区域上界为(B0+a1,G0+a2,R0+a3)
  • flag:为泛洪算法的处理模式
  • flag可设置参数如下:
    低八位:控制算法的连通性,是以seed点为中心,接着判断周围的几个像素点,再将泛洪区域像素点周围的几个像素点进行考虑。 一般为4,8;默认为4
    中间八位:与掩码层赋值密切相关,一般使用(255<<8)使中间8位全位1,则值为255,也就是掩码层对应原图的泛洪区域的部分被由原来的初值0赋值成255,如果中间8位为0,则赋值为1.
    高八位:由opencv宏参数指定,如下所示:
    • cv2.FLOODFILL_FIXED_RANGE:改变图像,填充newvalue
    • cv2.FLOODFILL_MASK_ONLY:不改变原图像,也就是newvalue参数失去作用,而是改变对应区域的掩码,设为中间八位的值

2)、sorted()函数为python内置函数,功能是该函数对所有可迭代的对象进行排序操作,原型如下:
sorted(iterable, key=None, reverse=False)

  • iterable: 可迭代对象
  • key:主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
  • reverse:排序规则,reverse = True 降序 , reverse = False 升序(默认)

3)、计算轮廓面积cv2.contourArea()原型:cv2.contourArea(cnt, True)

  • cnt:输入的单个轮廓值
  • True:该函数返回一个带符号的面积,其正负取决于轮廓的方向(顺时针还是逆时针);如果是False,则面积以绝对值的形式返回

注意:以上函数作为sorted()函数中的key传递进去了哦!

4)、旋转边界cv2.minAreaRect()原型:result=cv2.minAreaRect(Points)

  • Points:点集,数据类型为ndarray,array((x1,y1),(x2,y2),…,(xn,yn)
  • result:函数返回对象
    • result[0]返回矩形的中心点:(x,y),实际上为y行x列的像素点
    • result[1]返回矩形的长和宽,顺序一定不要弄错,在旋转角度上有很重要的作用
    • result[2]返回矩形的旋转角度
      在这里插入图片描述
      angel是由x轴逆时针转至W(宽)的角度;角度范围是[-90,0)

提示:minAreaRect就是求出在上述点集下的最小面积矩形

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

懂得感恩的人,往往是有谦虚之德的人,是有敬畏之心的人。对待比自己弱小的人,知道要躬身弯腰,便是属于前者;感受上苍懂得要抬头仰视,便是属于后者。

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

  • 9
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈一月的编程岁月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值