Python Opencv实现单目标检测的示例代码


Posted in Python onSeptember 08, 2020

一 简介

目标检测即为在图像中找到自己感兴趣的部分,将其分割出来进行下一步操作,可避免背景的干扰。以下介绍几种基于opencv的单目标检测算法,算法总体思想先尽量将目标区域的像素值全置为1,背景区域全置为0,然后通过其它方法找到目标的外接矩形并分割,在此选择一张前景和背景相差较大的图片作为示例。

Python Opencv实现单目标检测的示例代码

环境:python3.7 opencv4.4.0

二 背景前景分离

1 灰度+二值+形态学 轮廓特征和联通组件

根据图像前景和背景的差异进行二值化,例如有明显颜色差异的转换到HSV色彩空间进行分割。

1 原图

Python Opencv实现单目标检测的示例代码

2 灰度化

Python Opencv实现单目标检测的示例代码

3 二值化

Python Opencv实现单目标检测的示例代码

4 形态学处理

Python Opencv实现单目标检测的示例代码

5 提取轮廓并找出目标外接矩形

代码封装:

def get_roi_contours(image_path, morph_size, num_morph):
  '''
  参数详解:
  image_path:所需处理图片路径
  morph_size:形态学处理核的大小
  num_morph:进行形态学处理的次数
  '''
  image = cv2.imread(image_path, cv2.IMREAD_COLOR)
  #灰度转换
  gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  #二值化
  threhold, binary_image = cv2.threshold(gray_image, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
  #形态学操作
  kernel = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=morph_size)
  morph_image = cv2.morphologyEx(binary_image, cv2.MORPH_CLOSE, kernel)
  for i in range(num_morph-1):
    morph_image = cv2.morphologyEx(morph_image, cv2.MORPH_CLOSE, kernel)
  #查找轮廓
  contours, hierarchy = cv2.findContours(morph_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  #选取轮廓面积最大的轮廓
  area = 0
  max_area_index = 0
  for j in range(len(contours)):
    if area < cv2.contourArea(contours[j]):
      max_area_index = j
      area = cv2.contourArea(contours[j])
  rect = cv2.boundingRect(contours[max_area_index])
  return rect

6 通过联通组件找到外接矩形
代码封装:

def get_roi_ConCom(image_path, morph_size, num_morph):
  '''
  参数详解:
  image_path:所需处理图片路径
  morph_size:形态学处理核的大小
  num_morph:进行形态学处理的次数
  '''
  image = cv2.imread(image_path, cv2.IMREAD_COLOR)
  #灰度转换
  gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  #二值化
  threhold, binary_image = cv2.threshold(gray_image, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
  #形态学操作
  kernel = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=morph_size)
  morph_image = cv2.morphologyEx(binary_image, cv2.MORPH_CLOSE, kernel)
  for i in range(num_morph-1):
    morph_image = cv2.morphologyEx(morph_image, cv2.MORPH_CLOSE, kernel)
  #联通组件查询
  numlabels, components_img, stats, centers = cv2.connectedComponentsWithStats(morph_image, 8)
  #获取除背景外的所有联通组件
  stats_without_back = stats[1:]
  #获取除背景外的所有联通组件的面积最大值
  max_area = np.max(stats_without_back, axis=0)[-1]
  #获取面积最大联通组件的index
  max_area_index = stats_without_back[:, -1]==max_area
  rect = stats_without_back[max_area_index]
  return np.squeeze(rect)[0:4]

2 Kmeans聚类实现前景和背景的分离

1 kmeans聚类后的图像,由于簇的中心是随机初始化的,所以目标的像素值可能为0,也可能为1,若采用opencv的findContours则要求前景像素值为1。

Python Opencv实现单目标检测的示例代码

2 利用轮廓特征找外接矩形

由于Kmeans随机初始化簇中心导致前景目标像素不确定,采用边缘提取的方法再查找轮廓。

边缘图:

Python Opencv实现单目标检测的示例代码

代码封装:

def get_roi_Kmeans(image_path):
  image = cv2.imread(image_path, cv2.IMREAD_COLOR)
  image_data = image.reshape(-1, 3).astype(np.float32) #必须要转成浮点类型进行计算
  #簇内平方和,标签和每个簇的中心
  criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 10, 1)
  interia, label, centers = cv2.kmeans(image_data, 2, None, criteria, 5, cv2.KMEANS_RANDOM_CENTERS)
  #二值化,将标签为0的转换为255,即是目标
  label[label==0] = 255
  label[label==1] = 0
  #转换数据类型,轮廓查找要是uint8类型数据
  thresh_img = label.reshape(image.shape[0:2]).astype(np.uint8)
  x_grad = cv2.Sobel(thresh_img, cv2.CV_32F, 1, 0)
  y_grad = cv2.Sobel(thresh_img, cv2.CV_32F, 0, 1)

  x_grad = cv2.convertScaleAbs(x_grad) #ax + b 线性变换
  y_grad = cv2.convertScaleAbs(y_grad)
  
  dst = cv2.add(x_grad, y_grad, dtype=cv2.CV_16S) #将两种sobel的加起来就可以得到整个边缘
  dst = cv2.convertScaleAbs(dst)
  plt.imshow(dst, cmap='gray')
  #轮廓查找目标必须为1
  contours, hierarchy = cv2.findContours(dst, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
  #获取外接矩形
  rect = cv2.boundingRect(contours[0])
  return rect

三 总结

单目标检测较为简单,只要合理利用目标和背景的差异便可将其分离出来。当然单目标检测的方法还有很多,比如有目标模板的时候可以采用模板匹配或者均值漂移,有足够的数据集时也可采用机器学习和深度学习方法。

到此这篇关于Python Opencv实现单目标检测的示例代码的文章就介绍到这了,更多相关Opencv 单目标检测内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python从ftp下载数据保存实例
Nov 20 Python
Python读写Redis数据库操作示例
Mar 18 Python
Python实现决策树C4.5算法的示例
May 30 Python
详解python异步编程之asyncio(百万并发)
Jul 07 Python
python+numpy+matplotalib实现梯度下降法
Aug 31 Python
Python列表list排列组合操作示例
Dec 18 Python
Python用Try语句捕获异常的实例方法
Jun 26 Python
详解mac python+selenium+Chrome 简单案例
Nov 08 Python
Python语法之精妙的十个知识点(装B语法)
Jan 18 Python
keras小技巧——获取某一个网络层的输出方式
May 23 Python
Python中else的三种使用场景
Jun 16 Python
Django中session进行权限管理的使用
Jul 09 Python
python获取本周、上周、本月、上月及本季的时间代码实例
Sep 08 #Python
Python 使用Opencv实现目标检测与识别的示例代码
Sep 08 #Python
Python requests接口测试实现代码
Sep 08 #Python
Python unittest装饰器实现原理及代码
Sep 08 #Python
Python selenium环境搭建实现过程解析
Sep 08 #Python
Python unittest生成测试报告过程解析
Sep 08 #Python
Python使用Selenium模拟浏览器自动操作功能
Sep 08 #Python
You might like
一个简易需要注册的留言版程序
2006/10/09 PHP
php实现网站顶踩功能的完整前端代码
2015/07/19 PHP
PHP请求远程地址设置超时时间的解决方法
2016/10/29 PHP
php+redis在实际项目中HTTP 500: Internal Server Error故障排除
2017/02/05 PHP
犀利的js 函数集合
2009/06/11 Javascript
Javascript UrlDecode函数代码
2010/01/09 Javascript
Javascript 获取链接(url)参数的方法[正则与截取字符串]
2010/02/09 Javascript
js 多浏览器分别判断代码
2010/04/01 Javascript
JQuery从头学起第三讲
2010/07/06 Javascript
jquery 操作DOM的基本用法分享
2012/04/05 Javascript
jQuery在页面加载时动态修改图片尺寸的方法
2015/03/20 Javascript
javascript三元运算符用法实例
2015/04/16 Javascript
JavaScript使用cookie实现记住账号密码功能
2015/04/27 Javascript
JS实现的不规则TAB选项卡效果代码
2015/09/18 Javascript
jQuery+Ajax实现限制查询间隔的方法
2016/06/07 Javascript
使用JS实现图片展示瀑布流效果(简单实例)
2016/09/06 Javascript
Angular ng-repeat 对象和数组遍历实例
2016/09/14 Javascript
Bootstrap Table使用整理(四)之工具栏
2017/06/09 Javascript
浅谈PDF.js使用心得
2018/06/07 Javascript
React性能优化系列之减少props改变的实现方法
2019/01/17 Javascript
详解javascript中的Error对象
2019/04/25 Javascript
vue 全局环境切换问题
2019/10/27 Javascript
python清除字符串里非数字字符的方法
2015/07/02 Python
django实现类似触发器的功能
2019/11/15 Python
使用python实现回文数的四种方法小结
2019/11/24 Python
详解python 破解网站反爬虫的两种简单方法
2020/02/09 Python
pandas to_excel 添加颜色操作
2020/07/14 Python
python 下载文件的几种方法汇总
2021/01/06 Python
师生聚会感言
2014/01/26 职场文书
工程项目建议书范文
2014/03/12 职场文书
学校庆元旦歌咏比赛主持词
2014/03/18 职场文书
演讲稿格式范文
2014/05/19 职场文书
全国税务系统先进集体事迹材料
2014/05/19 职场文书
golang日志包logger的用法详解
2021/05/05 Golang
MySQL快速插入一亿测试数据
2021/06/23 MySQL
5个pandas调用函数的方法让数据处理更加灵活自如
2022/04/24 Python