OpenCV初尝试9——轮廓检测

OpenCV初尝试9——轮廓检测,第1张

9 轮廓检测 9.1 轮廓检测与绘制

检测轮廓API:

  • cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])
  • 返回三个值:img(轮廓本身);contours(每条轮廓对应的属性);hierarchy(层级)

– mode:轮廓的检索模式,有四种:
1.cv2.RETR_EXTERNAL:只检测外轮廓;
2.cv2.RETR_LIST:检测所有的轮廓,并将其保存在一条链表中;
3.cv2.RETR_CCOMP:检测所有的轮廓,并将他们组织为两层:顶层是个部分的外部边界,第二次是空洞的边界;
4.cv2.RETR_TREE:检测所有的轮廓,并重构前台轮廓的整个层次。


  • 第四种用得最多。


– method:轮廓逼近方法:
1.cv2.CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列);存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1;
2.cv2.CHAIN_APPROX_SIMPLE:压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息;
3.cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法。


绘制轮廓API:

  • cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]]):绘制轮廓
    为了更高的准确率,我们使用二值图像。


  • image:在哪个图像上绘制轮廓;contours:检测 *** 作得到的轮廓,是个list;contourIdx:指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。


import cv2
import numpy as np

if __name__ == '__main__':
	# 二值图像的转化
    img = cv2.imread('./img.jpeg')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
    binary, contours, hierarchy = cv2.findContours(thresh, cv2,RETR_TREE, cv2.CHAIN_APPROX_NONE)
    #传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
    #注意要对原图使用copy,不然原图也会改变
    draw_img = img.copy()
    res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)
    cv2.imshow('img', thresh)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
9.2 轮廓特征

调用对应API得到结果,仅此而已,用到的时候再说吧。






import cv2
import numpy as np

if __name__ == '__main__':
	# 二值图像的转化
    img = cv2.imread('./img.jpeg')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
    binary, contours, hierarchy = cv2.findContours(thresh, cv2,RETR_TREE, cv2.CHAIN_APPROX_NONE)
    #开始查看轮廓特征,从列表中取出一个
    cnt = contours[0]
    #面积
    cv2.contourArea(cnt)
    #周长,True表示闭合
    cv2.areLength(cnt, True)
9.3 轮廓近似 9.3.1 近似图形
  • cv2.approxPolyDP(contour, epsilon, isClosed)
    轮廓近似
import cv2
import numpy as np

if __name__ == '__main__':
	# 二值图像的转化
    img = cv2.imread('./contours.png')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
    binary, contours, hierarchy = cv2.findContours(thresh, cv2,RETR_TREE, cv2.CHAIN_APPROX_NONE)
   
    cnt = contours[0]
	draw_img = img.copy()
    res = cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2)
	#轮廓近似
	epsilon = 0.1 * cv2.arcLength(cnt, True)
	approx = cv2.approxPolyDP(cnt, epsilon, True)
	draw_img = img.copy()
    res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)
    cv2.imshow('res', res)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
9.3.2 外接矩形 9.3.2.1 直边界矩形

没有进行旋转,所以该边界矩形的面积不是最小的。


  • cv2.boundingRect(contour)

  • 返回4个值:x,y,w,h(x,y为矩形左上角坐标,w,h为矩形宽,高)

  • 先靠这个API获取外界举行的信息,再用图像绘制中的cv2.rectangle()绘制外界矩形。


import cv2
import numpy as np

if __name__ == '__main__':
	# 二值图像的转化
    img = cv2.imread('./contours.png')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
    binary, contours, hierarchy = cv2.findContours(thresh, cv2,RETR_TREE, cv2.CHAIN_APPROX_NONE)
    cnt = contours[0]

	x, y, w, h = cv2.boundingRect(cnt)
	img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
	cv2.imshow('img', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
9.3.2.2 旋转边角矩形

需要用到角点知识,后面再进行补充。


  • cv2.minAreaRect(contour)
  • 返回5个值:矩形左上角角点坐标(x, y),矩形的宽和高(w, h)以及旋转角度。


  • 绘制该矩形需要矩形的四个角点,可通过函数cv2.boxPoints()获得。


import cv2
import numpy as np

if __name__ == '__main__':
	# 二值图像的转化
    img = cv2.imread('./contours.png')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
    binary, contours, hierarchy = cv2.findContours(thresh, cv2,RETR_TREE, cv2.CHAIN_APPROX_NONE)
    cnt = contours[0]

	s = cv2.minAreaRect(cnt)
	a = cv2.boxPoints(s)
	a = np.int0(a)
	cv2.polylines(img, [a], True, (0, 0, 255), 2)
	cv2.imshow('img', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
9.3.3 最小外接圆
  • cv2.minEnclosingCircle(contour)
  • 返回中心点(x, y)和圆的半径radius
import cv2
import numpy as np

if __name__ == '__main__':
	# 二值图像的转化
    img = cv2.imread('./contours.png')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
    binary, contours, hierarchy = cv2.findContours(thresh, cv2,RETR_TREE, cv2.CHAIN_APPROX_NONE)
    cnt = contours[0]
	#注意都需要转换成int型
	(x, y), radius = cv2.minEnclosingCircle(cnt)
	center = (int(x), int(y))
	radius = int(radius)
	img = cv2.circle(img, center, radius, (0, 255, 0), 2)
	cv2.imshow('img', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/568265.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)

保存