椒盐噪声
椒盐噪声就是给图片添加黑白噪点,椒指的是黑色的噪点(0,0,0),盐指的是白色的噪点(255,255,255),通过num来控制噪声多少,值越大添加的噪声越多,图像损坏的更加严重。
void add_salt_pepper_noise(Mat& src,Mat& dst,int num)
{dst = src.clone();unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();std::default_random_engine generator (seed);std::uniform_int_distribution<int> distribute_x(0, src.cols - 1);//包含maxstd::uniform_int_distribution<int> distribute_y(0, src.rows - 1);//包含max//blackfor(int i = 0;i < num;i ++){int x = distribute_x(generator);int y = distribute_y(generator);dst.at<Vec3b>(y,x) = Vec3b(0,0,0);}//whitefor(int i = 0;i < num;i ++){int x = distribute_x(generator);int y = distribute_y(generator);dst.at<Vec3b>(y,x) = Vec3b(255,255,255);}
}
下图是设置num=1000时产生的噪声图像:
高斯噪声
高斯噪声就是给图片添加一个服从高斯分布的噪声,可以通过调节高斯分布标准差sigma的大小来控制添加噪声程度,sigma
越大添加的噪声越多图片损坏的越厉害.
void add_gassion_noise(Mat& src,Mat& dst,int mean,int sigma)
{dst = src.clone();Mat _gassion = Mat::zeros(src.rows,src.cols,CV_8UC3);cv::RNG rng;rng.fill(_gassion, RNG::NORMAL, mean, sigma);dst = dst + _gassion;
}
下图是mean=50,sigma=50时产生的噪声图像:
随机形状斑点噪声
随机斑点噪声是通过生成随机的多变形来实现的。
注意以下代码中image是QImage,num表示产生20个斑点。
Mat _msk = Mat::zeros(image->height(),image->width(),CV_8UC1);num = 20;Mat kernal = Mat::ones(3,3,CV_8UC1);kernal.at<uchar>(0,0) = 0;kernal.at<uchar>(0,2) = 0;kernal.at<uchar>(2,0) = 0;kernal.at<uchar>(2,2) = 0;for(int i = 0;i < num;i ++){quint32 value = QRandomGenerator::global()->generate();int cx = value % (this->width() / 2 - 1);value = QRandomGenerator::global()->generate();int cy = value % (this->height() - 1);std::vector<Point> _polygon;int _line_num = 20,_min_radius = 2,_max_radius = 7;double _angle_step = 2 * 3.1415926 / _line_num;Point center(cx,cy);for (int i = 0;i < _line_num;i ++){quint32 value = QRandomGenerator::global()->generate();double k = value % 100 / 100.0;double _angle = _angle_step * i;_angle = _angle + (k - 0.5) * _angle_step * 0.25;value = QRandomGenerator::global()->generate();k = value % 100 / 100.0;double radius = _min_radius + k * (_max_radius - _min_radius);int x = radius * cos(_angle);int y = radius * sin(_angle);_polygon.push_back(Point(center.x + x,center.y + y));}value = QRandomGenerator::global()->generate();int c = value % 255;cv::fillPoly(_msk,_polygon,Scalar(c));//cv::morphologyEx(_msk,_msk,MORPH_DILATE,kernal,Point(-1,-1),1);}cv::GaussianBlur(_msk,_msk,Size(5,5),0);for (int h = 0;h < _msk.rows;h ++){uchar *d1 = image->scanLine(h);uchar *d2 = _msk.ptr<uchar>(h);for (int w = 0;w < _msk.cols;w ++){int w4 = 4*w;double v = d1[w4 + 0] * (1 - d2[w] / 255.0);if (v > 255)v = 255;if (v < 0)v = 0;d1[w4 + 0] = v;v = d1[w4 + 1] * (1 - d2[w] / 255.0);if (v > 255)v = 255;if (v < 0)v = 0;d1[w4 + 1] = v;v = d1[w4 + 2] * (1 - d2[w] / 255.0);if (v > 255)v = 255;if (v < 0)v = 0;d1[w4 + 2] = v;}}
以上代码只产生黑色斑点, 白色斑点只要将合并方式改成加即可:double v = d1[w4 + 0] * (1 + d2[w] / 255.0);