網站首頁 編程語言 正文
為了加深對中值濾波算法的理解以及方便以后更好的復習,我將該算法的一些重點細節和實現過程踩過的坑記錄下來。
中值濾波器是一種非線性濾波器,或者叫統計排序濾波器。
適用對象:帶椒鹽噪聲的圖像
由于椒鹽噪聲像素值與原圖像素值沒有關聯,隨機性較大,因此使用中值濾波可有效濾掉噪聲。
中值濾波需要對像素值進行排序,因此首先寫一個冒泡排序算法。
冒泡排序實現:
為提高效率加入標志位flag,當第i次尋找最大值時,如果相鄰兩個數均未發生互換,此時flag位為false,即說明此時數組已經按照遞增排列,可提前終止。此處應該注意flag=false所在位置,因為需要保證第i次尋找最大值過程中,遍歷到所有未參與排列的數據,所以flag=false應該放在循環條件for(int j=0; j<len-1-i; j++)的外部。
void bubble(std::vector<int> &arr, int len)
{
bool flag = true;
for (int i = 0; i < len-1; i++)
{
while (flag)
{
flag = false;
for (int j = 0; j < len - i - 1; j++)
{
if (arr[j + 1] < arr[j])
{
flag = true; //只要發生一次交換就繼續判斷
int temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
}
}
中值濾波的實現:
需要注意的主要問題:
為了能夠遍歷到原圖的邊界,需要對原圖進行邊界擴充,擴充長度為(窗口的長度-1)/ 2。
注意利用窗口對擴充后的圖像遍歷時,起始的位置不是0,而是擴充的長度,因為這時對應的才是原圖的第一個像素點,同理結束的位置也是原圖的最后一個像素點。
另外為了方便將窗口內對應的像素存到容器中,可以寫兩個循環,循環長度為窗口的長度與寬度,依次將像素值存入容器中。
最后對容器內的像素按照遞增排列后,取中值賦給目標矩陣相應的位置,而此時的位置也應該用i-h,對應擴充前的位置。
經實踐證明我寫的這兩個算法可有效使用。
void medianFilter(cv::Mat& src, cv::Mat& dst, cv::Size width)
{
//判斷窗口是否為奇數
if (width.width % 2 == 0 || width.height % 2 == 0)
{
std::cout << "輸入窗口大小應該為奇數,請重新輸入" << endl;
exit(-1);
}
else
{
//計算邊界擴充長度
int h = (width.height - 1) / 2;
int w = (width.width - 1) / 2;
//對原圖邊界擴充
cv::Mat src_border;
cv::copyMakeBorder(src, src_border, h, h, w, w, cv::BORDER_REFLECT_101);
for (int i = h; i < src.rows + h; i++)
{
for (int j = w; j < src.cols + w; j++)
{
//定義容器存放窗口對應的像素
std::vector <int> v;
for (int ii = i - h; ii <= i + h; ii++)
{
for (int jj = j - w; jj <= j + w; jj++)
{
v.push_back(src_border.at<uchar>(ii, jj));
}
}
//對容器內存放的像素排序
int len = width.area();
bubble(v, len);
//將中值賦給目標圖像對應位置
dst.at<uchar>(i-h, j-w) = v[(len - 1) / 2];
}
}
}
}
原文鏈接:https://blog.csdn.net/qq_62945476/article/details/123694500
相關推薦
- 2023-02-01 Python?asyncore?socket客戶端開發基本使用教程_python
- 2022-07-10 springboot 將logback日志根據不同類輸入到不同路徑下
- 2022-11-28 Python?redis模塊的使用教程指南_python
- 2022-06-22 Git文件常用操作總結及拓展_其它綜合
- 2021-12-02 C++內存分布及用法_C 語言
- 2022-07-13 Atom 常用快捷鍵
- 2022-04-11 【Android】覺得不好看?自定義CheckBox樣式
- 2022-10-08 docker安裝redis并掛載到本地的詳細教程_docker
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支