使用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多线程抓取天涯帖子内容示例
Apr 03 Python
在Python中操作字典之fromkeys()方法的使用
May 21 Python
简单上手Python中装饰器的使用
Jul 12 Python
Python的Flask框架应用程序实现使用QQ账号登录的方法
Jun 07 Python
Django model序列化为json的方法示例
Oct 16 Python
Python定时任务工具之APScheduler使用方式
Jul 24 Python
Python实现密码薄文件读写操作
Dec 16 Python
pytorch实现mnist分类的示例讲解
Jan 10 Python
Python3实现建造者模式的示例代码
Jun 28 Python
Python性能分析工具py-spy原理用法解析
Jul 27 Python
python 基于opencv实现高斯平滑
Dec 18 Python
Python实现信息轰炸工具(再也不怕说不过别人了)
Jun 11 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
java EJB 加密与解密原理的一个例子
2008/01/11 PHP
PHP获取数组中重复最多的元素的实现方法
2014/11/11 PHP
php结合正则批量抓取网页中邮箱地址
2015/05/19 PHP
php json相关函数用法示例
2017/03/28 PHP
利用phpexcel对数据库数据的导入excel(excel筛选)、导出excel
2017/04/27 PHP
用Jquery实现可编辑表格并用AJAX提交到服务器修改数据
2009/12/27 Javascript
jQuery数据显示插件整合实现代码
2011/10/24 Javascript
利用JQuery动画制作滑动菜单项效果实现步骤及代码
2013/02/07 Javascript
JS+DIV实现鼠标划过切换层效果的实例代码
2013/11/26 Javascript
js类定义函数时用prototype与不用的区别示例介绍
2014/06/10 Javascript
Js中使用hasOwnProperty方法检索ajax响应对象的例子
2014/12/08 Javascript
js实现延迟加载的方法
2015/06/24 Javascript
innerHTML中标签可以换行的方法汇总
2015/08/14 Javascript
javascript自定义滚动条实现代码
2020/04/20 Javascript
AngularJS入门教程之AngularJS表达式
2016/04/18 Javascript
jquery表单插件Autotab使用方法详解
2016/06/24 Javascript
jQuery实现下拉菜单(内容为时间)的实时更新及图表的随动更新的方法
2016/07/07 Javascript
高性能的javascript之加载顺序与执行原理篇
2018/01/14 Javascript
详解刷新页面vuex数据不消失和不跳转页面的解决
2018/01/30 Javascript
Python 闭包的使用方法
2017/09/07 Python
为什么选择python编程语言入门黑客攻防 给你几个理由!
2018/02/02 Python
对pandas处理json数据的方法详解
2019/02/08 Python
Python的3种运行方式:命令行窗口、Python解释器、IDLE的实现
2020/10/10 Python
Django自带的用户验证系统实现
2020/12/18 Python
CSS3截取字符串实例代码【推荐】
2018/06/07 HTML / CSS
canvas基础之图形验证码的示例
2018/01/02 HTML / CSS
SmartBuyGlasses台湾:名牌眼镜,名牌太阳眼镜及隐形眼镜
2017/01/04 全球购物
马来西亚户外装备商店:PTT Outdoor
2019/07/13 全球购物
主管会计岗位责任制
2014/02/10 职场文书
大学社团活动总结
2014/04/26 职场文书
企业消防安全责任书
2014/07/23 职场文书
教师节横幅标语
2014/10/08 职场文书
2015年村党支部工作总结
2015/04/30 职场文书
同学聚会感言一句话
2015/07/30 职场文书
Vue3.0 手写放大镜效果
2021/07/25 Vue.js
python程序的组织结构详解
2021/12/06 Python