如果你想每次只增加多出的那几圈半径,可以在循环中判断是否需要增加20(或其他值),而不是固定地每次都增加20。你可以通过计算当前总和与目标总和之间的差异来确定是否需要增加半径。
以下是修改后的代码片段:
cv::Mat image1;
image.copyTo(image1);
int sum = 0;
int currentRadius = 0;
int sum1 = cv::sum(image1)[0]; // 计算灰度图像的像素总和
while (sum < sum1 * ratio / 100)
{
// 遍历每个像素点
#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;
}
}
}
}
int nextRadius = currentRadius + 20; // 增加20作为下一个半径
int nextSum = 0;
// 计算下一个半径对应的总和(包括新增的圈)
for (int i = Center.y - nextRadius; i <= Center.y + nextRadius; ++i)
{
double powIcenterX = pow(i - Center.y, 2);
uchar* rowPtr = image1.ptr<uchar>(i); // 获取当前行指针,减少内存访问次数
for (int j = Center.x - nextRadius; j <= Center.x + nextRadius; ++j)
{
// 确保不会超出图像范围
if (i >= 0 && i < image1.rows && j >= 0 && j < image1.cols)
{
// 计算欧几里得距离
double distance = sqrt(powIcenterX + pow(j - Center.x, 2));
// 如果在下一个半径范围内且该像素未被处理过,则将灰度值累加到总和中
if (distance <= nextRadius && rowPtr[j] != 0)
{
nextSum += rowPtr[j];
}
}
}
}
// 判断是否需要增加半径
if (nextSum - sum >= sum1 * ratio / 100)
{
currentRadius = nextRadius;
sum = nextSum;
}
}
这样,每次只会增加多出的那几圈半径。请根据你的实际需求进行调整和测试。
内容由零声教学AI助手提供,问题来源于学员提问