1 图像遍历与修改
C++中支持 数组遍历 和 指针方式遍历
1.1 使用数组
访问使用 image.at(row,col) 进行访问
如果是单通道灰度图,就使用image.at进行读取
如果是三通道彩色图,就使用Image.at进行读取单个像素,通过 Image.at [0], Image.at[1], Image.at[2]读取每个通道的数据
void QuickDemo::pixel_visit_demo(Mat &image)
{
int w = image.cols;
int h = image.rows;
int dimis = image.channels();
for (int row = 0; row < h; row++)
{
for (int col = 0; col < w; col++)
{
if (dimis == 1)
{
// 灰色图像 打印像素 几行几列的那个像素点
int pv = image.at<uchar>(row, col);
// 修改像素点
image.at<uchar>(row, col) = 255 - pv;
}
if (dimis == 3)
{
// 彩色图像 专门获取三通道的存储
Vec3b bgr = image.at<Vec3b>(row, col);
image.at<Vec3b>(row, col)[0] = 255 - bgr[0];
image.at<Vec3b>(row, col)[1] = 255 - bgr[1];
image.at<Vec3b>(row, col)[2] = 255 - bgr[2];
}
}
}
imshow("像素读写演示", image);
}
这边就是对三通道进行一个取反
1.2 使用指针
使用image.ptr 进行遍历
for (int row = 0; row < h; row++)
{
uchar* current_row = image.ptr<uchar>(row);
for (int col = 0; col < w; col++)
{
if (dimis == 1)
{
// 灰色图像 打印像素 几行几列的那个像素点
int pv = *current_row;
// 修改像素点
*current_row++ = 255 - pv;
}
if (dimis == 3)
{
// 彩色图像 专门获取三通道的存储
*current_row++ = 255 - *current_row;
*current_row++ = 255 - *current_row;
*current_row++ = 255 - *current_row;
}
}
}
2 图像的算术运算
2.1 一般算术操作
Mat dst;
dst = image + Scalar(50, 50, 50);
imshow("加法测试");
同样可以使用减法,除法
Mat dst;
dst = image - Scalar(50, 50, 50);
dst = image / Scalar(2, 2, 2);
imshow("加法测试");
进行乘法时会报错,这时候需要特殊操作
使用multiply 进行乘法操作
Mat dst;
//dst = image + Scalar(50, 50, 50);
Mat m = Mat::zeros(image.size(), image.type());
multiply(image, m, dst);
imshow("加法测试");
会进行截断操作,超过255会变成255
为避免加法也会出现超过255的操作,使用C++的数据类型转换,
saturate_cast(a,b);
Mat dst = Mat::zeros(image.size(), image.type());
//dst = image + Scalar(50, 50, 50);
Mat m = Mat::zeros(image.size(), image.type());
/*multiply(image, m, dst);
imshow("加法测试");*/
m = Scalar(50, 50, 50);
int w = image.cols;
int h = image.rows;
int dimis = image.channels();
for (int row = 0; row < h; row++)
{
for (int col = 0; col < w; col++)
{
if (dimis == 1)
{
// 灰色图像 打印像素 几行几列的那个像素点
int pv = image.at<uchar>(row, col);
// 修改像素点
image.at<uchar>(row, col) = 255 - pv;
}
if (dimis == 3)
{
// 彩色图像 专门获取三通道的存储
Vec3b p1 = image.at<Vec3b>(row, col);
Vec3b p2 = m.at<Vec3b>(row, col);
image.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(p1[0] + p2[0]);
image.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(p1[1] + p2[1]);
image.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(p1[2] + p2[2]);
}
}
}
2.2 算术API
上节已经有乘法的API
multiply(第一个mat,第二个mat, 输出结果);
加法
add(image, m, dst);
减法
subtract(image , m, dst)
除法
divide(image, m, dst)
multiply(image, m, dst);
add(image, m, dst);
subtract(image, m, dst);
divide(image, m, dst);