前言
在上一章中描述了如何使用自己实现掩膜运算以及调用cv :: filter2D函数对图像进行掩膜运算矩阵的掩膜运算
目标
本章中,将学习如何:
- 读写像素
- 修改像素值
- 计算反差图像
读写像素
- 在OpenCV中图像存储基本为Mat格式,如果我们想要获取GRAY图的像素点灰度值,可以通过img.at
(i,j)的方式轻松获取:
Scalar gray = img.at(i,j) 或者 Scalar intensity = img.at(Point(j,i))
- 其中有一个要注意的地方是i对应的是点y的坐标,j对应的是点的x坐标,所以建议在访问时都用img.at
(Point(j,i))这种形式访问,免去了点坐标和行列的转换。对于获取RGB图像的像素点的像素值则可以使用如下方法,来分别获取B、G、R三个通道的对应的值:
Vec3f rgb = img.at(i,j) 或者 Vec3f rgb = img.at(Point(j,i))
float blue = bgr.val[0];
float green = bgr.val[1];
float red = bgr.val[2];
修改像素值
- 修改灰度图像
img.at(Point(j,i)) = 128;
- 修改RGB三通道图像
img.at(Point(j,i)) [0] = 128; //blue
img.at(Point(j,i)) [1] = 128; //green
img.at(Point(j,i)) [2] = 128; //red
- 空白图像赋值
img = Scalar(0)
- ROI选择
Rect r(10,10,100,100);
Mat roiImg = img(r);
源代码
#include
#include
#include
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
Mat grayImage;
src = imread("../data/HappyFish.jpg", IMREAD_UNCHANGED);
if (src.empty())
{
printf("Could not find the image!\n");
return -1;
}
namedWindow("input", WINDOW_NORMAL);
imshow("input", src);
cvtColor(src, grayImage, COLOR_BGR2GRAY);
namedWindow("gray", WINDOW_NORMAL);
imshow("gray", grayImage);
int rows = grayImage.rows;
int cols = grayImage.cols;
dst = Mat(grayImage.size(), grayImage.type()); // 示例对象
// 反差图像
dst.create(src.size(), src.type());
int rows = src.rows;
int cols = src.cols;
int chls = src.channels();
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
if (chls == 1)
{
int gray = grayImage.at(row, col);
dst.at(row, col) = 255 - gray;
}
else if (chls == 3)
{
int b = src.at(row, col)[0];
int g = src.at(row, col)[1];
int r = src.at(row, col)[2];
dst.at(row, col)[0] = 255 - b;
dst.at(row, col)[1] = 255 - g;
dst.at(row, col)[2] = 255 - r;
}
}
}
// 按位取反,和上述功能一致
bitwise_not(src, dst);
namedWindow("output", WINDOW_NORMAL);
imshow("output", dst);
waitKey(0); // Wait for a keystroke in the window
return 0;
}
说明
- Vec3b与Vec3f
- Vec3b对应图像的三通道顺序是B、G、R的uchar类型数据。
- Vec3f对应图像的三通道为Float类型的数据
- 通过src.convertTo(dst,CV_32F)可以把CV_8UC1转到CV32F1类型