目录
1.图像指针像素的获取
Mat.ptr<uchar>(int i=0)获取像素矩阵的指针,其中指针的类型是 Mat.ptr<uchar>,索引i表示第几行,从0开始计数。
获取当前行指针const uchar * current=myimage.ptr<uchar>(row);
获取当前像素点的像素值P(row,col)的像素值,p(row,col)=current[col];
2.像素范围的处理
saturate_cast<uchar>(-100),返回的像素是0;
saturate_cast<uchar>(288),返回的像素是255;
saturate_cast<uchar>(100),返回的像素是100;
这个函数的主要作用就是确保RGB值的范围在0-255之间。
3.图像的掩膜操作
掩膜操作是实现图像的对比度调整。
3.1掩膜操作的概念
用选定的图像,图形或物体,对处理的图像(全部或局部)进行遮挡,来控制图像处理的区域或处理过程。用于覆盖的特定图像或物体称为掩模或模板。光学图像处理中,掩模可以足胶片,滤光片等。掩模是由0和1组成的一个二进制图像。当在某一功能中应用掩模时,1值区域被处理,被屏蔽的0值区域不被包括在计算中。通过指定的数据值,数据范围,有限或无限值,感兴趣区和注释文件来定义图像掩模,也可以应用上述选项的任意组合作为输入来建立掩模。
3.2掩模的作用
数字图像处理中,掩模为二维矩阵数组,有时也用多值图像数字图像处理中,图像掩模主要用于:
- 提取感兴趣区,用预先制作的感兴趣区掩模与待处理图像相乘,得到感兴趣区图像,感兴趣区内图像值保持不变,而区外图像值都为0。
- 屏蔽作用,用掩模对图像上某些区域作屏蔽,使其不参加处理或不参加处理参数的计算,或仅对屏蔽区作处理或统计。
- 结构特征提取,用相似性变量或图像匹配方法检测和提取图像中与掩模相似的结构特征。
- 特殊形状图像的制作
- 掩膜是一种图像滤镜的模板,实用掩膜经常处理的是遥感图像。当提取道路或者河流,或者房屋时,通过一个N * N的矩阵来对图像进行像素过滤,然后将我们需要的地物或者标志突出显示出来。这个矩阵就是一种掩膜。
-
在OpenCV的中,掩模操作是相对简单的。大致的意思是,通过一个掩模矩阵,重新计算图像中的每一个像素值。掩模矩阵控制了旧图像当前位置以及周围位置像素对新图像当前位置像素值的影响力度。用数学术语讲,即我们自定义一个权重表
3.3掩模操作实现图像对比度改变
void QuickDemo::pic_masking1_demo(Mat& image) {
int cols = (image.cols - 1)* image.channels();//获取图像的宽;
int offsetx = image.channels();
int rows = image.rows;
Mat dst = Mat::zeros(image.size(), image.type());
for (int row = 1; row < rows - 1; row++) {//是从(1,1)位置开始的,而不是从0位置开始的
const uchar* current = image.ptr<uchar>(row);
const uchar* previous = image.ptr<uchar>(row-1);
const uchar* nest = image.ptr<uchar>(row+1);
uchar* output = dst.ptr<uchar>(row);
for (int col = offsetx; col < cols; col++) {
output[col] = saturate_cast<uchar>(5 * current[col] - (current[col - offsetx] + current[col + offsetx] + nest[col]));
}
}
imshow("contrast_image", dst);
}
方式2 直接调用包:
void QuickDemo::pic_masking_way2_demo(Mat& image) {
Mat dst;
Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(image, dst, image.depth(), kernel);
imshow("contrast_image",dst);
}
4.Mat对象
4.1概述
opencv中以Mat对象表示图像的数据结构
-------lpllmage是从2001年opencv发布之后就一直存在,是c语言表示的数据结构,需要开发者自己分配和管理内存,对大型程序使用它容易导致内存泄漏问题。
-------Mat对象是opencv2.0之后引进的图像数据结构,自动分配内存,不存在内存泄漏问题,是面向对象的数据结构,分为两部分:头部和数据部分。
4.2Mat对象使用要点
-----输出图像的内存是自动分配的
-----使用opencv的c++接口不用考虑内存分配问题
-----赋值操作和拷贝构造函数只会复制头部分,不会赋值图像的数据部分
-----使用clone和copyTo两个函数实现图像数据的完全拷贝
5.图像的操作
5.1像素的获取与像素的修改
void QuickDemo::read_write_piexl_demo(Mat& image) {
Mat gray_image;
cvtColor(image, gray_image, COLOR_BGR2GRAY);
imshow("gray_image", gray_image);
int height = gray_image.rows;
int width = gray_image.cols;
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
int gray = gray_image.at<uchar>(row, col);//获取每行每列的像素值
//我们可以改变像素显示反差之后的图像
gray_image.at<uchar>(row, col) = 255 - gray;
}
}
imshow("反差图像", gray_image);
}
经过像素的修改反差图像的结果如下所示:
6.图像线性混合
g(x) = (1-α)f0(x)+αf1(x) α的取值范围位0-1之间 f0(x)为图像1,f1(x)表示第二张图像 α是混合系数 g(x)是生成的图像,对每一个像素进行这个线性公式的操作.相关的API如下所示:
CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2,
double beta, double gamma, OutputArray dst, int dtype = -1);
参数介绍:
参数1:输入图像Mat-src1
参数2:输入图像的src1的alpha值
参数3:输入图像Mat-src2
参数4:输入图像src2的alpha值
参数5:gamma值
参数6:输出混合图像Mat
注意事项:两张图像的大小和类型必须一致才可以进行混合
void QuickDemo::image_blending_demo() {
Mat image1, image2, dst;
image1 = imread("D:\\testImage\\12.jpg");
image2 = imread("D:\\testImage\\2.jpg");
if (!image1.data) {
cout << "image1图像不存在" << endl;
}
if (!image2.data) {
cout << "image2图像不存在" << endl;
}
if (image1.rows == image2.rows && image1.cols == image2.cols && image1.type() == image2.type()) {
//进行图像融合
double alpha = 0.5;
addWeighted(image1, alpha, image2, (1.0 - alpha), 0.0, dst);
imshow("image_blending", dst);
}
else {
cout << "could not blend image,the size of images is not same" << endl;
}
}
7.调整图像亮度和对比度
void QuickDemo::adjust_brightness_and_contrast_demo(Mat& image) {
int height = image.rows;
int width = image.cols;
//生成一张和原图大小相同的空白图
Mat dst;
dst = Mat::zeros(image.size(), image.type());
float alpha = 1.2;
float belta = 30;
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
if (image.channels() == 3) {
float b = image.at<Vec3b>(row, col)[0];
float g = image.at<Vec3b>(row, col)[1];
float r = image.at<Vec3b>(row, col)[2];
dst.at<Vec3b>(row, col)[0] = saturate_cast<uchar>(b*alpha+belta);
dst.at<Vec3b>(row, col)[1] = saturate_cast<uchar>(g * alpha + belta);
dst.at<Vec3b>(row, col)[2] = saturate_cast<uchar>(r * alpha + belta);
}
else if (image.channels() == 1) {
float v = image.at<uchar>(row, col);
}
}
}
imshow("adjust_brightness_and_contrast_image", dst);
}