一、椒盐噪声
void salt(Mat& img, int num) { if (img.data == NULL) return; srand(time(NULL)); int i, j; for (int k = 0; k < num; k++) { i = rand() % img.rows; j = rand() % img.cols; img.at<Vec3b>(i, j)[0] = 255; img.at<Vec3b>(i, j)[1] = 255; img.at<Vec3b>(i, j)[2] = 255; } }
二、排序
中值滤波原理,用核函数依次扫描每个像素,将核函数覆盖的图像区域像素排序,取出中值。
三、滤波实现
Mat median_filter(Mat& noise_img) { int height = noise_img.rows; int width = noise_img.cols; int channel = noise_img.channels(); // prepare output Mat out = Mat::zeros(height, width, noise_img.type()); int pad = floor(kernel_size / 2); uchar kernel_value[kernel_size * kernel_size] = {0}; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { for (int c = 0; c < channel; c++) { int count = 0; // get neighbor pixels for (int dy = -pad; dy < pad + 1; dy++) { for (int dx = -pad; dx < pad + 1; dx++) { if (((y - pad) > 0) && ((x - pad) > 0)&& ((y + pad) < height) && ((x + pad) < width)) { //边界像素pad/2不管,保持原样 kernel_value[count++] = (uchar)noise_img.at<Vec3b>(y+dy, x+dx)[c]; } else { //kernel_value[count++] = 0; kernel_value[count++] = (uchar)noise_img.at<Vec3b>(y , x )[c];; } } } sort(kernel_value, kernel_value + count); out.at<Vec3b>(y, x)[c] = (uchar)kernel_value[(int)floor(count / 2) + 1]; } } } return out; }