使用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获取电脑硬件信息及状态的实现方法
Aug 29 Python
python读取word文档,插入mysql数据库的示例代码
Nov 07 Python
Python格式化字符串f-string概览(小结)
Jun 18 Python
python实现两个dict合并与计算操作示例
Jul 01 Python
Django 迁移、操作数据库的方法
Aug 02 Python
python中matplotlib条件背景颜色的实现
Sep 02 Python
pytorch 归一化与反归一化实例
Dec 31 Python
Python版中国省市经纬度
Feb 11 Python
如何用Python 加密文件
Sep 10 Python
python ssh 执行shell命令的示例
Sep 29 Python
python中子类与父类的关系基础知识点
Feb 02 Python
Python查找算法的实现 (线性、二分,分块、插值查找算法)
Apr 24 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
php5 mysql分页实例代码
2008/04/10 PHP
基于在生产环境中使用php性能测试工具xhprof的详解
2013/06/03 PHP
实现在同一方法中获取当前方法中新赋值的session值解决方法
2014/06/26 PHP
PHP基于php_imagick_st-Q8.dll实现JPG合成GIF图片的方法
2014/07/11 PHP
php性能分析之php-fpm慢执行日志slow log用法浅析
2016/10/17 PHP
laravel框架中路由设置,路由参数和路由命名实例分析
2019/11/23 PHP
主页面中的两个iframe实现鼠标拖动改变其大小
2013/04/16 Javascript
JQuery动画animate的stop方法使用详解
2014/05/09 Javascript
深入理解JavaScript系列(25):设计模式之单例模式详解
2015/03/03 Javascript
JavaScript函数的调用以及参数传递
2015/10/21 Javascript
学习JavaScript设计模式之代理模式
2016/01/12 Javascript
静态页面html中跳转传值的JS处理技巧
2016/06/22 Javascript
javascript 广告移动特效的实现代码
2016/06/25 Javascript
Node.js connect ECONNREFUSED错误解决办法
2016/09/15 Javascript
JavaScript奇技淫巧44招【实用】
2016/12/11 Javascript
bootstrap table使用入门基本用法
2017/05/24 Javascript
Angular.js中$resource高大上的数据交互详解
2017/07/30 Javascript
Vue.js 2.x之组件的定义和注册图文详解
2018/06/19 Javascript
Angular2使用SVG自定义图表(条形图、折线图)组件示例
2019/05/10 Javascript
vue项目中常见问题及解决方案(推荐)
2019/10/21 Javascript
Java Varargs 可变参数用法详解
2020/01/28 Javascript
详解Vue之计算属性
2020/06/20 Javascript
JS倒计时两种实现方式代码实例
2020/07/27 Javascript
[03:20]2015国际邀请赛全明星表演赛
2015/08/08 DOTA
python实现图片变亮或者变暗的方法
2015/06/01 Python
Python读取文件内容的三种常用方式及效率比较
2017/10/07 Python
在自动化中用python实现键盘操作的方法详解
2019/07/19 Python
python实现定时发送邮件
2020/12/23 Python
python自动生成证件号的方法示例
2021/01/14 Python
美国体育用品在线:Modell’s Sporting Goods
2018/06/07 全球购物
导游词之无锡梅园
2019/11/28 职场文书
python中sys模块的介绍与实例
2021/04/17 Python
Nginx配置Https安全认证的实现
2021/05/26 Servers
详解Go语言运用广度优先搜索走迷宫
2021/06/23 Python
JavaScript函数柯里化
2021/11/07 Javascript
基于Apache Hudi在Google云构建数据湖平台的思路详解
2022/04/07 Servers