OpenCV4图像处理--图像轮廓计算

轮廓面积与周长

求解方法

在这里插入图片描述

  • C++ API: contourAreaarcLength
//计算轮廓面积
CV_EXPORTS_W double contourArea( InputArray contour, bool oriented = false );
//计算轮廓周长
CV_EXPORTS_W double arcLength( InputArray curve, bool closed );
  • 利用轮廓的面积和周长,对轮廓进行过滤
Mat src = imread("F:/code/images/rice.png");
	CV_Assert(!src.empty());
	namedWindow("input", WINDOW_AUTOSIZE);
	imshow("input", src);


	//高斯滤波
	GaussianBlur(src, src, Size(3, 3), 0);

	//得到灰度图
	Mat gray, binary;
	cvtColor(src, gray, COLOR_RGB2GRAY);
	imshow("gray", gray);

	//得到二值图
	threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
	imshow("binary", binary);

	
	//发现轮廓
	vector<vector<Point>>contours;//因为每个contour都是一系列点的集合
	vector<Vec4i> hierarchy;//层次信息
	findContours(binary, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());

	printf("%llu", contours.size());//25

	for (size_t t = 0; t < contours.size(); t++) {

		//图像轮廓计算:计算面积和周长
		double area = contourArea(contours[t]);
		double length = arcLength(contours[t], true);
		printf("area:%.2f, contour length:%.2f\n", area, length);
		//通过面积和周长来过滤掉一些轮廓
		if (area < 1800 || length < 10) continue;
		drawContours(src, contours, t, Scalar(0, 0, 255), 1, 8);
	}
	imshow("find contours demo", src);
  • python API
area = cv2.contourArea(cnt)

# 可以使用cv.arcLength()获取轮廓的周长。第二个参数规定了这个轮廓是否是闭合的,True代表是闭合的,False代表轮廓仅仅是一个曲线。
perimeter = cv2.arcLength(cnt, True)

图像的矩

  • python API
cv2.moments()用来获取轮廓的矩,通过图像的矩可以计算某些特征,比如说物体的重心等等

import numpy as np
import cv2 as cv
img = cv.imread('test.jpg',0)
ret,thresh = cv.threshold(img,127,255,0)
contours,hierarchy = cv.findContours(thresh, 1, 2)
cnt = contours[0]
M = cv.moments(cnt) #计算图像矩
print( M )

图像的重心

  • 对于上面获取的 M,可以提炼出一些有用的信息,比如说面积重心等等。重心可以通过以下方程进行计算:
    在这里插入图片描述
cx = int(M['m10']/M['m00'])#重心的x坐标
cy = int(M['m01']/M['m00'])#重心的y坐标
  • moments 中的 M[‘m00’] 就是轮廓的面积

对轮廓的其他计算

获取轮廓最大外接矩形、旋转矩形、轮廓最小外接矩形

  • C++ API
    boundingRect()得到包覆此轮廓的最小正矩形,minAreaRect()得到包覆轮廓的最小斜矩形
CV_EXPORTS_W Rect boundingRect( InputArray array );
CV_EXPORTS_W RotatedRect minAreaRect( InputArray points );
  • 轮廓的旋转矩形是通过minAreaRect返回的旋转矩形
  • 轮廓的最小外接矩形利用获取旋转矩形的四个顶点,通过绘制四条直线实现绘制
		//获取轮廓最大外接矩形
		Rect box = boundingRect(contours[t]);
		rectangle(src, box, Scalar(0,0,255), 1, LINE_AA);
		
		//椭圆绘制
		RotatedRect rrt = minAreaRect(contours[t]);
		ellipse(src, rrt, Scalar(255, 0, 0), 1, 8);

		//获取轮廓最小外接矩形
		Point2f pts[4];
		rrt.points(pts);
		for (int i = 0; i < 4; i++) {
			line(src, pts[i], pts[(i + 1) % 4], Scalar(0, 255, 0), 1, 8);//编程技巧 % 4
		}

在这里插入图片描述

  • python API
cv2.boundingRect(cnt) 
# 返回四个值,分别是 x,y,w,h;
# x,y是矩阵左上点的坐标,w,h是矩阵的宽和高


bgr_img = cv2.imread("./demo.jpeg")
gray_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2GRAY)
th, binary = cv2.threshold(gray_img, 0, 255, cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(bgr_img, contours, -1, (0, 0, 255), 3)
 
bounding_boxes = [cv2.boundingRect(cnt) for cnt in contours]
 
for bbox in bounding_boxes:
     [x , y, w, h] = bbox
     cv2.rectangle(bgr_img, (x, y), (x + w, y + h), (0, 255, 0), 2)
 
cv2.imshow("name", bgr_img)
cv2.waitKey(0)
cv2.minAreaRect(Points)

# minAreaRect函数返回rect对象
# rect[0]返回矩形的中心点,(x,y),实际上为y行x列的像素点
# rect[1]返回矩形的长和宽
# rect[2]返回矩形的旋转角度

注意:(1) cv2.boxPoints(rect)可以返回四个点的值,其中cv2.boxPoints(rect)[0]为point[0],cv2.boxPoints(rect)[1]为point[1]…
在这里插入图片描述(2) 旋转角度,angel是由x轴逆时针转至W(宽)的角度,角度范围是[-90,0)
在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值