一、数学模型:
正方形及内接圆的面积:
A_circle = Pi × R × R
A_square = L × L = 4 × R × R
由此得到:
Pi = 4 × (A_circle / A_square)
二、算法
1.思想
简单的说即:通过在图像内的随机位置绘制许多像素并计算位于内接圆中像素的个数来估计内接圆的面积,正方形的面积就是绘制的像素的总数,进而可以估计出Pi的值。
2.过程
(1)在一个黑色的正方形图像上,画一个纯白色的内接圆;
(2)在另一个黑色的正方形图像上(和上面的正方形大小相同),随机绘制大量像素;
(3)在两幅图像之间进行一个二进制“与”运算(“AND”),并计算所产生的图像中的非零像素个数;
(4)使用上面公式估计Pi。
三、代码实现
//Pi.cpp by yh
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
const int side = 100;
const int npixels =8000;
int i, j;
Mat s1 = Mat::zeros(side, side, CV_8UC1);
Mat s2 = s1.clone();
circle(s1 ,Point(side/2,side/2),side/2,255,-1);
namedWindow("s1", WINDOW_NORMAL);
imshow("s1",s1);
//随机生成像素
for (int k = 0; k < npixels; k++)
{
i = rand() % side;
j = rand() % side;
s2.at<uchar>(i, j) = 255;
}
//逻辑“与”运算
Mat r;
bitwise_and(s1, s2, r);
namedWindow("s2", WINDOW_NORMAL);
imshow("s2",s2);
namedWindow("r", WINDOW_NORMAL);
imshow("r",r);
//计算正方形与内接圆的面积
int Acircle = countNonZero(r);
int Asquare = countNonZero(s2);
//根据公式估计Pi值
float Pi = 4 * (float)Acircle / Asquare;
cout << "Estimated value of Pi:" << Pi << endl;
waitKey();
return 0;
}
四、结果展示
End & Enjoy!