基於L0測度的優化能量公式的流場平滑
阿新 • • 發佈:2018-11-24
視訊網址:https://www.bilibili.com/video/av36468467/
程式碼網址:https://download.csdn.net/download/lykymy/10799373
影象能量的計算
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); } }