作业好多TAT
有不懂的可以私信我,现在是没时间详细解释代码了
里面也有opencv的高斯/中值去噪,c++和opencv的都写了
封面就是我处理的那张图片
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <string>
#define PI 3.141592654
using namespace cv;
using namespace std;
void addingGaussianNoise(Mat img) {
RNG rng;
Mat noise = Mat::zeros(img.rows, img.cols, img.type());
rng.fill(noise, RNG::NORMAL, 10, 20);
img = img + noise;
return;
}
void addingSaltAndPepperNoise(Mat img) {
int cols = img.cols;
int rows = img.rows;
for (int i = 0; i < cols; i++) {
for (int j = 0; j < rows; j++) {
if (rand() / double(RAND_MAX + 1.0) > 0.95) { // 每个像素有0.05的几率变成噪点
if (rand() / double(RAND_MAX + 1.0) > 0.5) { // 随机产生黑白噪点,使用at指针访问图像像素
img.at<Vec3b>(j, i)[0] = 0;
img.at<Vec3b>(j, i)[1] = 0;
img.at<Vec3b>(j, i)[2] = 0;
}
else {
img.at<Vec3b>(j, i)[0] = 255;
img.at<Vec3b>(j, i)[1] = 255;
img.at<Vec3b>(j, i)[2] = 255;
}
}
}
}
return;
}
void myGaussianBlur(Mat img_gaus, Mat img_blur, int core, double sigma = 0) {
if (sigma <= 0) {
sigma = ((core - 1) * 0.5 - 1.0) * 0.3 + 0.8;//若未指定sigma则自行计算
}
vector<vector<float>> conv_core(core, vector<float>(core)); //声明一个二维数组
int center = core / 2;
for (int i = 0; i < core; i++)//产生高斯卷积核
{
for (int j = 0; j < core; j++)
{
conv_core[i][j] = exp(-((i - center) * (i - center) + (j - center) * (j - center)) / (2 * sigma * sigma)) / (2 * PI * sigma * sigma);
}
}
uchar* pixel_list = img_gaus.data;//原图像像素值列表(三通道),也可以设成二维数组,但是要分离RGB比较繁琐。
int count = 0;
int cols = img_gaus.cols;
int rows = img_gaus.rows;
int channels = img_gaus.channels();
Mat pixel_expand;
pixel_expand.create(Size(cols + 2 * center, rows + 2 * center), img_gaus.type());
uchar* pixel_expand_list = pixel_expand.data;//扩张后图像像素列表(三通道),使用data指针访问图像元素,因为要遍历的次数过多,多次使用at指针略为缓慢
for (int i = 0; i < rows + 2 * center; i++) {//填入扩充后图像
for (int j = 0; j < cols + 2 * center; j++) {
if (i >= center && i < rows + center && j >= center && j < cols + center) {
for (int ch = 0; ch < channels; ch++) {
pixel_expand_list[(i * (cols + 2 * center) + j) * channels + ch] = pixel_list[((i - center) * cols + j - center) * channels + ch];
}
}
else {
int m = i < center ? i + center : (i >= rows + center ? i - center : i);
int n = j < center ? j + center : (j >= rows + center ? j - center : j);
for (int ch = 0; ch < channels; ch++) {
pixel_expand_list[(i * (rows + 2 * center) + j) * channels + ch] = pixel_list[((pixel_expand.rows - m) * rows + (pixel_expand.cols - n)) * channels + ch];
}
}
}
}
/*
//检查扩充后图像是否正确
imshow("test", pixel_expand);
waitKey(0);
*/
uchar* pixel_blur_list = img_blur.data;
for (int i = 0; i < rows; i++) {//卷积
for (int j = 0; j < cols; j++) {
for (int ch = 0; ch < channels; ch++) {
double conv = 0;//存放单步卷积结果
for (int x = 0; x < core; x++) {
for (int y = 0; y < core; y++) {
conv += saturate_cast<uchar>(conv_core[x][y] * pixel_expand_list[((i + x) * (cols + 2 * center) + j + y) * channels + ch]);
}
}
pixel_blur_list[(i * cols + j) * channels + ch] = conv;
}
}
}
return;
}
void bubbleSort(int* list, int len){//冒泡排序
int temp;
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - i - 1; j++)
{
if (list[j + 1] < list[j])
{
temp = list[j];
list[j] = list[j + 1];
list[j + 1] = temp;
}
}
}
}
void myMedianBlur(Mat& img_salt, Mat& img_blur, int core) {
img_blur.create(Size(img_salt.cols - core + 1, img_salt.rows - core + 1), img_salt.type());//用于放置滤波后像素
uchar* img_p = img_salt.data;
uchar* img_blur_p = img_blur.data;
int cols = img_salt.cols;
int rows = img_salt.rows;
int channels = img_salt.channels();
int* p = new int[core * core];//由于core为变量,所以只能建立动态数组
int median;
for (int ch = 0; ch < channels; ch++) {
for (int x = 0; x < rows - core + 1; x++) {
for (int y = 0; y < cols - core + 1; y++) {
for (int i = 0; i < core; i++) {
for (int j = 0; j < core; j++) {
p[i * core + j] = img_p[((x + i) * cols + (y + j)) * channels + ch];
}
}
bubbleSort(p, core * core);
if (core % 2 == 0) {
median = (p[core * core / 2] + p[core * core / 2 - 1]) / 2;
}
else{
median = p[core * core / 2];
}
img_blur_p[(x * (cols - core + 1) + y) * channels + ch] = median;
}
}
}
delete [] p;
return;
}
int main() {
String str = "C:\\Users\\33507\\Desktop\\sun.jpg";
Mat image = imread(str);
Mat image_gaus = image.clone();
Mat image_gaus_blur = image.clone();
Mat image_salt = image.clone();
Mat image_salt_blur = image.clone();
Mat my_image_gaus_blur = image.clone();
Mat my_image_salt_blur;
addingGaussianNoise(image_gaus);
addingSaltAndPepperNoise(image_salt);
GaussianBlur(image_gaus, image_gaus_blur, Size(5, 5), 0, 0);
medianBlur(image_salt, image_salt_blur, 3);
myGaussianBlur(image_gaus, my_image_gaus_blur, 5);
myMedianBlur(image_salt, my_image_salt_blur, 5);
imshow("origin image", image);
imshow("image of gaus", image_gaus);
imshow("image of salt", image_salt);
imshow("image after gausblur", image_gaus_blur);
imshow("image after saltblur", image_salt_blur);
imshow("image after my gausblur", my_image_gaus_blur);
imshow("image after my saltblur", my_image_salt_blur);
waitKey(0);
return 0;
}