一、对比度亮度调整
g(x) = a * f(x) + b
a.参数f(x)表示原图像像素
b.参数g(x)表示输出图像像素
c.参数a(a>0),被称为增益(gain), 通常用来控制图像的对比度
d.参数b通常被称为偏置(bias), 通常用来控制图像的亮度
g(i,j) = a * f(i,j) + b
eg:
#include "opencv2/opencv.hpp"
using namespace cv;
#define WIN_NAME "输出图像"
Mat srcImg;
Mat dstImg;
int Contrase_Value = 20;
int Bright_Value = 20;
void OnChange(int, void*)
{
for(int i = 0; i<srcImg.rows; i++)
{
for(int j = 0; j<srcImg.cols; j++)
{
dstImg.at<Vec3b>(i, j)[0] = saturate_cast<uchar>(Contrase_Value * 0.01 * srcImg.at<Vec3b>(i, j)[0] + Bright_Value);
dstImg.at<Vec3b>(i, j)[1] = saturate_cast<uchar>(Contrase_Value * 0.01 * srcImg.at<Vec3b>(i, j)[1] + Bright_Value);
dstImg.at<Vec3b>(i, j)[2] = saturate_cast<uchar>(Contrase_Value * 0.01 * srcImg.at<Vec3b>(i, j)[2] + Bright_Value);
}
}
imshow("原图", srcImg);
imshow(WIN_NAME, dstImg);
}
void main()
{
srcImg = imread("1.jpg");
dstImg = Mat::zeros(srcImg.size(), srcImg.type());
Mat::zeros(); 将矩阵元素都置为0
Mat::ones(); 将矩阵元素都置为1
namedWindow(WIN_NAME, CV_WINDOW_AUTOSIZE);
createTrackbar("对比度", WIN_NAME, &Contrase_Value, 300, OnChange, 0);
createTrackbar("亮 度", WIN_NAME, &Bright_Value, 200, OnChange, 0);
OnChange(Contrase_Value, 0); 回调函数初始化
OnChange(Bright_Value, 0);
waitKey(0);
}
其中saturate_cast为溢出保护,原理如下:
if(data<0)
data=0;
else if(data>255)
data=255;
上面那个小程序是用滑动条来实现对比度和亮度的调整。
二、通道的分离和合并
split通道分离函数,merge通道合并函数
threshold图像二值化函数:
double threshold( const Mat& src, Mat& dst, double thresh,double maxVal, int thresholdType );
参数:
src:原图像。
dst:结果图像。
thresh:当前阈值。
maxVal:最大阈值,一般为255.
thresholdType:阈值类型,主要有下面几种:
enum { THRESH_BINARY=0, THRESH_BINARY_INV=1,
THRESH_TRUNC=2, THRESH_TOZERO=3,
THRESH_TOZERO_INV=4};
THRESH BINARY:二进制阈值,。在运用该阈值类型的时候,先要选定一个特定的阈值量,比如:125,这样,新的阈值产生规则可以解释为大于125的像素点的灰度值设定为最大值255,灰度值小于125的像素点的灰度值设定为0。 (value>threshold?255:0)
THRESH BINARY INV:反二进制阈值。设定一个初始阈值如125,则大于125的设定为0,而小于该阈值的设定为255。 (value>threshold?0:255)THRESH TRUNC:截断阈值。同样首先需要选定一个阈值,图像中大于该阈值的像素点被设定为该阈值,小于该阈值的保持不变。(例如:阈值选取为125,那小于125的阈值不改变,大于125的灰度值(230)的像素点就设定为该阈值)。 (value>threshold?threshold:value)
eg:
#include "opencv2/opencv.hpp"
using namespace cv;
void main()
{
Mat img = imread("2.jpg");
Mat dst;
vector<Mat> channels;
split(img, channels);
Mat blueChannel = channels.at(0);
Mat greenChannel = channels.at(1);
Mat redChannel = channels.at(2);
threshold(blueChannel, blueChannel, 200, 255, THRESH_BINARY);
threshold(greenChannel, greenChannel, 200, 255, THRESH_BINARY);
threshold(redChannel, redChannel, 200, 255, THRESH_BINARY);
merge(channels, dst);
/*imshow("Blue", blueChannel);
imshow("green", greenChannel);
imshow("red", redChannel);*/
imshow("dst", dst);
waitKey(0);
}