天天看點

C++ OpenCV4.5 調整圖像亮度的幾種方法(八)系列文章目錄前言一、像素值計算二、使用cv::add三、使用cv::addWeighted四、主函數總結

系列文章目錄

C++ OpenCV4.5環境搭建(一)

C++ OpenCV4.5常用API查詢手冊(二)

C++ OpenCV4.5 圖像處理(三)

C++ OpenCV4.5 繪制形狀與文字(四)

C++ OpenCV4.5 圖像模糊(五)

C++ OpenCV4.5 項目實戰一(六)

C++ OpenCV4.5 形态學操作(七)

文章目錄

  • 系列文章目錄
  • 前言
  • 一、像素值計算
  • 二、使用cv::add
  • 三、使用cv::addWeighted
  • 四、主函數
  • 總結

前言

本篇介紹如何調整圖像亮度和對比度的方法,效果等價于美圖app中的小功能,目測不止這幾種方式,持續更新!

一、像素值計算

通過對每個點的像素值進行加減計算,達到調整圖檔亮度的目的,示例代碼如下:

// 增加亮度方法一
void IncreaseBrightness1(int iPos, void* pUserdata)
{
	Mat img = ((Mat*)pUserdata)->clone();

	int iWidth = img.cols;
	int iHeight = img.rows;
	int iChannels = img.channels();

	// 直接挨個像素點加上某個值
	for (int row = 0; row < iHeight; row++)
	{
		// 可以指針偏移,也可用使用數組下标通路
		uchar* pCurRow = img.ptr<uchar>(row);
		for (int col = 0; col < iWidth; col++)
		{
			if (iChannels == 1)
			{
				*pCurRow++ = saturate_cast<uchar>(*pCurRow + iPos);
			}
			else if (iChannels == 3)
			{
				// saturate_cast 防止顔色溢出操作;像素值小于0時,指派0;大于255時,指派255
				*pCurRow++ = saturate_cast<uchar>(*pCurRow + iPos);
				*pCurRow++ = saturate_cast<uchar>(*pCurRow + iPos);
				*pCurRow++ = saturate_cast<uchar>(*pCurRow + iPos);
			}
		}
	}

	imshow(g_pOutputWinTitle, img);
}
           

二、使用cv::add

使用cv::add等API進行圖像像素計算,實作圖像對比度調整,示例代碼如下:

// 增加亮度方法二
void IncreaseBrightness2(int iPos, void* pUserdata)
{
	Mat img = ((Mat*)pUserdata)->clone();
	Mat dst;
	Mat src2 = Mat::zeros(img.size(), img.type());
	src2 = Scalar(iPos, iPos, iPos);
	// 功能:計算兩個圖像的像素值的和
	// 參數:src1 第一個輸入圖像
	//			src2 第二個輸入圖像
	//			dst 與輸入圖像具有相同大小和通道數的輸出圖像;深度由dtype或src1/src2定義
	//			mask 可選操作掩碼-8位單通道圖像,指定要更改的輸出圖像元素。
	//			dtype 輸出圖像的可選深度,src1和src2深度相等時可設定值-1(預設)
	add(img, src2, dst);
	
	// 如果src1和src2深度相同,等價于
	//dst = img + src2;

	// 相減 subtract,參數清單同上,如果深度相同,等價于dst = src1 - src2;
	// 相乘 multiply,參數清單同上,像素值之間的運算
	// 相除 divide,參數清單同上,像素值之間的運算

	imshow(g_pOutputWinTitle, dst);
}
           

三、使用cv::addWeighted

圖像混合函數addWeighted不但可以調整亮度,還可以調整對比度,代碼如下(示例):

// 增加 亮度/對比度 方法三
void IncreaseBrightness3(int iPos, void* pUserdata)
{
	Mat img = ((Mat*)pUserdata)->clone();
	// addWeighted的兩張混合圖像的大小和類型必須一緻
	Mat src2 = Mat::zeros(img.size(), img.type());
	Mat dst;

	/*******************************調整圖像亮度**********************************/
	// 使用圖像混合函數(dst = src1*alpha + src2*beta + gamma;)
	// 輸入圖像1權重為1,輸入圖像2的權重設定為0,增加gamma的值即可實作亮度調整
	addWeighted(img, 1.0, src2, 0, iPos, dst);
	imshow(g_pOutputWinTitle, dst);

	/*******************************調整圖像對比度**********************************/
	// 使用圖像混合函數(dst = src1*alpha + src2*beta + gamma;)
	// 輸入圖像2的權重設定為0,gamma的值為0,修改輸入圖像1的權重、可實作對比度調整
	//double dContrast =  (double)iPos / 100.0;
	//addWeighted(img, dContrast, src2, 0, 0, dst);
	//imshow(g_pOutputWinTitle, dst);
}
           

四、主函數

代碼如下(示例):

#include "opencv2/opencv.hpp"
#include <iostream>

using namespace cv;
using std::cout;
using std::endl;

char* g_pOutputWinTitle = "輸出圖像";
int g_iBrightnessValue1 = 30;
int g_iBrightnessValue2 = 30;
int g_iBrightnessValue3 = 30;
int g_iBrightnessMax = 255;

// 增加亮度方法一
void IncreaseBrightness1(int iPos, void* pUserdata);
// 增加亮度方法二
void IncreaseBrightness2(int iPos, void* pUserdata);
// 增加 亮度/對比度 方法三
void IncreaseBrightness3(int iPos, void* pUserdata);

int main(void)
{
	Mat img = imread("E:\\2.png");
	if (img.empty())
	{
		cout << "load image fail." << endl;
		return -1;
	}
	imshow("輸入圖像", img);

	namedWindow(g_pOutputWinTitle);

	createTrackbar("亮度調整方法一", g_pOutputWinTitle, &g_iBrightnessValue1, g_iBrightnessMax, IncreaseBrightness1, (void*)&img);
	
	createTrackbar("亮度調整方法二", g_pOutputWinTitle, &g_iBrightnessValue2, g_iBrightnessMax, IncreaseBrightness2, (void*)&img);
	
	createTrackbar("亮度調整方法三", g_pOutputWinTitle, &g_iBrightnessValue3, g_iBrightnessMax, IncreaseBrightness3, (void*)&img);

	IncreaseBrightness1(g_iBrightnessValue1, (void*)&img);

	waitKey(0);

	return 0;
}
           

總結

純粹是學習道路上的一點記錄,很多地方了解的不是很透徹,不足的地方歡迎指正,會一直完善!

繼續閱讀