c语言和opencv实现图像均值滤波和中值滤波

心已赠人 2021-11-01 02:56 731阅读 0赞

1,c语言实现中值滤波以及算法实现描述

我们在一个矩阵中去除边缘,在剩余数中求取所有像素点的均值来取代中间的值,我们来举例说明:

公式:meanvalue = \\sum \_\{i=0,j=0\}^\{i=2,j=2\}a\[i\]\[j\] a[i][j]是下面数据除去边缘值的平均值。







































1 2 3 3 1

3

10 23 54 3
2 23 45 14 2
1 21 32 28 1
3 4 4 2 3






































1 2 3 3 1
3 27.8 27.8 27.8 3
2 27.8 27.8 27.8 2
1 27.8 27.8 27.8 1
3 4 4 2 3

图像的椒盐化补充:

椒盐噪声是由图像传感器,传输信道,解码处理等产生的黑白相间的亮暗点噪声。椒盐噪声是指两种噪声,一种是盐噪声(salt noise)盐=白色(255),另一种是胡椒噪声(pepper noise),椒=黑色(0)。

c语言代码实现:

  1. #include "opencv2/imgproc.hpp"
  2. #include "opencv2/highgui.hpp"
  3. #include<ctime>
  4. using namespace cv;
  5. using namespace std;
  6. //均值滤波
  7. void AverFiltering(const Mat &src,Mat &dst) {
  8. if (!src.data) return;
  9. //at访问像素点
  10. for (int i = 1; i<src.rows; ++i)
  11. for (int j = 1; j < src.cols; ++j) {
  12. if ((i - 1 >= 0) && (j - 1) >= 0 && (i + 1)<src.rows && (j + 1)<src.cols) {//边缘不进行处理
  13. dst.at<Vec3b>(i, j)[0] = (src.at<Vec3b>(i, j)[0] + src.at<Vec3b>(i - 1, j - 1)[0] + src.at<Vec3b>(i - 1, j)[0] + src.at<Vec3b>(i, j - 1)[0] +
  14. src.at<Vec3b>(i - 1, j + 1)[0] + src.at<Vec3b>(i + 1, j - 1)[0] + src.at<Vec3b>(i + 1, j + 1)[0] + src.at<Vec3b>(i, j + 1)[0] +
  15. src.at<Vec3b>(i + 1, j)[0]) / 9;
  16. dst.at<Vec3b>(i, j)[1] = (src.at<Vec3b>(i, j)[1] + src.at<Vec3b>(i - 1, j - 1)[1] + src.at<Vec3b>(i - 1, j)[1] + src.at<Vec3b>(i, j - 1)[1] +
  17. src.at<Vec3b>(i - 1, j + 1)[1] + src.at<Vec3b>(i + 1, j - 1)[1] + src.at<Vec3b>(i + 1, j + 1)[1] + src.at<Vec3b>(i, j + 1)[1] +
  18. src.at<Vec3b>(i + 1, j)[1]) / 9;
  19. dst.at<Vec3b>(i, j)[2] = (src.at<Vec3b>(i, j)[2] + src.at<Vec3b>(i - 1, j - 1)[2] + src.at<Vec3b>(i - 1, j)[2] + src.at<Vec3b>(i, j - 1)[2] +
  20. src.at<Vec3b>(i - 1, j + 1)[2] + src.at<Vec3b>(i + 1, j - 1)[2] + src.at<Vec3b>(i + 1, j + 1)[2] + src.at<Vec3b>(i, j + 1)[2] +
  21. src.at<Vec3b>(i + 1, j)[2]) / 9;
  22. }
  23. else {//边缘赋值
  24. dst.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0];
  25. dst.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1];
  26. dst.at<Vec3b>(i, j)[2] = src.at<Vec3b>(i, j)[2];
  27. }
  28. }
  29. }
  30. //图像椒盐化
  31. void salt(Mat &image, int num) {
  32. if (!image.data) return;//防止传入空图
  33. int i, j;
  34. srand(time(NULL));
  35. for (int x = 0; x < num; ++x) {
  36. i = rand() % image.rows;
  37. j = rand() % image.cols;
  38. image.at<Vec3b>(i, j)[0] = 255;
  39. image.at<Vec3b>(i, j)[1] = 255;
  40. image.at<Vec3b>(i, j)[2] = 255;
  41. }
  42. }
  43. void main()
  44. {
  45. Mat image = imread("路飞.jpg");
  46. Mat Salt_Image;
  47. image.copyTo(Salt_Image);
  48. salt(Salt_Image, 3000);
  49. Mat image1(image.size(), image.type());
  50. Mat image2;
  51. AverFiltering(Salt_Image, image1);
  52. imshow("原图", image);
  53. imshow("自定义均值滤波", image1);
  54. waitKey();
  55. }

运行结果如下: g++ 2_opencv.cpp `pkg-config opencv —cflags` `pkg-config opencv —libs`

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMDA4MzI1_size_16_color_FFFFFF_t_70

opencv实现均值滤波:

  1. import cv2
  2. import numpy as np
  3. img = cv2.imread('image11.jpg',1)
  4. cv2.imshow('src',img)
  5. dst = cv2.GaussianBlur(img,(5,5),1.5)
  6. cv2.imshow('dst',dst)
  7. cv2.waitKey(0)

运行结果如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMDA4MzI1_size_16_color_FFFFFF_t_70 1

2,c语言以及opencv实现中值滤波:







































1 2 3 3 1  

3

10 23 54 3
2 23 45 14 2
1 21 32 28 1
3 4 4 2 3






































1 2 3 3 1

3

10 23 54 3
2 23 23 14 2
1 21 32 28 1
3 4 4 2 3


对中间的9个数据10,23,54,23,45,14,21,32,28进行排序,所以排序后的数据如下:

10,14,21,23,23,28,32,45,45 所以我们看到中值是23,我们只需要替换掉中间

值,将45替换为23即可。

c语言代码实现中值滤波:

  1. #include "opencv2/imgproc.hpp"
  2. #include "opencv2/highgui.hpp"
  3. #include<ctime>
  4. using namespace cv;
  5. using namespace std;
  6. typedef unsigned char uchar;
  7. void swap(uchar* p1,uchar* p2)
  8. {
  9. uchar* temp = p1;
  10. p1 = p2;
  11. p2 = temp ;
  12. }
  13. //求九个数的中值
  14. uchar Median(uchar n1, uchar n2, uchar n3, uchar n4, uchar n5,
  15. uchar n6, uchar n7, uchar n8, uchar n9) {
  16. uchar arr[9];
  17. arr[0] = n1;
  18. arr[1] = n2;
  19. arr[2] = n3;
  20. arr[3] = n4;
  21. arr[4] = n5;
  22. arr[5] = n6;
  23. arr[6] = n7;
  24. arr[7] = n8;
  25. arr[8] = n9;
  26. for (int gap = 9 / 2; gap > 0; gap /= 2)//希尔排序
  27. for (int i = gap; i < 9; ++i)
  28. for (int j = i - gap; j >= 0 && arr[j] > arr[j + gap]; j -= gap)
  29. swap(&arr[j], &arr[j + gap]);
  30. return arr[4];//返回中值
  31. }
  32. //图像椒盐化
  33. void salt(Mat &image, int num) {
  34. if (!image.data) return;//防止传入空图
  35. int i, j;
  36. srand(time(NULL));
  37. for (int x = 0; x < num; ++x) {
  38. i = rand() % image.rows;
  39. j = rand() % image.cols;
  40. image.at<Vec3b>(i, j)[0] = 255;
  41. image.at<Vec3b>(i, j)[1] = 255;
  42. image.at<Vec3b>(i, j)[2] = 255;
  43. }
  44. }
  45. //中值滤波函数
  46. void MedianFlitering(const Mat &src, Mat &dst) {
  47. if (!src.data)return;
  48. Mat _dst(src.size(), src.type());
  49. for(int i=0;i<src.rows;++i)
  50. for (int j=0; j < src.cols; ++j) {
  51. if ((i - 1) > 0 && (i + 1) < src.rows && (j - 1) > 0 && (j + 1) < src.cols) {
  52. _dst.at<Vec3b>(i, j)[0] = Median(src.at<Vec3b>(i, j)[0], src.at<Vec3b>(i + 1, j + 1)[0],
  53. src.at<Vec3b>(i + 1, j)[0], src.at<Vec3b>(i, j + 1)[0], src.at<Vec3b>(i + 1, j - 1)[0],
  54. src.at<Vec3b>(i - 1, j + 1)[0], src.at<Vec3b>(i - 1, j)[0], src.at<Vec3b>(i, j - 1)[0],
  55. src.at<Vec3b>(i - 1, j - 1)[0]);
  56. _dst.at<Vec3b>(i, j)[1] = Median(src.at<Vec3b>(i, j)[1], src.at<Vec3b>(i + 1, j + 1)[1],
  57. src.at<Vec3b>(i + 1, j)[1], src.at<Vec3b>(i, j + 1)[1], src.at<Vec3b>(i + 1, j - 1)[1],
  58. src.at<Vec3b>(i - 1, j + 1)[1], src.at<Vec3b>(i - 1, j)[1], src.at<Vec3b>(i, j - 1)[1],
  59. src.at<Vec3b>(i - 1, j - 1)[1]);
  60. _dst.at<Vec3b>(i, j)[2] = Median(src.at<Vec3b>(i, j)[2], src.at<Vec3b>(i + 1, j + 1)[2],
  61. src.at<Vec3b>(i + 1, j)[2], src.at<Vec3b>(i, j + 1)[2], src.at<Vec3b>(i + 1, j - 1)[2],
  62. src.at<Vec3b>(i - 1, j + 1)[2], src.at<Vec3b>(i - 1, j)[2], src.at<Vec3b>(i, j - 1)[2],
  63. src.at<Vec3b>(i - 1, j - 1)[2]);
  64. }
  65. else
  66. _dst.at<Vec3b>(i, j) = src.at<Vec3b>(i, j);
  67. }
  68. _dst.copyTo(dst);//拷贝
  69. }
  70. int main() {
  71. Mat image = imread("1.JPG");
  72. Mat Salt_Image;
  73. image.copyTo(Salt_Image);
  74. salt(Salt_Image, 3000);
  75. Mat image3, image4;
  76. MedianFlitering(Salt_Image, image3);
  77. medianBlur(Salt_Image, image4, 3);
  78. imshow("自定义中值滤波处理后", image3);
  79. imshow("openCV自带的中值滤波", image4);
  80. waitKey();
  81. }

代码实现效果如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMDA4MzI1_size_16_color_FFFFFF_t_70 2

发表评论

表情:
评论列表 (有 0 条评论,731人围观)

还没有评论,来说两句吧...

相关阅读