原理:
在opencv改變圖像的對(duì)比度和亮度本質(zhì)是對(duì)像素點(diǎn)的操作,一個(gè)像素映射到另一個(gè)像素刁卜,用數(shù)學(xué)表示就是f(x蠢正,y)--->g(x,y)彻消,改變對(duì)比度和亮度的公式是g(i,j)=α?f(i,j)+β竿拆。其中α控制對(duì)比度,β控制亮度宾尚。有幾種實(shí)現(xiàn)方法丙笋。
1.遍歷圖像訪問(wèn)每個(gè)像素并改變像素,為了提高遍歷效率最好使用指針來(lái)遍歷煌贴,用函數(shù)cv::ptr(x)或cv::ptr(x,y)御板。
//部分代碼
uchar *p, *pt;
float a = 1.2;//對(duì)比度
int b = 50;//亮度
//對(duì)通道數(shù)量不同的圖像做不同處理
if (channel == 1)
{
for (int i = 0; i < src.rows; i++)
{
pt = src.ptr(i);
p = dst.ptr(i);
for (int j = 0; j < src.cols; j++)
{
p[j] = saturate_cast<uchar>(a * pt[j] + b);
}
}
}
else
{
for (int i = 0; i < src.rows; i++)
{
for (int j = 0; j < src.cols; j++)
{
pt = src.ptr(i,j);
p = dst.ptr(i,j);
for (int c = 0; c < src.channels(); c++)
{
p[c] = saturate_cast<uchar>(a * pt[c] + b);
}
}
}
}
由于操作可以使結(jié)果超出范圍或不是整數(shù)(如果是float),我們使用cv :: saturate_cast函數(shù)來(lái)確保值是有效的牛郑。
2.直接用矩陣的運(yùn)算:new_image = a * image + b
注意image和new_image的大械±摺(長(zhǎng)寬)、類型要一樣
//部分代碼
src = imread("./src/img4.jpg", IMREAD_UNCHANGED);
dst = Mat::zeros(src.size(), src.type());
float a = 1.2;//對(duì)比度
int b = 50;//亮度
dst = a * src + b;
3.高效率的方法:cv :: Mat :: convertTo(out, rtype, alpha, beta)
out是轉(zhuǎn)換的圖像淹朋,rtype是輸出矩陣的類型笙各, alpha和beta分別是對(duì)比度和亮度钉答。該函數(shù)是經(jīng)過(guò)優(yōu)化的opencv函數(shù),所以運(yùn)算效率要快的多酪惭。
//部分代碼
src = imread("./src/img4.jpg", IMREAD_UNCHANGED);
dst = Mat::zeros(src.size(), src.type());
float a = 1.2;//對(duì)比度
int b = 50;//亮度
src.convertTo(dst, -1, a, b);