1. 程式人生 > >直方圖實現快速中值濾波

直方圖實現快速中值濾波

  1 #include <opencv2\opencv.hpp>
  2 #include <iostream>
  3 #include <string>
  4 
  5 using namespace cv;
  6 using namespace std;
  7 
  8 //計算亮度中值和灰度<=中值的畫素點個數
  9 void CalculateImage_MedianGray_PixelCount(const Mat &histogram, int pixelCount, int &medianValue, int &pixleCountLowerMedian)
10 { 11 float *data = (float *)histogram.data;//直方圖 12 int sum = 0; 13 for (int i = 0; i <= 255; ++i) 14 { 15 // 16 sum += data[i]; 17 if (2 * sum>pixelCount) 18 { 19 medianValue = i; 20 pixleCountLowerMedian = sum; 21
break; 22 } 23 } 24 } 25 26 void fastMedianBlur(const Mat &srcImg, Mat &dstImg, int diameter) 27 { 28 int radius = (diameter - 1) / 2; 29 int imgW = srcImg.cols; 30 int imgH = srcImg.rows; 31 int channels = srcImg.channels(); 32 dstImg = Mat::zeros(imgH, imgW, CV_8UC1);
33 int windowSize = diameter*diameter; 34 Mat windowImg = Mat::zeros(diameter, diameter, CV_8UC1); 35 36 //直方圖 37 Mat histogram; 38 int histogramSize = 256;//灰度等級 39 int thresholdValue = windowSize / 2 + 1;//step1.設定閾值(步驟參考:影象的高效程式設計要點之四) 40 41 //待處理影象畫素 42 uchar *pDstData = dstImg.data + imgW*radius + radius; 43 //整個影象中視窗位置指標 44 uchar *pSrcData = srcImg.data; 45 46 //逐行遍歷 47 for (int i = radius; i <= imgH - 1 - radius; i++) 48 { 49 //列指標 50 uchar *pColDstData = pDstData; 51 uchar *pColSrcData = pSrcData; 52 53 //單個視窗指標 54 uchar *pWindowData = windowImg.data; 55 uchar *pRowSrcData = pColSrcData; 56 //從源圖中提取視窗影象 57 for (int winy = 0; winy <= diameter - 1; winy++) 58 { 59 for (int winx = 0; winx <= diameter - 1; winx++) 60 { 61 pWindowData[winx] = pRowSrcData[winx]; 62 } 63 pRowSrcData += imgW; 64 pWindowData += diameter; 65 } 66 67 //求直方圖,確定中值,並記錄亮度<=中值的畫素點個數 68 calcHist(&windowImg, 69 1,//Mat的個數 70 0,//用來計算直方圖的通道索引,通道索引依次排開 71 Mat(),//Mat()返回一個空值,表示不用mask, 72 histogram, //直方圖 73 1, //直方圖的維數,如果計算2個直方圖,就為2 74 &histogramSize, //直方圖的等級數(如灰度等級),也就是每列的行數 75 0//分量的變化範圍 76 ); 77 78 //求亮度中值和<=中值的畫素點個數 79 int medianValue, pixelCountLowerMedian; 80 CalculateImage_MedianGray_PixelCount(histogram, windowSize, medianValue, pixelCountLowerMedian); 81 ////////////滑動視窗操作結束/////////////////////// 82 83 //濾波 84 pColDstData[0] = (uchar)medianValue; 85 86 //處理同一行下一個畫素 87 pColDstData++; 88 pColSrcData++; 89 for (int j = radius + 1; j <= imgW - radius - 1; j++) 90 { 91 //維護滑動視窗直方圖 92 //刪除左側 93 uchar *pWinLeftData = pColSrcData - 1; 94 float *pHistData = (float*)histogram.data; 95 for (int winy = 0; winy < diameter; winy++) 96 { 97 uchar grayValue = pWinLeftData[0]; 98 pHistData[grayValue] -= 1.0; 99 if (grayValue <= medianValue) 100 { 101 pixelCountLowerMedian--; 102 } 103 pWinLeftData += imgW; 104 } 105 106 //增加右側 107 uchar *pWinRightData = pColSrcData + diameter - 1; 108 for (int winy = 0; winy < diameter; winy++) 109 { 110 uchar grayValue = pWinRightData[0]; 111 pHistData[grayValue] += 1.0; 112 if (grayValue <= medianValue) 113 { 114 pixelCountLowerMedian++; 115 } 116 pWinRightData += imgW; 117 } 118 //計算新的中值 119 if (pixelCountLowerMedian > thresholdValue) 120 { 121 while (1) 122 { 123 pixelCountLowerMedian -= pHistData[medianValue]; 124 medianValue--; 125 if (pixelCountLowerMedian <= thresholdValue) 126 { 127 break; 128 } 129 } 130 } 131 else 132 { 133 while (pixelCountLowerMedian < thresholdValue) 134 { 135 medianValue++; 136 pixelCountLowerMedian += pHistData[medianValue]; 137 138 } 139 } 140 141 pColDstData[0] = medianValue; 142 //下一個畫素 143 pColDstData++; 144 pColSrcData++; 145 } 146 //移動至下一行 147 pDstData += imgW; 148 pSrcData += imgW; 149 } 150 151 //邊界直接賦原始值,不做濾波處理 152 pSrcData = srcImg.data; 153 pDstData = dstImg.data; 154 //上下邊界 155 for (int j = 0; j < imgW; j++) 156 { 157 for (int i = 0; i < radius; i++) 158 { 159 int idxTop = i*imgW + j; 160 pDstData[idxTop] = pSrcData[idxTop]; 161 int idxBot = (imgH - i - 1)*imgW + j; 162 pDstData[idxBot] = pSrcData[idxBot]; 163 } 164 } 165 //左右邊界 166 for (int i = radius; i < imgH - radius - 1; i++) 167 { 168 for (int j = 0; j < radius; j++) 169 { 170 int idxLeft = i*imgW + j; 171 pDstData[idxLeft] = pSrcData[idxLeft]; 172 int idxRight = i*imgW + imgW - j-1; 173 pDstData[idxRight] = pSrcData[idxRight]; 174 } 175 } 176 } 177 178 179 void main() 180 { 181 string imgPath = "data/"; 182 Mat srcImg = imread(imgPath + "moon.jpg", 0); 183 Mat dstImg; 184 double t0 = cv::getTickCount(); 185 fastMedianBlur(srcImg, dstImg, 5); 186 //cv::medianBlur(srcImg, dstImg, 5); //OpenCV 187 double t1 = cv::getTickCount(); 188 cout << "time=" << (t1 - t0) / cv::getTickFrequency() << endl; 189 190 imwrite("data/test/srcImg.bmp", srcImg); 191 imwrite("data/test/myFilter.bmp", dstImg); 192 }

相關推薦

直方圖實現快速濾波

1 #include <opencv2\opencv.hpp> 2 #include <iostream> 3 #include <string> 4 5 using namespace cv; 6 using namespace std;

實時高速實現改進型濾波算法_愛學術_免費下載

models 編程 摘要 png 下載 ril document fpga bsp 【摘要】在圖像采集和處理過程中會引入噪聲,必須先對圖像進行預處理。本文介紹一種快速中值濾波算法,該算法在硬件平臺上實現實時處理功能。綜合考慮,選擇現場可編程門陣列(FPGA)作為硬件平臺,采

基於FPGA的快速濾波演算法--轉載我之前的blog的內容

轉: http://xiongwei.site/ 在實時影象採集中,不可避免的會引入噪聲,尤其是干擾噪聲和椒鹽噪聲,噪聲的存在嚴重影響邊緣檢測的效果,中值濾波是一種基於排序統計理論的非線性平滑計數,能有效平滑噪聲,且能有效保護影象的邊緣資訊,所以被廣泛用於數字影象

CVPR論文《100+ Times FasterWeighted Median Filter (WMF)》的實現和解析(附原始碼)。 任意半徑中值濾波(擴充套件至百分比濾波器)O(1)時間複雜度演算法的原理、實現及效果 任意半徑中值濾波(擴充套件至百分比濾波器)O(1)時間複雜度演算法的原理、實現

  四年前第一次看到《100+ Times FasterWeighted Median Filter (WMF)》一文時,因為他附帶了原始碼,而且還是CVPR論文,因此,當時也對程式碼進行了一定的整理和解讀,但是當時覺得這個演算法雖然對原始速度有不少的提高,但是還是比較慢。因此,沒有怎麼在意,這幾天有幾位朋友

關於濾波演算法,以及C語言實現

關於中值濾波演算法,以及C語言實現 2017年04月06日 11:45:58 閱讀數:1464 1、什麼是中值濾波? 中值濾波是對一個滑動視窗內的諸畫素灰度值排序,用其中值代替視窗中心象素的原來灰度值,它是一種非線性的影象平滑法,它對脈衝干擾級椒鹽噪聲的抑制效果好,在抑制隨機噪聲的同

verilog實現濾波

轉自:https://www.cnblogs.com/happyamyhope/ 前言: 首先謝謝原博主的文章,對我的幫助很大,提供了一個完整的思路,極大方便了我將演算法移植到FPGA上。 實現步驟: 1.查看了中值濾波實現相關的網站和paper; 2.按照某篇paper的設計思

基於MATLAB影象處理的濾波、均值濾波以及高斯濾波實現與對比

基於MATLAB影象處理的中值濾波、均值濾波以及高斯濾波的實現與對比 作者:lee神 1.背景知識 中值濾波法是一種非線性平滑技術,它將每一畫素點的灰度值設定為該點某鄰域視窗內的所有畫素點灰度值的中值. 中值濾波是基於排序統計理論的一種能有效抑制噪聲的非線性訊號處

opencv實現影象鄰域均值濾波濾波、高斯濾波

void CCVMFCView::OnBlurSmooth()//鄰域均值濾波 { IplImage* in; in = workImg; IplImage* out = cvCreateImage(cvGetSize(in),IPL_DEPTH_8U,workImg-&g

均值濾波濾波matlab實現

clc; close all; %原始圖片 283*289*3 data=imread('圖片1.png');%讀入圖片,圖片複製到當前資料夾 subplot(221); imshow(data); title('原始圖片'); %二值化 283*289 gdata=rgb2gray(dat

自適應濾波實現

前言 無意中看到了一篇比較老的論文,Adaptive median filters: new algorithms and results。感興趣的可以下載下來看看。主要就是提出了一種自適應中值濾波演算法,這個演算法是很經典的中值濾波演算法的改進版本,自動選擇

濾波原理及MATLAB演算法實現

中值濾波是一種非線性濾波方式,它依靠模板來實現。 對於一維中值濾波,設模板的尺寸為 M ,M=2*r+1,r為模板半徑,給定一維訊號f(i),i = 1,2,3……N,則中值濾波輸出為: g(i) = median[ f(j-r),f(j-r+1),…………,f(j),f(

MATLAB實現濾波演算法

x = imread('C:\Users\Administrator\Desktop\im7.jpg'); x = rgb2gray(x); [m, n] = size(x); %m表示行數(即高度);n表示列數(即寬度) x = imnoise(x,'salt &

數字影象處理,自適應濾波的C++實現

自適應中值濾波的原理      自適應中值濾波的思想是根據噪聲密度改變濾波視窗的大小,同時對噪聲點和訊號點採取不同的處理方法。對噪聲點進行中值濾波,對訊號點保持其灰度值不變。        設為fij

第三節--一種改進的濾波策略的實現

 //----------------------------------------【一種改進的中值濾波策略的實現】------------------------------------ //1--傳統的中值濾波器的缺點:中值濾波的效果依賴於--濾波視窗的大小,太大

VC++高斯濾波\中濾波實現影象模糊處理

一、演算法 高斯模糊演算法 詳見:高斯模糊,基本思想就是利用高斯函式,將一個座標點的所有鄰域的加權平均值設定為這些點的顏色值。 中值濾波演算法就更簡單了:將一個座標點的所有鄰域的平均值設定為這些點的畫素值。 二、演算法的程式碼實現 高斯函式: 使用巨集定義來替換: #de

基於Opencv的自適應濾波函數selfAdaptiveMedianBlur()

blog com begin clas logs opencv2 cal return mat 終於搞出來了:) #include <iostream> #include <opencv2/opencv.hpp> #include &l

均值濾波濾波,最大最小濾波

fin proc repeat 效果 mod ava rom static 包含 http://blog.csdn.net/fastbox/article/details/7984721 討論如何使用卷積作為數學工具來處理圖像,實現圖像的濾波,其方法包含以下幾種,均值 濾波

【NOIP 模擬賽】濾波 打表找規律

超出 數學 printf clas col else 中值濾波 include noi 對於這樣看起來不像什麽算法也沒什麽知識點的題,一臉懵逼的話不是手推規律就是打表找規律......... 當然還有一些超出你能力之外的數學題...... #include <

opencv3 圖片模糊操作-均值濾波 高斯濾波 濾波 雙邊濾波

empty size mage point ima could not key image ace #include <iostream>#include <opencv2/opencv.hpp> using namespace std;using

0025-給影象新增椒鹽噪聲之後用均值濾波濾波過濾影象!

椒鹽噪聲是椒噪聲和鹽噪聲的合稱,它是由影象感測器,傳輸通道,解碼處理等產生的黑白相間的亮暗點噪聲,去除椒鹽噪聲的最常用演算法是中值濾波,在去除椒鹽噪聲的效果上均值濾波不如中值濾波,本文所給的程式碼會證明這個結論。 首先說下怎麼給影象加上椒噪聲和鹽噪聲。我們可以利用C++的srand函式和rand