千万注意opencv的轮廓检测和边缘检测是两码事

本文链接:https://blog.csdn.net/wsp_1138886114/article/details/82945328

1 获取轮廓

OpenCV2获取轮廓主要是用 cv2.findContours()

import cv2

img = cv2.imread('wujiaoxing.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) _,contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) draw_img0 = cv2.drawContours(img.copy(),contours,0,(0,255,255),3)
draw_img1 = cv2.drawContours(img.copy(),contours,1,(255,0,255),3)
draw_img2 = cv2.drawContours(img.copy(),contours,2,(255,255,0),3)
draw_img3 = cv2.drawContours(img.copy(), contours, -1, (0, 0, 255), 3) print ("contours:类型:",type(contours))
print ("第0 个contours:",type(contours[0]))
print ("contours 数量:",len(contours)) print ("contours[0]点的个数:",len(contours[0]))
print ("contours[1]点的个数:",len(contours[1])) cv2.imshow("img", img)
cv2.imshow("draw_img0", draw_img0)
cv2.imshow("draw_img1", draw_img1)
cv2.imshow("draw_img2", draw_img2)
cv2.imshow("draw_img3", draw_img3) cv2.waitKey(0)
cv2.destroyAllWindows() 输出:
contours:类型: <class 'list'>
第0 个contours: <class 'numpy.ndarray'>
contours 数量: 3
contours[0]点的个数: 6
contours[1]点的个数: 74

  

其中,cv2.findContours() 的第二个参数主要有

cv2.RETR_LIST:检测的轮廓不建立等级关系
cv2.RETR_TREE:L建立一个等级树结构的轮廓。
cv2.RETR_CCOMP:建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。
cv2.RETR_EXTERNAL:表示只检测外轮廓
cv2.findContours() 的第三个参数 method为轮廓的近似办法

cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1
cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法
1.1 返回值:image, contours, hierarchy
contour返回值
cv2.findContours()函数首先返回一个list,list中每个元素都是图像中的一个轮廓,用numpy中的ndarray表示。
hierarchy返回值
该函数还可返回一个可选的hiararchy结果,这是一个ndarray,其中的元素个数和轮廓个数相同,每个轮廓contours[i]对应4个hierarchy元素hierarchy[i][0] ~hierarchy[i][3],分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号,如果没有对应项,则该值为负数。
2 绘出轮廓
cv2.drawContours()函数
cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]])

第一个参数是指明在哪幅图像上绘制轮廓;
第二个参数是轮廓本身,在Python中是一个list。
第三个参数指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。后面的参数很简单。其中thickness表明轮廓线的宽度,如果是-1(cv2.FILLED),则为填充模式。绘制参数将在以后独立详细介绍。
为了看到自己画了哪些轮廓,可以使用 cv2.boundingRect()函数获取轮廓的范围,即左上角原点,以及他的高和宽。然后用cv2.rectangle()方法画出矩形轮廓

"""
x, y, w, h = cv2.boundingRect(img)
参数:
img 是一个二值图
x,y 是矩阵左上点的坐标,
w,h 是矩阵的宽和高 cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
img: 原图
(x,y): 矩阵的左上点坐标
(x+w,y+h):是矩阵的右下点坐标
(0,255,0): 是画线对应的rgb颜色
2: 线宽
"""
for i in range(0,len(contours)):
x, y, w, h = cv2.boundingRect(contours[i])
cv2.rectangle(image, (x,y), (x+w,y+h), (153,153,0), 5)

3 获取轮廓区域

new_image=image[y+2:y+h-2,x+2:x+w-2]    # 先用y确定高,再用x确定宽
input_dir=("E:/cut_image/")
if not os.path.isdir(input_dir):
os.makedirs(input_dir)
cv2.imwrite( nrootdir+str(i)+".jpg",newimage)
print (i)

4 获取物体最小外界矩阵
使用 cv2.minAreaRect(cnt) ,返回点集cnt的最小外接矩形,cnt是所要求最小外接矩形的点集数组或向量,这个点集不定个数。
其中:cnt = np.array([[x1,y1],[x2,y2],[x3,y3],[x4,y4]]) # 必须是array数组的形式

rect = cv2.minAreaRect(cnt) # 得到最小外接矩形的(中心(x,y), (宽,高), 旋转角度)
box = np.int0(cv2.boxPoints(rect)) #通过box会出矩形框

OpenCV—Python 轮廓检测 绘出矩形框(findContours\ boundingRect\rectangle的更多相关文章

  1. OpenCV图像轮廓检测

    轮廓检测: 轮廓检测的原理通俗的说就是掏空内部点,比如原图中有3*3的矩形点.那么就可以将中间的那一点去掉. 一.关键函数1.1  cvFindContours函数功能:对图像进行轮廓检测,这个函数将 ...

  2. opencv HSV找颜色,找轮廓用最小旋转矩形框出

    #include <opencv2/opencv.hpp> #include<iostream> #include<string> using namespace ...

  3. OpenCV + Python 人脸检测

    必备知识 Haar-like opencv api 读取图片 灰度转换 画图 显示图像 获取人脸识别训练数据 探测人脸 处理人脸探测的结果 实例 图片素材 人脸检测代码 人脸检测结果 总结 下午的时候 ...

  4. OpenCV 闭合轮廓检测

    这个好像是骨头什么的,但是要求轮廓闭合,于是对图片进行一下膨胀操作,再次检测轮廓就好了. // A closed contour.cpp : 定义控制台应用程序的入口点. // #include &q ...

  5. appium+python自动化98-非select弹出选择框定位解决

    前言 遇到问题:document.getElementsByClassName(...)[0] is undefined 选择框如果是select标签的,可以直接用select专用的方法去定位点击操作 ...

  6. 15、OpenCV Python 轮廓发现

    __author__ = "WSX" import cv2 as cv import numpy as np # 基于拓扑结构来发现和绘制(边缘提取) # cv.findConto ...

  7. 14、OpenCV Python 直线检测

    __author__ = "WSX" import cv2 as cv import numpy as np #-----------------霍夫变换------------- ...

  8. 【python+opencv】轮廓发现

    python+opencv---轮廓发现 轮廓发现---是基于图像边缘提取的基础寻找对象轮廓的方法, 所有边缘提取的阈值选定会影响最终轮廓发现的结果. 介绍两种API使用: -cv.findConto ...

  9. Opencv在视频中静态、动态方式绘制矩形框ROI

    Opencv视频处理中的目标跟踪经常用到要在视频上画一个矩形框ROI,标注出要跟踪的物体,这里介绍两种在视频中绘制矩形框的方法,一种是"静态的",一种是"动态的" ...

随机推荐

  1. How to pass values across the pages in ASP.net without using Session

    https://stackoverflow.com/questions/14956027/how-to-pass-values-across-the-pages-in-asp-net-without- ...

  2. Mac下用命令行压缩和解压rar文件的方法

    废话不多说,直接进入主题 第一步:下载RAR工具包,根据自己需要下载相对应的版本 第二步:解压对应的压在的压缩包rarosx-5.4.0.tar.gz(我下载的是5.4.0版本) 第三步:从终端进入到 ...

  3. EasyUI的columns中列标题居中

    $("#supDataList").datagrid({   url: "../Ajax/SupplierAjax.ashx",   queryParams:  ...

  4. ES6 find 和 filter 的区别

    ES6 find 和 filter 的区别 : 遇到个功能是要分类就想说在前端过滤,不要从查数据库的时候过滤了.然后就想说除了filter还有啥好用的 发现有个find,测试一番之后发现 const ...

  5. webpack2.0 基本使用

    webpack是一款前端模块打包工具, 它的出现是由于现代web开发越来越复杂,如果还是像原来那样把所有的js代码都写到一个文件中,维护非常困难.而解决复杂化的方法通常是分而治之,就是把复杂化的东西进 ...

  6. Assembly language 再读---续

    前面已经写到了第三章的数据类型 的那一部分 接下来是一些关于伪指令和其他杂七杂八的东西 1. 当前地址计数器:   $ 常用于  计算数组以及字符串的长度,如: .data list db ,,,,, ...

  7. /dev/random vs /dev/urandom

    If you want random data in a Linux/Unix type OS, the standard way to do so is to use /dev/random or ...

  8. hdu6311 Cover (欧拉路径输出)

    hdu6311Cover 题目传送门 题意:有最少用多少条边不重复的路径可以覆盖一个张无向图. 分析:对于一个连通块(单个点除外),如果奇度数点个数为 k,那么至少需要max{k/2,1}  条路径. ...

  9. python学习二十三天函数的定义

    在计算机编程中,函数就是可以重复调用,可以传递参数,减少代码的量,可以高效写出好的代码,提高软件的运行质量,下面简单讲述python函数的定义方式 1,函数的定义 函数的定义用关键词def  函数名跟 ...

  10. android 完全退出应用程序(经过严格验证)

    今天解决了如何彻底结束Android应用程序的方法.网上有很多的参考方法,什么finish():android.os.Process.killProcess(android.os.Process.my ...