在当前代码中,使用一个循环来逐渐增加半径值(currentRadius)直到满足条件。如果你想找到更准确的满足条件的半径值,可以进行以下修改:
- 在进入 while 循环之前,定义一个变量 previousRadius 来保存上一次满足条件的半径值。
- 将 currentRadius 的增加步长改为较小的值(例如每次增加 1)。
- 当 sum 大于等于 sum1 * ratio / 100 时,跳出循环。
- 在循环结束后,通过比较 sum 和 sum1 * ratio / 100 的差异来确定更接近目标的半径值。
下面是修改后的代码示例:
cv::Mat image1;
//image.copyTo(image1);
image1 = image.clone();
int sum = 0;
int currentRadius = 0;
int previousRadius = 0; // 添加变量保存上一次满足条件的半径值
int sum1 = cv::sum(image1)[0]; // 计算灰度图像的像素总和
while (sum < sum1 * ratio / 100)
{
// 遍历每个像素点
sum = 0;
#pragma omp parallel for reduction(+:sum)
for (int i = Center.y - currentRadius; i <= Center.y + currentRadius; ++i)
{
double powIcenterX = pow(i - Center.y, 2);
uchar* rowPtr = image1.ptr<uchar>(i); // 获取当前行指针,减少内存访问次数
for (int j = Center.x - currentRadius; j <= Center.x + currentRadius; ++j)
{
// 确保不会超出图像范围
if (i >= 0 && i < image1.rows && j >= 0 && j < image1.cols)
{
// 计算欧几里得距离
double distance = sqrt(powIcenterX + pow(j - Center.x, 2));
// 如果在半径范围内且该像素未被处理过,则将灰度值累加到总和中
if (distance <= currentRadius && rowPtr[j] != 0)
{
//#pragma omp atomic update
sum += rowPtr[j];
// 将已处理过的像素值设为0,表示已累加过
//rowPtr[j] = 0;
}
}
}
}
if (sum >= sum1 * ratio / 100) {
previousRadius = currentRadius;
}
currentRadius++; // 增加半径值,向外扩展
}
currentRadius = previousRadius; // 使用上一次满足条件的半径值
beamdiameter_energy = currentRadius * 2;
return true;
通过保存上一次满足条件的半径值,并在循环结束后将其赋给 currentRadius,可以获取更接近目标的半径值。
内容由零声教学AI助手提供,问题来源于学员提问




