2015-06-05
知识点:
(1)像素值的存储
(2)引用的参数传递方式
(3)单通道和三通道图像像素访问的区别
代码如下:
1 #include "highgui.h" 2 #include "cxcore.h" 3 #include "cv.h" 4 #include "cmath" 5 6 void salt(cv::Mat &, int ); 7 8 9 int main() 10 { 11 cv::Mat tp1 = cv::imread("1.bmp"); 12 salt (tp1, 3000); 13 cv::namedWindow("1"); 14 cv::imshow("1",tp1); 15 cv::waitKey(0); 16 return 0; 17 } 18 19 20 21 void salt(cv::Mat &tp, int n) 22 { 23 for (int k=0; k < n; k++) 24 { 25 int i = rand() % tp.cols; 26 int j = rand() % tp.rows; 27 28 if(tp.channels() == 1) 29 tp.at <uchar>(j,i) = 255;//单通道像素赋值 30 else if (tp.channels() == 3) 31 { 32 tp.at <cv::Vec3b>(j,i)[0] = 255;//多通道像素赋值 33 tp.at <cv::Vec3b>(j,i)[1] = 255; 34 tp.at <cv::Vec3b>(j,i)[2] = 255; 35 } 36 } 37 return; 38 }
效果图:
主要代码解析:
(1)tp.at<uchar>(j,i) = 255;
类cv::Mat 有若干成员函数可以获取图像的属性。公有成员的变量cols和rows给出了图像的宽和高。成员函数at(int y, int x)可以用来存取图像的元素。但是必须在编译期知道图像的数据类型,因为cv::Mat 可以存放任意数据类型的元素。这也是这个函数用模板函数来实现的原因。这也意味着,当调用该函数时,你必须以如<uchar>来指定数据类型。
注:一定要确保指定的数据类型要和矩阵中的数据类型相符合。at方法本身不会进行任何数据类型转换。
(2)tp.at <cv::Vec3b>(j,i)[channel] = 255;
对于彩色图像,每个像素由三个部分构成(r,g,b三通道)。因此,一个包含彩色图像的cv::Mat 会返回一个由三个8位数组成的向量。opencv将此类向量定义为cv::Vec3b,即由三个unsigned char 组成的向量。索引值channel标明了颜色通道号。
(3)void salt(cv::Mat &tp, int n)
第一个参数是一张输入图像,使用传引用的参数传递方式,可以在原图像上直接做修改,不用再新建一张空白图像。
椒盐噪声可以模仿雨雪天气,具体效果可以调节n(噪声点的个数)的大小。
时间: 2024-11-06 03:48:08