图像能量的计算
long min_energy(int value1, int value2)
{
int min_difference1 = 100, min_difference2 = 100;
int min_difference = abs(value2 - value1);
if ((value1 - 0) < min_difference1)
{
min_difference1 = value1 - 0;
}
if ((90 - value1) < min_difference1)
{
min_difference1 = 90 - value1;
}
if ((value2 - 0) < min_difference2)
{
min_difference2 = value2 - 0;
}
if ((90 - value2) < min_difference2)
{
min_difference2 = 90 - value2;
}
if (min_difference < (min_difference1 + min_difference2))
{
long temp = min_difference * min_difference;
return temp;
}
else
{
long temp = (min_difference1 + min_difference2) * (min_difference1 + min_difference2);
return temp;
}
}
void energy_solve(Mat & image, int time)
{
long sum = 0, temp = 0, up_difference = 0, down_difference = 0, left_difference = 0 , right_difference = 0;
for (int i = 1; i < image.rows - 1; i++)
{
for (int j = 1; j < image.cols - 1; j++)
{
up_difference = min_energy(image.at<short>(i, j) , image.at<short>(i - 1, j));
down_difference = min_energy(image.at<short>(i, j) , image.at<short>(i + 1, j));
left_difference = min_energy(image.at<short>(i, j) , image.at<short>(i, j - 1));
right_difference = min_energy(image.at<short>(i, j) , image.at<short>(i, j + 1));
temp = sqrt(up_difference + down_difference + left_difference + right_difference);
sum += temp;
}
}
cout << "This is "<< time << " Flow Field Energy Value : " << sum << endl;
}
L0测度平滑处理
void l0_smooth(Mat & image, float angle_rate, float side_rate, float left_down_rate, float right_down_rate, float right_top_rate, int time)
{
//创建grad_x和grad_y 、abs_grad_x和abs_grad_y矩阵
Mat grad_x;
Mat grad_y;
//创建sobel算子处理显示图片
Mat sobel_img = Mat::zeros(image.size(), CV_16S);
int scale = 1;
int delta = 0;
int ddepth = CV_16S;
//求X方向梯度
Sobel(image, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT);
//求Y方向梯度
Sobel(image, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT);
//构建流场
for (int i = 0; i < image.rows; i++)
{
for (int j = 0; j < image.cols; j++)
{
if (grad_x.at<ushort>(i, j) != 0)
{
sobel_img.at<short>(i, j) = atan(fabs(grad_y.at<ushort>(i, j) / grad_x.at<ushort>(i, j)));
}
else
{
sobel_img.at<short>(i, j) = 90;
}
}
}
//构造l0平滑流场
Mat l0_img = Mat::zeros(sobel_img.size(), CV_16S);
//构造临时变量
int left_down_value, right_down_value, right_top_value;
//计算图像的能量值
energy_solve(sobel_img, 0);
//重复迭代time次
for (int k = 1; k <= time; k++)
{
//进行l0平滑,处理中间部分
for (int i = 1; i < sobel_img.rows - 1; i++)
{
for (int j = 1; j < sobel_img.cols - 1; j++)
{
left_down_value = (sobel_img.at<short>(i - 1, j) - sobel_img.at<short>(i, j)) + (sobel_img.at<short>(i, j + 1) - sobel_img.at<short>(i, j)) + 2 * (sobel_img.at<short>(i - 1, j - 1) - sobel_img.at<short>(i, j));
right_down_value = (sobel_img.at<short>(i - 1, j) - sobel_img.at<short>(i, j)) + (sobel_img.at<short>(i, j - 1) - sobel_img.at<short>(i, j)) + 2 * (sobel_img.at<short>(i + 1, j + 1) - sobel_img.at<short>(i, j));
right_top_value = (sobel_img.at<short>(i + 1, j) - sobel_img.at<short>(i, j)) + (sobel_img.at<short>(i, j - 1) - sobel_img.at<short>(i, j)) + 2 * (sobel_img.at<short>(i - 1, j + 1) - sobel_img.at<short>(i, j));
l0_img.at<short>(i, j) = sobel_img.at<short>(i, j) + left_down_value *left_down_rate + right_down_value * right_down_rate + right_top_value * right_top_rate;
}
}
//进行l0平滑,处理上边缘部分
for (int t = 1; t < sobel_img.cols - 1; t++)
{
l0_img.at<short>(0, t) = sobel_img.at<short>(0, t) + side_rate * ((sobel_img.at<short>(0, t - 1) - sobel_img.at<short>(0, t)) + (sobel_img.at<short>(1, t) - sobel_img.at<short>(0, t)) + (sobel_img.at<short>(0, t + 1) - sobel_img.at<short>(0, t)));
}
//进行l0平滑,处理下边缘部分
for (int t = 1; t < sobel_img.cols - 1; t++)
{
l0_img.at<short>(l0_img.rows - 1, t) = sobel_img.at<short>(sobel_img.rows - 1, t) + side_rate * ((sobel_img.at<short>(sobel_img.rows - 1, t - 1) - sobel_img.at<short>(sobel_img.rows - 1, t)) + (sobel_img.at<short>(sobel_img.rows - 2, t) - sobel_img.at<short>(sobel_img.rows - 1, t)) + (sobel_img.at<short>(sobel_img.rows - 1, t + 1) - sobel_img.at<short>(sobel_img.rows - 1, t)));
}
//进行l0平滑,处理左边缘部分
for (int t = 1; t < sobel_img.rows - 1; t++)
{
l0_img.at<short>(t, 0) = sobel_img.at<short>(t, 0) + side_rate * ((sobel_img.at<short>(t - 1, 0) - sobel_img.at<short>(t, 0)) + (sobel_img.at<short>(t, 1) - sobel_img.at<short>(t, 0)) + (sobel_img.at<short>(t + 1, 0) - sobel_img.at<short>(t, 0)));
}
//进行l0平滑,处理右边缘部分
for (int t = 1; t < sobel_img.rows - 1; t++)
{
l0_img.at<short>(t, l0_img.cols - 1) = sobel_img.at<short>(t, sobel_img.cols - 1) + side_rate * ((sobel_img.at<short>(t - 1, sobel_img.cols - 1) - sobel_img.at<short>(t, sobel_img.cols - 1)) + (sobel_img.at<short>(t, sobel_img.cols - 2) - sobel_img.at<short>(t, sobel_img.cols - 1)) + (sobel_img.at<short>(t + 1, sobel_img.cols - 1) - sobel_img.at<short>(t, sobel_img.cols - 1)));
}
//进行l0平滑,处理左上角
l0_img.at<short>(0, 0) = sobel_img.at<short>(0, 0) + angle_rate * ((sobel_img.at<short>(0, 1) - sobel_img.at<short>(0, 0)) + (sobel_img.at<short>(1, 1) - sobel_img.at<short>(0, 0)) + (sobel_img.at<short>(1, 0) - sobel_img.at<short>(0, 0)));
//进行l0平滑,处理右上角
l0_img.at<short>(0, l0_img.cols - 1) = sobel_img.at<short>(0, sobel_img.cols - 1) + angle_rate * ((sobel_img.at<short>(0, sobel_img.cols - 2) - sobel_img.at<short>(0, sobel_img.cols - 1)) + (sobel_img.at<short>(1, sobel_img.cols - 2) - sobel_img.at<short>(0, sobel_img.cols - 1)) + (sobel_img.at<short>(1, sobel_img.cols - 1) - sobel_img.at<short>(0, sobel_img.cols - 1)));
//进行l0平滑,处理左下角
l0_img.at<short>(l0_img.rows - 1, 0) = sobel_img.at<short>(sobel_img.rows - 1, 0) + angle_rate * ((sobel_img.at<short>(sobel_img.rows - 2, 0) - sobel_img.at<short>(sobel_img.rows - 1, 0)) + (sobel_img.at<short>(sobel_img.rows - 2, 1) - sobel_img.at<short>(sobel_img.rows - 1, 0)) + (sobel_img.at<short>(sobel_img.rows - 1, 1) - sobel_img.at<short>(sobel_img.rows - 1, 0)));
//进行l0平滑,处理右下角
l0_img.at<short>(l0_img.rows - 1, l0_img.cols - 1) = sobel_img.at<short>(l0_img.rows - 1, sobel_img.cols - 1) + angle_rate * ((sobel_img.at<short>(l0_img.rows - 1, sobel_img.cols - 2) - sobel_img.at<short>(l0_img.rows - 1, sobel_img.cols - 1)) + (sobel_img.at<short>(l0_img.rows - 2, sobel_img.cols - 2) - sobel_img.at<short>(l0_img.rows - 1, sobel_img.cols - 1)) + (sobel_img.at<short>(l0_img.rows - 2, sobel_img.cols - 1) - sobel_img.at<short>(l0_img.rows - 1, sobel_img.cols - 1)));
for (int i = 0; i < l0_img.rows; i++)
{
for (int j = 0; j < l0_img.cols; j++)
{
if (l0_img.at<short>(i , j) < 0)
{
l0_img.at<short>(i, j) = 0;
}
if (l0_img.at<short>(i, j) > 90)
{
l0_img.at<short>(i, j) = 90;
}
}
}
//获取下次迭代图像
sobel_img = l0_img.clone();
//计算当前的图像能量
energy_solve(l0_img, k);
}
}
效果
原始处理图片