[OpenCV入門チュートリアル6]トラックバーを作成し、画像のコントラストと明るさの値を調整します



このシリーズの記事は@浅墨_毛星✓によって作成されています。転載のソースを示してください。
記事のリンク:http://blog.csdn.net/poem_qianmo/article/details/21176257
現在のブログ投稿を書くときに使用されるOpenCVバージョン:4.20

この記事では、OpenCVのcreateTrackbar関数を使用してトラックバーを作成および使用する方法と、画像のコントラストと明るさの値を動的に調整する方法を学びました。

この記事では、最初に新しいバージョンのOpenCV2.0の関数createTrackbarについて詳しく説明し、詳細なコメントの例を示しました。

次に、画像のコントラストと明るさの調整の詳細を説明し、最後にcreateTrackbar関数を使用して画像のコントラストと明るさの調整を支援するトラックバーを作成するプログラムソースコードをリリースしました。

それでも、最初に操作のスクリーンショットを置きます
ここに画像の説明を挿入します
。OK、正式に説明を始めましょう。

1.OpenCVでのトラックバーの作成と使用

<1>トラックバーの作成-createTrackbar関数の詳細な説明

関数createTrackbarは、今後頻繁に使用される予定です。値を調整できるトラックバーを作成し、指定されたウィンドウにトラックバーをアタッチするので非常に便利です。まず第一に、それはコールバック関数と組み合わせて使用​​されることが多いことを誰もが覚えておく必要があります。彼の関数プロトタイプを最初に見てください:

C++: int createTrackbar(conststring& trackbarname, conststring& winname,
 int* value, int count, TrackbarCallback onChange=0,void* userdata=0);

最初のパラメーターであるconststring&typeのtrackbarnameは、作成したトラックバーを表すために使用されるトラックバーの名前を表します。
2番目のパラメーターであるconststring&typeのwinnameは、ウィンドウの名前を入力します。これは、トラックバーがアタッチされるウィンドウを示します。これは、namedWindow()がウィンドウを作成するときに入力される特定のウィンドウ名に対応します。
3番目のパラメーターであるint *型の値は、スライダーの位置を示す整数へのポインターです。また、作成時のスライダーの初期位置は、変数の現在の値です。
4番目のパラメーターであるint型のカウントは、スライダーが到達できる最大位置の値を表します。PS:スライダーの最小位置の値は常に0です。
5番目のパラメーターonChangeof TrackbarCallbackタイプは、デフォルト値が0であることに最初に気づきます。これはコールバック関数へのポインタです。この関数は、スライダーの位置が変わるたびにコールバックを作成します。また、この関数のプロトタイプはvoid XXXX(int、void *)である必要があります。最初のパラメーターはトラックバーの位置であり、2番目のパラメーターはユーザーデータです(以下の6番目のパラメーターを参照)。コールバックがNULLポインターの場合、コールバック関数呼び出しがなく、3番目のパラメーター値のみが変更されたことを意味します。
6番目のパラメーターであるvoid *タイプのuserdataも、デフォルト値は0です。このパラメーターは、トラックバーイベントを処理するためにユーザーからコールバック関数に渡されるデータです。使用される3番目のパラメーター値引数がグローバル変数である場合、userdataパラメーターは無視できます。

このcreateTrackbar関数は、特定の名前と範囲でトラックバー(トラックバー、またはスライダー範囲制御ツール)を作成し、トラックバーの位置と同期する変数を指定します。また、トラックバーの位置が変更されたときに呼び出されるコールバック関数onChange(5番目のパラメーター)を指定する必要があります。そして、作成されたトラックバーが、指定されたwinname(2番目のパラメーター)で表されるウィンドウに表示されることがわかります。

関数の説明を読んだ後、最初に関数の使用法の小さな例を示しましょう。

 //创建轨迹条
       createTrackbar("对比度:", "【效果图窗口】",&g_nContrastValue,
300,ContrastAndBright );// g_nContrastValue为全局的整型变量,ContrastAndBright为回调函数的函数名(即指向函数地址的指针)

完全な使用例を示しましょう。これは、OpenCVの公式サンプルプログラムです。これは、トラックバーを使用して輪郭検出と輪郭塗りつぶしを制御する方法を示すプログラムです。Qianmoは、誰もが消化して学習できるように、変更、コードの簡素化、詳細なコメントを公開しています。輪郭検出の詳細については、後で更新されるブログ投稿で説明します。

//-----------------------------------【头文件包含部分】---------------------------------------
//	描述:包含程序所依赖的头文件
//---------------------------------------------------------------------------------------------- 
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>

//-----------------------------------【命名空间声明部分】---------------------------------------
//	描述:包含程序所使用的命名空间
//-----------------------------------------------------------------------------------------------   
using namespace cv;
using namespace std;

//-----------------------------------【全局函数声明部分】--------------------------------------
//	描述:全局函数声明
//-----------------------------------------------------------------------------------------------
Mat img;
int threshval = 160;			//轨迹条滑块对应的值,给初值160

//-----------------------------【on_trackbar( )函数】------------------------------------
//	描述:轨迹条的回调函数
//-----------------------------------------------------------------------------------------------
static void on_trackbar(int, void*)
{
	Mat bw = threshval < 128 ? (img < threshval) : (img > threshval);

	//定义点和向量
	vector<vector<Point> > contours;
	vector<Vec4i> hierarchy;

	//查找轮廓
	findContours(bw, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE);
	//初始化dst
	Mat dst = Mat::zeros(img.size(), CV_8UC3);
	//开始处理
	if (!contours.empty() && !hierarchy.empty())
	{
		//遍历所有顶层轮廓,随机生成颜色值绘制给各连接组成部分
		int idx = 0;
		for (; idx >= 0; idx = hierarchy[idx][0])
		{
			Scalar color((rand() & 255), (rand() & 255), (rand() & 255));
			//绘制填充轮廓
			drawContours(dst, contours, idx, color, FILLED, 8, hierarchy);
		}
	}
	//显示窗口
	imshow("Connected Components", dst);
}


//-----------------------------------【main( )函数】--------------------------------------------
//	描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main()
{
	system("color 5F");
	//载入图片
	img = imread("1.jpg", 0);
	if (!img.data) { printf("Oh,no,读取img图片文件错误~! \n"); return -1; }

	//显示原图
	namedWindow("Image", 1);
	imshow("Image", img);

	//创建处理窗口
	namedWindow("Connected Components", 1);
	//创建轨迹条
	createTrackbar("Threshold", "Connected Components", &threshval, 255, on_trackbar);
	on_trackbar(threshval, 0);//轨迹条回调函数

	waitKey(0);
	return 0;
}

元の画像:
ここに画像の説明を挿入します
ランニングエフェクトの画像:
ここに画像の説明を挿入します

スクロールバーをドラッグしてthreshval(しきい値)の値を変更し、さまざまな効果のある画像を取得します。

ここに画像の説明を挿入します
さらに、元の公式コードは、OpenCVパスopencv_source_code / samples / cpp /connected_components.cppにあります。

次に、現在のトラックバーの位置を取得するために使用されるgetTrackbarPos関数であるcreateTrackbarで使用される関数について説明します。

<2>現在のトラックバーの位置を取得します-getTrackbarPos関数

<2>現在のトラックバーの位置を取得します-getTrackbarPos関数

この関数は、現在のトラックバーの位置を取得して返すために使用されます。

最初のパラメーターであるconststring&タイプのtrackbarnameは、トラックバーの名前を表します。
2番目のパラメーターであるconststring&タイプのwinnameは、トラックバーの親ウィンドウの名前を表します。

この部分はおそらくこれで終わりです。次のパートにノンストップで行きましょう:)

2.明るさとコントラストの調整の理論的根拠

まず、演算子の概念を示します。一般的な画像処理演算子は、1つ以上の入力画像を受け取り、出力画像を生成する関数です。次の式は、演算子の一般的な形式を示しています。

ここに画像の説明を挿入します
今日説明している画像の明るさとコントラストの調整操作は、実際には比較的単純なタイプの画像処理変換ポイント演算子です。ポイント操作には、対応する出力ピクセル値を計算するために、入力ピクセル値のみに基づく特性があります(グローバル情報またはパラメーターを追加できる場合もあります)。このような演算子には、明るさとコントラストの調整、および色補正と変換が含まれます。

最も一般的に使用される2つのポイント演算(またはポイント演算子)は、明らかに、定数の乗算(コントラストの調整に対応)と定数の加算(輝度値の調整に対応)です。式は次のようになります。

ここに画像の説明を挿入します
この公式を見て、画像の明るさとコントラスト調整のための私たちの戦略が出てくる準備ができています。

その中で:

**パラメータf(x)**は、ソース画像のピクセルを表します。
パラメータg(x)は、出力画像のピクセルを表します。
パラメータa(a> 0を満たす必要がある)はゲインと呼ばれ、画像のコントラストを制御するためによく使用されます。
パラメータbは通常バイアスと呼ばれ、画像の明るさを制御するためによく使用されます。

そして、一歩近づいて、この式を次のように書き直します。
ここに画像の説明を挿入します
ここで、iとjは、ピクセルがi番目の行とj番目の列にあることを示します。

次に、この式は、OpenCVで画像の明るさとコントラストを制御するための理論式として使用できます。

3.画像のピクセルへのアクセスについて

画像のピクセルにアクセスする方法はたくさんありますが、ライトインクはトピックを使用して将来説明します。現在、私たちは最初に次のことを理解することができます。

この操作を実行するには、画像のすべてのピクセルにアクセスする必要があります。操作はGBR画像で実行されるため、各ピクセルには3つの値(G、B、R)があり、それらに個別にアクセスする必要があります(PS:OpenCVの画像ストレージモードはGBRです)。以下は、ピクセルにアクセスするためのコードスニペットです。3つのforループが問題を解決します。

//三个for循环,执行运算 new_image(i,j) =a*image(i,j) + b
       for(int y = 0; y < image.rows; y++ )
       {
              for(int x = 0; x < image.cols; x++ )
              {
                     for(int c = 0; c < 3; c++ )
                     {
                            new_image.at<Vec3b>(y,x)[c]= saturate_cast<uchar>( (g_nContrastValue*0.01)*(image.at<Vec3b>(y,x)[c] ) + g_nBrightValue );
                     }
              }
       }

3つの側面で説明しましょう:

画像の各ピクセルにアクセスするには、次の構文を使用します:image.at(y、x)[c]

その中で、yはピクセルが配置されている行、xはピクセルが配置されている列、cはR、G、およびB(0、1、2に対応)のいずれかです。

計算結果がピクセル値の範囲を超える(オーバーフロー)か、非整数(浮動小数点数の場合)になる可能性があるため、saturate_castを使用して結果を変換し、有効な値であることを確認する必要があります。

ここでaはコントラストです。通常、値は観測効果のために0.0から3.0までの浮動小数点値ですが、トラックバーは通常整数値を取るため、ここでコントラスト値を表すnContrastValueパラメーターを設定できます。は0から300までの整数です。最終式で0.01を掛けて、トラックバーで300の異なる値の変更を完了できるようにします。したがって、式ではsaturate_cast((g_nContrastValue 0.01)(image.at(y、x)[c])+ g_nBrightValue)にg_nContrastValue * 0.01が表示されます。

4、画像コントラスト、明るさ値調整サンプルプログラム

すべての記事が割り当てられるのは、サンプルプログラムをサポートする詳細な注釈付きブログ投稿です。この記事で紹介するナレッジポイントは、コードを表示するためのキャリアとして使用されます。

このサンプルプログラムは、2つのトラックバーを使用して、コントラストと明るさの値をそれぞれ制御します。これには、ある程度の再生可能性があります。あまりナンセンスではありません。コードに行きましょう。

// 操作系统: Windows 10 64bit
// 开发语言: C++
// IDE 版 本:Visual Studio 2019
// OpenCV版本:4.20
//-----------------------------------【头文件包含部分】---------------------------------------
//	描述:包含程序所依赖的头文件
//---------------------------------------------------------------------------------------------- 
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>

//-----------------------------------【命名空间声明部分】---------------------------------------
//	描述:包含程序所使用的命名空间
//-----------------------------------------------------------------------------------------------   
using namespace std;
using namespace cv;


//-----------------------------------【全局函数声明部分】--------------------------------------
//	描述:全局函数声明
//-----------------------------------------------------------------------------------------------
static void ContrastAndBright(int, void*);
void   ShowHelpText();

//-----------------------------------【全局变量声明部分】--------------------------------------
//	描述:全局变量声明
//-----------------------------------------------------------------------------------------------
int g_nContrastValue; //对比度值
int g_nBrightValue;  //亮度值
Mat g_srcImage, g_dstImage;
//-----------------------------------【main( )函数】--------------------------------------------
//	描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main()
{
	//改变控制台前景色和背景色
	system("color 2F");

	// 读入用户提供的图像
	g_srcImage = imread("1.jpg");
	if (!g_srcImage.data) { printf("读取g_srcImage图片错误~! \n"); return false; }
	g_dstImage = Mat::zeros(g_srcImage.size(), g_srcImage.type());

	//设定对比度和亮度的初值
	g_nContrastValue = 80;
	g_nBrightValue = 80;

	//创建窗口
	namedWindow("【效果图窗口】", 1);

	//创建轨迹条
	createTrackbar("对比度:", "【效果图窗口】", &g_nContrastValue, 300, ContrastAndBright);
	createTrackbar("亮   度:", "【效果图窗口】", &g_nBrightValue, 200, ContrastAndBright);

	//调用回调函数
	ContrastAndBright(g_nContrastValue, 0);
	ContrastAndBright(g_nBrightValue, 0);

	//输出一些帮助信息
	cout << endl << "\t运行成功,请调整滚动条观察图像效果\n\n"
		<< "\t按下“q”键时,程序退出\n";

	//按下“q”键时,程序退出
	while (char(waitKey(1)) != 'q') {}
	return 0;
}


//-----------------------------【ContrastAndBright( )函数】------------------------------------
//	描述:改变图像对比度和亮度值的回调函数
//-----------------------------------------------------------------------------------------------
static void ContrastAndBright(int, void*)
{

	// 创建窗口
	namedWindow("【原始图窗口】", 1);

	// 三个for循环,执行运算 g_dstImage(i,j) = a*g_srcImage(i,j) + b
	for (int y = 0; y < g_srcImage.rows; y++)
	{
		for (int x = 0; x < g_srcImage.cols; x++)
		{
			for (int c = 0; c < 3; c++)
			{
				g_dstImage.at<Vec3b>(y, x)[c] = saturate_cast<uchar>((g_nContrastValue * 0.01) * (g_srcImage.at<Vec3b>(y, x)[c]) + g_nBrightValue);
			}
		}
	}

	// 显示图像
	imshow("【原始图窗口】", g_srcImage);
	imshow("【效果图窗口】", g_dstImage);
}

最後に、操作のスクリーンショットを見てください。このプログラムを実行すると、2つの画像表示ウィンドウが表示されます。1つ目は元の画像ウィンドウで、2つ目はエフェクト画像ウィンドウです。エフェクト画像ウィンドウで2つのトラックバーを調整して、現在の画像のコントラストと明るさを変更できます。

元の画像:
ここに画像の説明を挿入します
ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/m0_51233386/article/details/114667113