作者:Steven
著作權宣告:著作權歸作者所有,商業轉載請聯系作者獲得授權,非商業轉載請注明出處
實作原理
影像對比度指的是一幅影像中明暗區域最亮的白和最暗的黑之間不同亮度層級的測量,即指一幅影像灰度反差的大小,差異范圍越大代表對比越大,差異范圍越小代表對比越小,設定一個基準值thresh,當percent大于0時,需要令影像中的顏色對比更強烈,即數值距離thresh越遠,則變化越大;當percent等于1時,對比強到極致,只有255和0的區分;當percent等于0時,不變;當percent小于0時,對比下降,即令遠離thresh的數值更近些;當percent等于-1時,沒有對比了,全是thresh值,
對比度調整演算法的實作流程如下:
1.設定調整引數percent,取值為-100到100,類似PS中設定,歸一化后為-1到1,
2.針對影像所有像素點單個處理,當percent大于等于0時,對比增強,調整后的RGB三通道數值為:
3.若percent小于0時,對比降低,此時調整后的影像RGB三通道值為:
4.若percent等于1時,大于thresh則等于255,小于則等于0,
至此,影像實作了明度的調整,演算法邏輯參考xingyanxiao,C++實作代碼如下,
功能函式代碼
// 對比度
cv::Mat Contrast(cv::Mat src, int percent)
{
float alpha = percent / 100.f;
alpha = max(-1.f, min(1.f, alpha));
cv::Mat temp = src.clone();
int row = src.rows;
int col = src.cols;
int thresh = 127;
for (int i = 0; i < row; ++i)
{
uchar *t = temp.ptr<uchar>(i);
uchar *s = src.ptr<uchar>(i);
for (int j = 0; j < col; ++j)
{
uchar b = s[3 * j];
uchar g = s[3 * j + 1];
uchar r = s[3 * j + 2];
int newb, newg, newr;
if (alpha == 1)
{
t[3 * j + 2] = r > thresh ? 255 : 0;
t[3 * j + 1] = g > thresh ? 255 : 0;
t[3 * j] = b > thresh ? 255 : 0;
continue;
}
else if (alpha >= 0)
{
newr = static_cast<int>(thresh + (r - thresh) / (1 - alpha));
newg = static_cast<int>(thresh + (g - thresh) / (1 - alpha));
newb = static_cast<int>(thresh + (b - thresh) / (1 - alpha));
}
else {
newr = static_cast<int>(thresh + (r - thresh) * (1 + alpha));
newg = static_cast<int>(thresh + (g - thresh) * (1 + alpha));
newb = static_cast<int>(thresh + (b - thresh) * (1 + alpha));
}
newr = max(0, min(255, newr));
newg = max(0, min(255, newg));
newb = max(0, min(255, newb));
t[3 * j + 2] = static_cast<uchar>(newr);
t[3 * j + 1] = static_cast<uchar>(newg);
t[3 * j] = static_cast<uchar>(newb);
}
}
return temp;
}
C++測驗代碼
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
cv::Mat Contrast(cv::Mat src, int percent);
int main()
{
cv::Mat src = imread("5.jpg");
cv::Mat result = Contrast(src, 50.f);
imshow("original", src);
imshow("result", result);
waitKey(0);
return 0;
}
// 對比度
cv::Mat Contrast(cv::Mat src, int percent)
{
float alpha = percent / 100.f;
alpha = max(-1.f, min(1.f, alpha));
cv::Mat temp = src.clone();
int row = src.rows;
int col = src.cols;
int thresh = 127;
for (int i = 0; i < row; ++i)
{
uchar *t = temp.ptr<uchar>(i);
uchar *s = src.ptr<uchar>(i);
for (int j = 0; j < col; ++j)
{
uchar b = s[3 * j];
uchar g = s[3 * j + 1];
uchar r = s[3 * j + 2];
int newb, newg, newr;
if (alpha == 1)
{
t[3 * j + 2] = r > thresh ? 255 : 0;
t[3 * j + 1] = g > thresh ? 255 : 0;
t[3 * j] = b > thresh ? 255 : 0;
continue;
}
else if (alpha >= 0)
{
newr = static_cast<int>(thresh + (r - thresh) / (1 - alpha));
newg = static_cast<int>(thresh + (g - thresh) / (1 - alpha));
newb = static_cast<int>(thresh + (b - thresh) / (1 - alpha));
}
else {
newr = static_cast<int>(thresh + (r - thresh) * (1 + alpha));
newg = static_cast<int>(thresh + (g - thresh) * (1 + alpha));
newb = static_cast<int>(thresh + (b - thresh) * (1 + alpha));
}
newr = max(0, min(255, newr));
newg = max(0, min(255, newg));
newb = max(0, min(255, newb));
t[3 * j + 2] = static_cast<uchar>(newr);
t[3 * j + 1] = static_cast<uchar>(newg);
t[3 * j] = static_cast<uchar>(newb);
}
}
return temp;
}
測驗效果
通過調整percent可以實作影像對比度的調整,
如果函式有什么可以改進完善的地方,非常歡迎大家指出,一同進步何樂而不為呢~
如果文章幫助到你了,可以點個贊讓我知道,我會很快樂~加油!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/297667.html
標籤:其他
上一篇:如何在OpenCV中為InRange閾值選擇顏色的最佳HSV值
下一篇:哈希影像相似性識別
