发现Mat类中的at方法对于获取图像矩阵某点的RGB值或者改变某点的值很方便,对于单通道的图像,则可以使用:
来获取或改变该点的值,而RGB通道的则可以使用:
- image.at<Vec3b>(i, j)[0]
- image.at<Vec3b>(i, j)[1]
- image.at<Vec3b>(i, j)[2]
来分别获取B、G、R三个通道的对应的值。下边的代码实现对图像加椒盐噪声:
- #include<opencv2\opencv.hpp>
- using namespace cv;
- using namespace std;
-
- void salt_noise(Mat image, int time)
- {
- for (int k = 0; k < time; k++)
- {
- int i = rand() % image.rows;
- int j = rand() % image.cols;
- if (image.channels() == 1)
- {
- image.at<uchar>(i, j) = rand() % 255;
- }
- else if (image.channels() == 3)
- {
- image.at<Vec3b>(i, j)[0] = rand() % 255;
- image.at<Vec3b>(i, j)[1] = rand() % 255;
- image.at<Vec3b>(i, j)[2] = rand() % 255;
- }
- }
- }
-
- int main(void)
- {
- Mat image = imread("..\\lena.bmp", 0);
- if (image.empty())
- {
- cout << "load image error" << endl;
- return -1;
- }
- salt_noise(image, 3000);
- namedWindow("image", 1);
- imshow("image", image);
-
- waitKey();
- return 0;
- }
不过貌似用at取值或改变值来做比较耗时,当然我们还可以使用Mat的模板子类Mat_<T>,,对于单通道的具体使用:
- Mat_<uchar> img = image;
- img(i, j) = rand() % 255;
对于RGB通道的使用:
- Mat_<Vec3b> img = image;
- img(i, j)[0] = rand() % 255;
- img(i, j)[1] = rand() % 255;
- mg(i, j)[2] = rand() % 255;
还可以用指针的方法遍历每一像素:(耗时较小)
- void colorReduce(Mat image, int div = 64)
- {
- int nrow = image.rows;
- int ncol = image.cols*image.channels();
- for (int i = 0; i < nrow; i++)
- {
- uchar* data = image.ptr<uchar>(i);
- for (int j = 0; j < ncol; j++)
- {
- data[i] = (data[i] / div)*div ;
- }
- }
- }