1.像素
1.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)
1.2像素范围处理
- saturate_cast<uchar>(-100),返回0
- saturate_cast<uchar>(288),返回255
- saturate_cast<uchar>(100),返回100
这个函数的功能是确保RGB值的范围在0-255之间
2.掩模
2.1概述
掩模操作时实现图像对比度调整
矩阵的掩模操作十分简单,根据掩模来重新计算每个像素的像素值,掩模(Mask,也称为kernel)
上图红色时中心像素,从上到下,从左到右,对每个像素做同样的处理操作,得到最终结果就是对比度提高之后的输出图像Mat对象
2.2实现
文件结构如下:
MyAPI.h中主要写函数的声明:
#pragma once
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
class MyApi {
public:
void improve_image_contrast(Mat& image);//提高图像的对比度
};
方法一:从定义出发实现对比度提高:实现放在MyAPI.cpp中:
#include"MyAPI.h"
void MyApi::improve_image_contrast(Mat& image)
{
Mat dst;
//由于读取的时RGB图所有实际的cols和row要乘以通道数、
int cols = (image.cols - 1) * image.channels();
int offsetx = image.channels();
int rows = image.rows;
dst = Mat::zeros(image.size(), image.type());
//看图3*3的掩模,将每个绿色的相加就是中间红色部分的值
for (int row = 1; row < (rows - 1); row++)
{
const uchar* previous = image.ptr<uchar>(row - 1);
const uchar* current = image.ptr<uchar>(row);
const uchar* next = 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] + previous[col] + next[col]));
}
}
namedWindow("contrast_improved_image", WINDOW_AUTOSIZE);
imshow("contrast_improved_image", dst);
}
测试文件为:
#include<opencv2/opencv.hpp>
#include<iostream>
#include"MyAPI.h"
using namespace std;
using namespace cv;
int main()
{
Mat src, dst;
src = imread("D:\\testImage\\123.bmp");
if (!src.data)
{
cout << "could not load Image...";
return -1;
}
namedWindow("input image", WINDOW_AUTOSIZE);
imshow("input image", src);
MyApi ma;
ma.improve_image_contrast(src);
waitKey(0);
return 0;
}
结果如下所示:
可以发现右边的对比度明显得到了改善。
方法二:我们也可以直接调用API实现提高对比度
- 定义掩模:Mat kernel=(Mat_<char>(3,3))<<0,-1,0,-1,5,-1,0,-1,0;
- filer2D(src,dst,src.depth(),kernel);其中src与dst是Mat类型变量,src.depth表示位图深度,有32,24,8等
我们可以在类中继续构造一个函数实现一下:
void MyApi::filter2DAPI(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);
namedWindow("contrast_improved_image", WINDOW_AUTOSIZE);
imshow("contrast_improved_image", dst);
}