求最小外接矩形的面积(C++实现)

求最小外接矩形的面积

求最小外接矩形的原理

最近在做课程设计的过程中遇到了一个问题,需要求出一幅图像中物体的矩形度,但是求解矩形度需要用到该物体的最小外接矩形的面积。所以我查了各种资料想要写一个求解物体最小外接矩形的代码。

首先我们来看一下求解的原理。一个物体的与x轴和y轴平行的外接矩形就是这个物体的简单外接矩形,显然,物体的简单外接矩形是比较容易计算面积的。那么我们只需要将物体旋转一定的角度,再求出旋转后的简单外接矩形,最后得到最小的简单外接矩形的面积就行了,而旋转的角度在正负90°之间,以1°为1个间隔。

因为我们只要求解面积而不需要将这个矩形画出来,所以可以采用C++中的set容器来实现,set容器具有自动排序的功能。

大致实现算法如下:
在这里插入图片描述

C++实现代码

// 求解最小外接矩形面积
long lengthAndWidth(LPSTR lpSrcStartBits, long lSrcWidth, long lSrcHeight, int label)
{
	unsigned char* lpSrc;
	int* pixel = new int[2];
	pixel[0] = pixel[1] = 0;
	long lLineBytes = WIDTHBYTES(lSrcWidth * 8);
	// 旋转角度(弧度)
	float	fRotateAngle;
	// 旋转角度的正弦和余弦
	float fSina, fCosa;
	int rotate = 0;
	long x0, y0;
	std::set<int> setx,sety;
	long min = 10000000;
	long square = 0;
	for (rotate = -90;rotate <= 90;rotate++)
	{
		// 将旋转角度从度转换到弧度
		fRotateAngle = (float)((rotate)*PI / 180.0);
		// 计算旋转角度的正弦
		fSina = (float)sin((double)fRotateAngle);
		// 计算旋转角度的余弦
		fCosa = (float)cos((double)fRotateAngle);
		for (long i = 0;i < lSrcHeight;i++)//旋转
		{
			for (long j = 0;j < lSrcWidth;j++)
			{
				lpSrc = (unsigned char*)lpSrcStartBits + lLineBytes * (lSrcHeight - 1 - i) + j;
				if (*lpSrc == label)
				{
					x0 = j * fCosa - i * fSina + 0.5;
					y0 = j * fSina + i * fCosa + 0.5;
					setx.insert(x0);
					sety.insert(y0);
				}
			}
		}
		square = abs((*setx.rbegin() - *setx.begin() + 1) * (*sety.rbegin() - *sety.begin() + 1));
		if(min > square)
		{
			min = square;
			pixel[0] = *setx.rbegin() - *setx.begin() + 1;
			pixel[1] = *sety.rbegin() - *sety.begin() + 1;
		}
		setx.clear();sety.clear();
	}
	return (pixel[0]*pixel[1]);
 }

当然这份代码只对8位图像有效,我们也可以参照算法把它改成适用于24位图像的代码。

参考文章:
https://zhuanlan.zhihu.com/p/97855964.

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要计算连通域的最小矩形面积,可以使用OpenCV库中的`minAreaRect`函数来获取最小矩形的四个顶点,然后通过计算两个相邻顶点之间的距离,再计算矩形的宽和高,最后计算矩形面积。 以下是一个示例代码: ```cpp #include <opencv2/opencv.hpp> using namespace cv; int main() { // 读取图像 Mat image = imread("image.jpg", IMREAD_GRAYSCALE); // 进行二值化处理 Mat binary; threshold(image, binary, 0, 255, THRESH_BINARY | THRESH_OTSU); // 查找连通域 Mat labels, stats, centroids; int num_labels = connectedComponentsWithStats(binary, labels, stats, centroids); // 计算连通域最小矩形面积 for (int i = 1; i < num_labels; ++i) { // 获取连通域的最小矩形 RotatedRect rotated_rect = minAreaRect(Mat(binary, Rect(stats.at<int>(i, CC_STAT_LEFT), stats.at<int>(i, CC_STAT_TOP), stats.at<int>(i, CC_STAT_WIDTH), stats.at<int>(i, CC_STAT_HEIGHT)))); // 计算矩形的宽和高 float width = rotated_rect.size.width; float height = rotated_rect.size.height; // 计算矩形面积 float area = width * height; // 打印矩形面积 std::cout << "连通域" << i << "的最小矩形面积为:" << area << std::endl; } return 0; } ``` 在这个示例代码中,我们使用`minAreaRect`函数获取连通域的最小矩形,然后通过`RotatedRect`的`size`成员变量获取矩形的宽和高。最后,计算矩形面积并打印出来。请确保在运行代码之前安装OpenCV库并将图像路径替换为你自己的图像路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值