基于OpenCV的圆周率PI值的估计

版权声明:未经吾理小子本人允许,禁止转载! https://blog.csdn.net/qq_39960119/article/details/82945552

 好久没有写博客了,今天有空写一下自己做的一个小实验,有兴趣的伙伴一起验证一下。刚刚开始学习计算机视觉,OpenCV没有基础,刚刚接触这门语言,就做几个小实验练习一下。

 好了,废话不多说,进入正题。吾理小子估计圆周率的值是通过内接圆完成的,首先简述一下原理。

                                             

如上图所示,圆内接于正方形。设圆的半径为R,易得圆的面积和正方形的面积如下:

                                                               S_{a}=Pi*R^{2}

                                                               S_{s}=4*R^{2}

由此可得:

                                                               Pi=4*\frac{S^{_{a}}}{S_{s}}

有上式可知,如果知道圆的面积和正方形的面积,就可以求出圆周率Pi的值。

此时,我们假设有一个未知边长的正方形及其内接圆。我们可以通过向正方形内随机撒入多个噪点,由噪点的个数来近似正方形的面积,用落在圆内的噪点个数来等效圆的面积,由此就可以估算圆周率Pi的值了。

接下来,使用OpenCV来实现上述过程。我将源码贴在文末,供各位小伙伴参考。

下面先给出程序的运行过程,以及估计结果。

                              

                              

                              

上面三幅图分别是估计过程中的三个图,最后一幅图是估计结果3.13908,与真实值3.1415还是比较接近的。可以通过进一步增大正方形的边长来提高估计精度。最后贴上源码。


#include <iostream>
#include <opencv2\opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
	const int side = 600;        //定义正方形边长
	const int npixels = 300000;  //定义随机点个数

	int i, j;
	Mat s1 = Mat::zeros(side,side,CV_8UC1);
	Mat s2 = s1.clone();         //图像s1,s2均为0值,即纯黑
	circle(s1, Point(side / 2, side / 2), side / 2, 255, -1);//在s1正方形图像中开辟一个内接圆
	imshow("s1", s1); //显示s1图像

	for (int k = 0; k < npixels; k++)  //产生随机数,撒在图像s2中
	{
		i = rand() % side;
		j = rand() % side;
		s2.at<uchar>(i, j) = 255;
	}

	Mat r;    //定义输出图像r
	bitwise_and(s1,s2,r); //图像s1与s2进行与运算

	imshow("s2", s2);     //显示图像s2
	imshow("r", r);       //显示图像r

	int Acircle = countNonZero(r);   //统计图像r中的非零点个数
	int Square = countNonZero(s2);   //统计图像s2中的非零点个数
	float pi = 4 * (float)Acircle / Square;  //估计圆周率的值

	cout << "PI的值:" << pi << endl;  //输出圆周率的值

	waitKey(0);
	return 0;

}


 

猜你喜欢

转载自blog.csdn.net/qq_39960119/article/details/82945552