日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【机器视觉学习笔记】双边滤波算法(C++)

發布時間:2023/12/9 c/c++ 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【机器视觉学习笔记】双边滤波算法(C++) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 源碼
    • 濾波器
    • 主函數
  • 效果
  • 完整源碼

平臺:Windows 10 20H2
Visual Studio 2015
OpenCV 4.5.3


本文所用源碼修改自雙邊濾波(bilateral filter)以及聯合雙邊濾波(joint bilateral filter)—— flow_specter

源碼

濾波器

// 雙邊濾波 // @ src 待濾波的影像 // @ dst 輸出的影像 void BilateralFilter(Mat& src, Mat& dst, int d, double sigmaColor, double sigmaSpace) {dst = src.clone();int n_rows = dst.rows;int n_cols = dst.cols;int n_channels = dst.channels();int n_cols_with_channels = n_cols * n_channels;int half_kernel_size = d / 2;int index;double pixel_sum;double weight_sum = 0;double temp_bilateral_weight = 0;double color_kernel[256];// 顏色域權重確定// @ color_kernel 顏色域核,1D,長度為256for (int i = 0; i < 256; i++){color_kernel[i] = exp(-1.0 * (i * i) / (2 * sigmaColor * sigmaColor));}// 空間域權重確定// @ distance_kernel 空間域核,1D// **************************************************************************************************************double *distance_kernel;distance_kernel = new double[d * d];int k = d / 2;//二維動態數組申請空間double **distance_kernel_2D = new double*[d];for (int i = 0; i < d; i++)distance_kernel_2D[i] = new double[d];double delta_square = 2 * sigmaSpace * sigmaSpace; //分母for (int i = -k; i <= k; i++){for (int j = -k; j <= k; j++){double distance_numerator = i * i + j * j;distance_kernel_2D[i + k][j + k] = exp(-1.0 * distance_numerator / delta_square);}}// 將2D kernel 轉換為 1D kernelfor (int i = 0; i < d; i++){for (int j = 0; j < d; j++){distance_kernel[d * i + j] = distance_kernel_2D[i][j];}}//釋放二維動態數組空間for (int i = 0; i < d; i++)delete[] distance_kernel_2D[i];delete[] distance_kernel_2D;// **************************************************************************************************************// 邊界不做處理for (int i = half_kernel_size; i < (n_rows - half_kernel_size); i++) {uchar* pt_dst = dst.ptr<uchar>(i);uchar* pt_src = src.ptr<uchar>(i);for (int j = n_channels * half_kernel_size; j < (n_cols_with_channels - n_channels * half_kernel_size); j++) {index = 0;pixel_sum = weight_sum = 0;// 內層kx,ky循環,空間域內濾波for (int kx = i - half_kernel_size; kx <= i + half_kernel_size; kx++) {uchar* pt_k_src = src.ptr<uchar>(kx);for (int ky = j - n_channels * half_kernel_size; ky <= (j + n_channels * half_kernel_size); ky += n_channels) {temp_bilateral_weight = distance_kernel[index++] * color_kernel[(int)abs(pt_src[j] - pt_k_src[ky])];weight_sum += temp_bilateral_weight;pixel_sum += (pt_k_src[ky] * temp_bilateral_weight); // 鄰域某像素與中心點的雙邊權重乘積}}pixel_sum /= weight_sum; // 歸一化pt_dst[j] = saturate_cast<uchar>(pixel_sum); //加權賦值}}delete[]distance_kernel; } //———————————————— //版權聲明:本文為CSDN博主「flow_specter」的原創文章,遵循CC 4.0 BY - SA版權協議,轉載請附上原文出處鏈接及本聲明。 //原文鏈接:https ://blog.csdn.net/flow_specter/article/details/107557303

主函數

圖片路徑根據實際情況調整,注意反斜杠是轉義字符的開頭,故“\”應替換為“\”

int main(int argc, char * argv[]) {Mat src = imread("D:\\Work\\OpenCV\\Workplace\\Test_1\\face.jpg");Mat dst;BilateralFilter(src, dst, 23, 35, 10);imshow("原圖", src);imshow("輸出", dst);waitKey(0);return 0; }

效果

完整源碼

#include <opencv2\opencv.hpp> #include <iostream>using namespace cv; using namespace std;// 雙邊濾波 // @ src 待濾波的影像 // @ dst 輸出的影像 void BilateralFilter(Mat& src, Mat& dst, int d, double sigmaColor, double sigmaSpace) {dst = src.clone();int n_rows = dst.rows;int n_cols = dst.cols;int n_channels = dst.channels();int n_cols_with_channels = n_cols * n_channels;int half_kernel_size = d / 2;int index;double pixel_sum;double weight_sum = 0;double temp_bilateral_weight = 0;double color_kernel[256];// 顏色域權重確定// @ color_kernel 顏色域核,1D,長度為256for (int i = 0; i < 256; i++){color_kernel[i] = exp(-1.0 * (i * i) / (2 * sigmaColor * sigmaColor));}// 空間域權重確定// @ distance_kernel 空間域核,1D// **************************************************************************************************************double *distance_kernel;distance_kernel = new double[d * d];int k = d / 2;//二維動態數組申請空間double **distance_kernel_2D = new double*[d];for (int i = 0; i < d; i++)distance_kernel_2D[i] = new double[d];double delta_square = 2 * sigmaSpace * sigmaSpace; //分母for (int i = -k; i <= k; i++){for (int j = -k; j <= k; j++){double distance_numerator = i * i + j * j;distance_kernel_2D[i + k][j + k] = exp(-1.0 * distance_numerator / delta_square);}}// 將2D kernel 轉換為 1D kernelfor (int i = 0; i < d; i++){for (int j = 0; j < d; j++){distance_kernel[d * i + j] = distance_kernel_2D[i][j];}}//釋放二維動態數組空間for (int i = 0; i < d; i++)delete[] distance_kernel_2D[i];delete[] distance_kernel_2D;// **************************************************************************************************************// 邊界不做處理for (int i = half_kernel_size; i < (n_rows - half_kernel_size); i++) {uchar* pt_dst = dst.ptr<uchar>(i);uchar* pt_src = src.ptr<uchar>(i);for (int j = n_channels * half_kernel_size; j < (n_cols_with_channels - n_channels * half_kernel_size); j++) {index = 0;pixel_sum = weight_sum = 0;// 內層kx,ky循環,空間域內濾波for (int kx = i - half_kernel_size; kx <= i + half_kernel_size; kx++) {uchar* pt_k_src = src.ptr<uchar>(kx);for (int ky = j - n_channels * half_kernel_size; ky <= (j + n_channels * half_kernel_size); ky += n_channels) {temp_bilateral_weight = distance_kernel[index++] * color_kernel[(int)abs(pt_src[j] - pt_k_src[ky])];weight_sum += temp_bilateral_weight;pixel_sum += (pt_k_src[ky] * temp_bilateral_weight); // 鄰域某像素與中心點的雙邊權重乘積}}pixel_sum /= weight_sum; // 歸一化pt_dst[j] = saturate_cast<uchar>(pixel_sum); //加權賦值}}delete[]distance_kernel; } //———————————————— //版權聲明:本文為CSDN博主「flow_specter」的原創文章,遵循CC 4.0 BY - SA版權協議,轉載請附上原文出處鏈接及本聲明。 //原文鏈接:https ://blog.csdn.net/flow_specter/article/details/107557303int main(int argc, char * argv[]) {Mat src = imread("D:\\Work\\OpenCV\\Workplace\\Test_1\\face.jpg");Mat dst;BilateralFilter(src, dst, 23, 35, 10);imshow("原圖", src);imshow("輸出", dst);waitKey(0);return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的【机器视觉学习笔记】双边滤波算法(C++)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。