滤波算法(2)(最大值、最小值、低通、巴特沃斯、Robinson_Guard)

来源:互联网 发布:周传雄 知乎 编辑:程序博客网 时间:2024/05/22 13:08

最大值滤波

void max_filter(Mat src, Mat dst,int kernalsize){int ksize;if (kernalsize % 2 == 0){ksize = kernalsize / 2;}else{ksize = (kernalsize - 1) / 2;}if (kernalsize>src.rows || kernalsize>src.cols)cout << "核不合适" << endl;//最大值滤波操作for (int i = ksize; i < src.rows - ksize; i++){for (int j = ksize; j <src.cols - ksize; j++){int maxt = 0; //如果是最小值滤波则初始化maxt=255;for (int k = i - ksize; k <= i + ksize; k++)for (int m = j - ksize; m <= j + ksize; m++)if (maxt<src.at<uchar>(k, m))//如果是最小值滤波,小于号改成大于号就可maxt = src.at<uchar>(k, m);dst.at<uchar>(i, j) = maxt;}}}

低通滤波

void ideal_Low_Pass_Filter(Mat src){Mat img;cvtColor(src, img, CV_BGR2GRAY);imshow("img", img);//调整图像加速傅里叶变换int M = getOptimalDFTSize(img.rows);int N = getOptimalDFTSize(img.cols);Mat padded;copyMakeBorder(img, padded, 0, M - img.rows, 0, N - img.cols, BORDER_CONSTANT, Scalar::all(0));//记录傅里叶变换的实部和虚部Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };Mat complexImg;merge(planes, 2, complexImg);//进行傅里叶变换dft(complexImg, complexImg);//获取图像Mat mag = complexImg;mag = mag(Rect(0, 0, mag.cols & -2, mag.rows & -2));//这里为什么&上-2具体查看opencv文档//其实是为了把行和列变成偶数 -2的二进制是11111111.......10 最后一位是0//获取中心点坐标int cx = mag.cols / 2;int cy = mag.rows / 2;//调整频域Mat tmp;Mat q0(mag, Rect(0, 0, cx, cy));Mat q1(mag, Rect(cx, 0, cx, cy));Mat q2(mag, Rect(0, cy, cx, cy));Mat q3(mag, Rect(cx, cy, cx, cy));q0.copyTo(tmp);q3.copyTo(q0);tmp.copyTo(q3);q1.copyTo(tmp);q2.copyTo(q1);tmp.copyTo(q2);//Do为自己设定的阀值具体看公式double D0 = 60;//处理按公式保留中心部分for (int y = 0; y < mag.rows; y++){double* data = mag.ptr<double>(y);for (int x = 0; x < mag.cols; x++){double d = sqrt(pow((y - cy), 2) + pow((x - cx), 2));if (d <= D0){}else{data[x] = 0;}}}//再调整频域q0.copyTo(tmp);q3.copyTo(q0);tmp.copyTo(q3);q1.copyTo(tmp);q2.copyTo(q1);tmp.copyTo(q2);//逆变换Mat invDFT, invDFTcvt;idft(mag, invDFT, DFT_SCALE | DFT_REAL_OUTPUT); // Applying IDFTinvDFT.convertTo(invDFTcvt, CV_8U);imshow("理想低通滤波器", invDFTcvt);}
巴特沃斯滤波器
void Butterworth_Low_Paass_Filter(Mat src){int n = 1;//表示巴特沃斯滤波器的次数//H = 1 / (1+(D/D0)^2n)Mat img;cvtColor(src, img, CV_BGR2GRAY);imshow("img", img);//调整图像加速傅里叶变换int M = getOptimalDFTSize(img.rows);int N = getOptimalDFTSize(img.cols);Mat padded;copyMakeBorder(img, padded, 0, M - img.rows, 0, N - img.cols, BORDER_CONSTANT, Scalar::all(0));Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };Mat complexImg;merge(planes, 2, complexImg);dft(complexImg, complexImg);Mat mag = complexImg;mag = mag(Rect(0, 0, mag.cols & -2, mag.rows & -2));int cx = mag.cols / 2;int cy = mag.rows / 2;Mat tmp;Mat q0(mag, Rect(0, 0, cx, cy));Mat q1(mag, Rect(cx, 0, cx, cy));Mat q2(mag, Rect(0, cy, cx, cy));Mat q3(mag, Rect(cx, cy, cx, cy));q0.copyTo(tmp);q3.copyTo(q0);tmp.copyTo(q3);q1.copyTo(tmp);q2.copyTo(q1);tmp.copyTo(q2);double D0 = 100;for (int y = 0; y < mag.rows; y++){double* data = mag.ptr<double>(y);for (int x = 0; x < mag.cols; x++){//cout << data[x] << endl;double d = sqrt(pow((y - cy), 2) + pow((x - cx), 2));//cout << d << endl;double h = 1.0 / (1 + pow(d / D0, 2 * n));if (h <= 0.5){data[x] = 0;}else{//data[x] = data[x]*0.5;//cout << h << endl;}//cout << data[x] << endl;}}q0.copyTo(tmp);q3.copyTo(q0);tmp.copyTo(q3);q1.copyTo(tmp);q2.copyTo(q1);tmp.copyTo(q2);//逆变换Mat invDFT, invDFTcvt;idft(complexImg, invDFT, DFT_SCALE | DFT_REAL_OUTPUT); // Applying IDFTinvDFT.convertTo(invDFTcvt, CV_8U);imshow("巴特沃斯低通滤波器", invDFTcvt);}

Robinson_Guard滤波

void Robinson_Guard(Mat src, Mat dst, int kernalsize){vector<uchar> tempdata,borderdata;tempdata.clear();borderdata.clear();uchar centerpix;int ksize = 0;if (kernalsize % 2 == 0){ksize = kernalsize / 2;}else{ksize = (kernalsize - 1) / 2;}if (kernalsize>src.rows || kernalsize>src.cols)cout << "核输入过大" << endl;for (int i = ksize; i < src.rows - ksize; i++){uchar* data = src.ptr<uchar>(i);uchar* datadst = dst.ptr<uchar>(i);for (int j = ksize; j < src.cols - ksize; j++){centerpix = data[j];/*计算带状窗口内的像素*/tempdata.clear();for (int l = i - ksize + 1; l < i + ksize - 1;++l)for (int k = j - ksize + 1; k < j + ksize - 1; k++){tempdata.push_back(src.at<uchar>(l, k));   }sort(tempdata.begin(), tempdata.end());double min = 0, max = 0;min = tempdata[0];//带状窗口内的像素灰度最小值max = tempdata[tempdata.size()-1];//带状窗口内的像素灰度最大值/*计算边缘区域像素*/borderdata.clear();/*边缘区域分成四个区域计算*/for (int bl = i - ksize; bl < i + ksize; ++bl){borderdata.push_back(src.at<uchar>(bl, j - ksize));}for (int bl = i - ksize; bl < i + ksize; ++bl){borderdata.push_back(src.at<uchar>(bl, j + ksize));}for (int bk = j - ksize+1; bk < j + ksize-1; ++bk){borderdata.push_back(src.at<uchar>(i - ksize, bk));}for (int bk = j - ksize + 1; bk < j + ksize - 1; ++bk){borderdata.push_back(src.at<uchar>(i + ksize, bk));}sort(borderdata.begin(), borderdata.end());double border_min = 0, border_max = 0;border_min = borderdata[0];//边缘区域的像素灰度最小值border_max = borderdata[borderdata.size() - 1];//边缘区域的像素灰度最大值if (centerpix > max)//当目标值大于带状窗口内的像素灰度最大值,目标背景估计值为边缘像素灰度最大值{/*datadst[j] = centerpix - border_max;*/datadst[j] =  border_max;}else if (centerpix <= min){/*datadst[j] = border_min - centerpix;*/datadst[j] = border_min ;}else{/*datadst[j] = 0;*/datadst[j] = centerpix;}}}}



原创粉丝点击