使用Python和OpenCV检测图像中的物体并将物体裁剪下来


Posted in Python onOctober 30, 2019

介绍

硕士阶段的毕设是关于昆虫图像分类的,代码写到一半,上周五导师又给我新的昆虫图片数据集了,新图片中很多图片很大,但是图片中的昆虫却很小,所以我就想着先处理一下图片,把图片中的昆虫裁剪下来,这样除去大部分无关背景,应该可以提高识别率。

原图片举例(将红色矩形框部分裁剪出来)):

使用Python和OpenCV检测图像中的物体并将物体裁剪下来

step1:加载图片,转成灰度图

image = cv2.imread("353.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

step2:用Sobel算子计算x,y方向上的梯度,之后在x方向上减去y方向上的梯度,通过这个减法,我们留下具有高水平梯度和低垂直梯度的图像区域。

gradX = cv2.Sobel(gray, ddepth=cv2.cv.CV_32F, dx=1, dy=0, ksize=-1)
gradY = cv2.Sobel(gray, ddepth=cv2.cv.CV_32F, dx=0, dy=1, ksize=-1)

# subtract the y-gradient from the x-gradient
gradient = cv2.subtract(gradX, gradY)
gradient = cv2.convertScaleAbs(gradient)

执行完这一步,得到的图像如下:

使用Python和OpenCV检测图像中的物体并将物体裁剪下来

step3:去除图像上的噪声。首先使用低通滤泼器平滑图像(9 x 9内核),这将有助于平滑图像中的高频噪声。低通滤波器的目标是降低图像的变化率。如将每个像素替换为该像素周围像素的均值。这样就可以平滑并替代那些强度变化明显的区域。

然后,对模糊图像二值化。梯度图像中不大于90的任何像素都设置为0(黑色)。 否则,像素设置为255(白色)。

# blur and threshold the image
blurred = cv2.blur(gradient, (9, 9))
(_, thresh) = cv2.threshold(blurred, 90, 255, cv2.THRESH_BINARY)

执行完这一步,得到的图像如下:

使用Python和OpenCV检测图像中的物体并将物体裁剪下来

step4:在上图中我们看到蜜蜂身体区域有很多黑色的空余,我们要用白色填充这些空余,使得后面的程序更容易识别昆虫区域,这需要做一些形态学方面的操作。

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25, 25))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

处理之后的图像如下:

使用Python和OpenCV检测图像中的物体并将物体裁剪下来

step5:从上图我们发现图像上还有一些小的白色斑点,这会干扰之后的昆虫轮廓的检测,要把它们去掉。分别执行4次形态学腐蚀与膨胀。

# perform a series of erosions and dilations
closed = cv2.erode(closed, None, iterations=4)
closed = cv2.dilate(closed, None, iterations=4)

执行完这步,得到的图形如下:

使用Python和OpenCV检测图像中的物体并将物体裁剪下来

step6:找出昆虫区域的轮廓。cv2.findContours()函数第一个参数是要检索的图片,必须是为二值图,即黑白的(不是灰度图),所以读取的图像要先转成灰度的,再转成二值图,我们在第三步用cv2.threshold()函数已经得到了二值图。第二个参数表示轮廓的检索模式,有四种:

  • cv2.RETR_EXTERNAL表示只检测外轮廓
  • cv2.RETR_LIST检测的轮廓不建立等级关系
  • cv2.RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
  • cv2.RETR_TREE建立一个等级树结构的轮廓。

第三个参数为轮廓的近似方法

  • cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1
  • cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息

cv2.findContours()函数返回两个值,一个是轮廓本身,还有一个是每条轮廓对应的属性。cv2.findContours()函数返回第一个值是list,list中每个元素都是图像中的一个轮廓,用numpy中的ndarray表示。每一个ndarray里保存的是轮廓上的各个点的坐标。我们把list排序,点最多的那个轮廓就是我们要找的昆虫的轮廓。
OpenCV中通过cv2.drawContours在图像上绘制轮廓。

  • 第一个参数是指明在哪幅图像上绘制轮廓
  • 第二个参数是轮廓本身,在Python中是一个list
  • 第三个参数指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓
  • 第四个参数是轮廓线条的颜色
  • 第五个参数是轮廓线条的粗细

cv2.minAreaRect()函数:
主要求得包含点集最小面积的矩形,这个矩形是可以有偏转角度的,可以与图像的边界不平行。

(cnts, _) = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
c = sorted(cnts, key=cv2.contourArea, reverse=True)[0]

# compute the rotated bounding box of the largest contour
rect = cv2.minAreaRect(c)
box = np.int0(cv2.cv.BoxPoints(rect))

# draw a bounding box arounded the detected barcode and display the image
cv2.drawContours(image, [box], -1, (0, 255, 0), 3)
cv2.imshow("Image", image)
cv2.imwrite("contoursImage2.jpg", image)
cv2.waitKey(0)

执行完这步得到的图形如下:

使用Python和OpenCV检测图像中的物体并将物体裁剪下来

step7:裁剪。box里保存的是绿色矩形区域四个顶点的坐标。我将按下图红色矩形所示裁剪昆虫图像。找出四个顶点的x,y坐标的最大最小值。新图像的高=maxY-minY,宽=maxX-minX。

使用Python和OpenCV检测图像中的物体并将物体裁剪下来

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
cropImg = image[y1:y1+hight, x1:x1+width]

裁剪出的图片如下:

使用Python和OpenCV检测图像中的物体并将物体裁剪下来

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现读取并显示图片的两种方法
Jan 13 Python
Python使用分布式锁的代码演示示例
Jul 30 Python
详解Python3 基本数据类型
Apr 19 Python
Python入门Anaconda和Pycharm的安装和配置详解
Jul 16 Python
基于 Django 的手机管理系统实现过程详解
Aug 16 Python
关于pandas的离散化,面元划分详解
Nov 22 Python
Python GUI自动化实现绕过验证码登录
Jan 10 Python
Python 面向对象之类class和对象基本用法示例
Feb 02 Python
Python爬取新型冠状病毒“谣言”新闻进行数据分析
Feb 16 Python
Python中pyecharts安装及安装失败的解决方法
Feb 18 Python
python爬虫请求头的使用
Dec 01 Python
Matplotlib配色之Colormap详解
Jan 05 Python
python基于K-means聚类算法的图像分割
Oct 30 #Python
Python列表原理与用法详解【创建、元素增加、删除、访问、计数、切片、遍历等】
Oct 30 #Python
Python文件路径名的操作方法
Oct 30 #Python
Python元组 tuple的概念与基本操作详解【定义、创建、访问、计数、推导式等】
Oct 30 #Python
解决python 上传图片限制格式问题
Oct 30 #Python
Python字典的概念及常见应用实例详解
Oct 30 #Python
Python集合基本概念与相关操作实例分析
Oct 30 #Python
You might like
php与php MySQL 之间的关系
2009/07/17 PHP
PHP curl模拟浏览器采集阿里巴巴的实现代码
2011/04/20 PHP
非常实用的php弹出错误警告函数扩展性强
2014/01/17 PHP
php学习笔记之面向对象
2014/11/08 PHP
Laravel搭建后台登录系统步骤详解
2016/07/26 PHP
完美解决thinkphp唯一索引重复时出错的问题
2017/03/31 PHP
PHP字典树(Trie树)定义与实现方法示例
2017/10/09 PHP
TP5框架实现自定义分页样式的方法示例
2020/04/05 PHP
解决jquery .ajax 在IE下卡死问题的解决方法
2009/10/26 Javascript
入门基础学习 ExtJS笔记(一)
2010/11/11 Javascript
JS 操作符整理[推荐收藏]
2011/11/15 Javascript
JS取request值以及自动执行使用示例
2014/02/24 Javascript
JavaScript和HTML DOM的区别与联系及Javascript和DOM的关系
2015/11/15 Javascript
易被忽视的js事件问题总结
2016/05/14 Javascript
AngularJs页面筛选标签小功能
2016/08/01 Javascript
AngularJS验证信息框架的封装插件用法【w5cValidator扩展插件】
2016/11/03 Javascript
nodejs超出最大的调用栈错误问题
2017/12/27 NodeJs
Vue点击切换颜色的方法
2018/09/13 Javascript
vue-cli脚手架打包静态资源请求出错的原因与解决
2019/06/06 Javascript
Vue路由权限控制解析
2020/11/09 Javascript
详解利用django中间件django.middleware.csrf.CsrfViewMiddleware防止csrf攻击
2018/10/09 Python
opencv转换颜色空间更改图片背景
2019/08/20 Python
Python namedtuple命名元组实现过程解析
2020/01/08 Python
详解Django自定义图片和文件上传路径(upload_to)的2种方式
2020/12/01 Python
python制作微博图片爬取工具
2021/01/16 Python
CSS3盒子模型详解
2013/04/24 HTML / CSS
html5构建触屏网站之网站尺寸探讨
2013/01/07 HTML / CSS
VICHY薇姿英国官网:全球专业敏感肌护肤领先品牌
2017/07/04 全球购物
人事部经理岗位职责
2014/03/07 职场文书
北京英文导游词
2015/02/12 职场文书
不同意离婚答辩状
2015/05/22 职场文书
2016暑期社会实践新闻稿
2015/11/25 职场文书
导游词之金鞭溪风景区
2019/09/12 职场文书
go结构体嵌套的切片数组操作
2021/04/28 Golang
浅谈自定义校验注解ConstraintValidator
2021/06/30 Java/Android
python使用matplotlib绘制图片时x轴的刻度处理
2021/08/30 Python