[OpenCV Getting Started Tutorial 6] Creating Trackbar & Adjusting Image Contrast and Brightness Values
[Copy link]
This post was last edited by Rambo on 2017-12-21 11:43 In this article, we learned how to create and use trackbars in OpenCV using the createTrackbar function, as well as dynamically adjust image contrast and brightness values. The article first explains in detail the new version of the createTrackbar function in OpenCV2.0 for creating trackbars, and gives a detailed annotated example. Then the details of adjusting the contrast and brightness values of the image are explained, and finally a program source code is released to create a track bar using the createTrackbar function to assist in adjusting the contrast and brightness values of the image. Still, let's first post a running screenshot: Okay, let's start our explanation. 1. Creation and use of trackbar in OpenCV <1>Creating trackbar - detailed explanation of createTrackbar function We will often use the createTrackbar function in the future. It creates a trackbar that can adjust the value and attaches the trackbar to the specified window. It is very convenient to use. First of all, everyone should remember that it is often used in conjunction with a callback function. Let’s take a look at his function prototype first: [cpp] view plain copy - C++: int createTrackbar(conststring& trackbarname, conststring& winname, int* value, int count, TrackbarCallback onChange=0,void* userdata=0);
复制代码 - The first parameter, trackbarname of type const string&, indicates the name of the trackbar, which is used to represent the trackbar we created.
- The second parameter, winname of type const string&, is used to fill in the name of the window, indicating which window the track bar will be attached to, that is, the window name filled in when the corresponding namedWindow() creates the window.
- The third parameter, value of type int*, is a pointer to an integer, indicating the position of the slider. And when it is created, the initial position of the slider is the current value of the variable.
- The fourth parameter, count of type int, indicates the value of the maximum position that the slider can reach.PS:The value of the slider's minimum position is always 0.
- The fifth parameter, onChange of TrackbarCallback type, first note that it has a default value of 0. This is a pointer to a callback function, which will be called back every time the slider position changes. And the prototype of this function must be void XXXX(int,void*); the first parameter is the position of the trackbar, and the second parameter is the user data (see the sixth parameter below). If the callback is a NULL pointer, it means that there is no callback function call, and only the third parameter value changes.
- The sixth parameter, userdata of void* type, also has a default value of 0. This parameter is the data passed by the user to the callback function to handle trackbar events. If the third parameter value parameter used is a global variable, you can completely ignore the userdata parameter.
This createTrackbar function creates a trackbar (or slider range control tool) with a specific name and range for us, specifies a variable that is synchronized with the trackbar position. And specifies the callback function onChange (the fifth parameter), which is called when the trackbar position changes. And we know that the created trackbar is displayed on the window represented by the specified winname (the second parameter). , "] After reading the function explanation, I will give you a small example of using the function: 248)][cpp] view plain copy - //Create trackbarcreateTrackbar("Contrast:", "【Effect Window】",&g_nContrastValue, 300,ContrastAndBright );// g_nContrastValue is a global integer variable, ContrastAndBright is the function name of the callback function (i.e. a pointer to the function address)
复制代码 Let me give you a complete example of use. This is the official sample program of OpenCV, a program that demonstrates the use of trackbars to control contour detection and contour filling. I have modified it, simplified the code and annotated it in detail, and put it out for everyone to digest and study. The blog post updated later will have a more detailed explanation of contour detection. [cpp] view plain copy - //-----------------------------------[Header file includes part]--------------------------------------- // Description: Contains header files that the program depends on//---------------------------------------------------------------------------------------------- #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include<iostream>
-
- //-----------------------------------[Namespace declaration part]--------------------------------------- // Description: Contains the namespace used by the program//----------------------------------------------------------------------------------------------- using namespace cv; using namespace std; //-----------------------------------[Global function declaration part]-------------------------------------- // Description: Global function declaration//----------------------------------------------------------------------------------------------- Mat img; int threshval = 160; //The value corresponding to the trackbar slider, give the initial value 160 //-----------------------------[on_trackbar() function]------------------------------------ // Description: Trackbar callback function//----------------------------------------------------------------------------------------------- static void on_trackbar(int, void*) { Mat bw = threshval < 128 ? (img < threshval) : (img > threshval); //Define point and vector vector<vector<point>> contours; vector<vec4i>hierarchy; //Find contoursfindContours( bw, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); //Initialize dst Mat dst = Mat::zeros(img.size(), CV_8UC3); //Start processingif( !contours.empty() && !hierarchy.empty() ) { //Traverse all top-level contours and randomly generate color values to draw for each connected componentint idx = 0; for( ; idx >= 0; idx = hierarchy[idx][0] ) { Scalar color( (rand()&255), (rand()&255), (rand()&255) ); //Draw filled contoursdrawContours( dst, contours, idx, color, CV_FILLED, 8, hierarchy ); } } //Display windowimshow( "Connected Components", dst ); } //-----------------------------------【main() function】-------------------------------------------- // Description: The entry function of the console application, our program starts here//------------------------------------------------------------------------------- int main() { system("color 5F"); //Load image img = imread("1.jpg", 0); if( !img.data ) { printf("Oh, no, error in reading img image file~! \n"); return -1; } //Display the original image namedWindow( "Image", 1 ); imshow( "Image", img ); //Create processing window namedWindow( "Connected Components", 1 ); //Create trackbar createTrackbar( "Threshold", "Connected Components", &threshval, 255, on_trackbar ); on_trackbar(threshval, 0);//Trackbar callback function waitKey(0); return 0; }
复制代码 Original image: Operation effect chart: Drag the scroll bar and change the value of threshval (threshold value) to get pictures with very different effects: in the OpenCV path opencv_source_code/samples/cpp/connected_components.cpp, you can find the original official code. Next, let's talk about a function that works with createTrackbar, the getTrackbarPos function that gets the position of the current trackbar. <2>Get the current track bar position - getTrackbarPos function This function is used to get the position of the current track bar and return it. [cpp] view plain copy - C++: int getTrackbarPos(conststring& trackbarname, conststring& winname);
- The first parameter, trackbarname of type const string&, indicates the name of the trackbar.
- The second parameter, const winname of string& type, indicating the name of the parent window of the trackbar.
That’s about it for this part. Let’s move on to the next part :) II. Theoretical basis for brightness and contrast adjustment First, let us give the concept of operator. A general image processing operator is a function that accepts one or more input images and produces an output image. The following formula gives the general form of the operator: or The image brightness and contrast adjustment operations we are going to talk about today are actually a relatively simple type of image processing transformation - point operators. Point operators have a characteristic that they only calculate the corresponding output pixel value based on the input pixel value (sometimes with some global information or parameters). This type of operator includes brightness and contrast adjustments, as well as color correction and transformations. The two most commonly used point operations (or point operators) are, obviously, multiplying by a constant (corresponding to contrast adjustment) and adding a constant (corresponding to brightness adjustment). The formulas are as follows: Seeing this formula, our strategy for image brightness and contrast adjustment is obvious. Where: - The parameter f(x) represents the source image pixel.
- The parameter g(x) represents the output image pixel.
- The parameter a (needs to satisfy a>0) is called gain and is often used to control the contrast of the image.
- The parameter b is usually called bias and is often used to control the brightness of the image.
And one step further, we rewrite this formula like this: Among them, i and j Indicates that the pixel is located in the i-th row and j-th column. Then, this formula can be used as the theoretical formula for controlling the brightness and contrast of images in OpenCV. 3. About accessing pixels in an image There are many ways to access pixels in an image. I will use a special topic to explain it in the future. For now, we can first understand the following one. And in order to perform this operation, we need to access every pixel of the image. , 220)][cpp] [cpp] [cpp] 207)]view plain copy[/ color] - //Three for loops, perform operations 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 ); } } }
复制代码 Let's explain it in three aspects: - In order to access each pixel of the image, we use this syntax: image.at(y,x)[c]
- where yis the row where the pixel is, xis the column where the pixel is, and cis one of R, G, or B (corresponding to 0, 1, or 2).
- Because the result of our operation may exceed the pixel value range (overflow) and may also be a non-integer (if it is a floating point number), we need to convert the result using saturate_cast to ensure that it is a valid value. Here a is the contrast. Generally, for the sake of observation, it is a floating point value between 0.0 and 3.0. However, our track bar usually takes integer values. So here we can set the nContrastValue parameter representing the contrast value to an integer between 0 and 300, and multiply it by 0.01 in the final formula. This way, we can complete the change of 300 different values in the track bar. So in the formula, we can see saturate_cast( (g_nContrastValue*0.01)*(image.at(y,x)[c] ) + g_nBrightValue )in g_nContrastValue*0.01.
IV. Example program for adjusting image contrast and brightness values As always, each article will be accompanied by a detailed blog post with a sample program, which presents the knowledge points introduced in this article to everyone in the form of code. This sample program uses two track bars to control the contrast and brightness values respectively, which is quite playable. Without further ado, here are the codes: [cpp] view plain copy - //-----------------------------------[Program Description]---------------------------------------------- // Program name:: [OpenCV Getting Started Tutorial 4] Create Trackbar & Image Contrast, Brightness Value Adjustment Supporting Blog Source Code // VS2010 Version of OpenCV: 2.4.8 // March 18, 2014Created by Qianmo//------------------------------------------------------------------------------------------------//-----------------------------------[Header file inclusion part]--------------------------------------- // Description: Includes header files that the program depends on//---------------------------------------------------------------------------------------------- #include<opencv2 core="" core.hpp="">
- #include<opencv2 highgui="" highgui.hpp="">
- #include"opencv2/imgproc/imgproc.hpp" #include<iostream>
-
- //-----------------------------------[Namespace declaration section]--------------------------------------- // Description: Contains namespaces used by the program//----------------------------------------------------------------------------------------------- using namespace std; using namespace cv; //-----------------------------------[Global function declaration section]-------------------------------------- // Description: Global function declaration//----------------------------------------------------------------------------------------------- static void ContrastAndBright(int, void *); //-----------------------------------[Global variable declaration section]-------------------------------------- // Description: Global variable declaration//----------------------------------------------------------------------------------------------- int g_nContrastValue; //Contrast valueint g_nBrightValue; //Brightness valueMat g_srcImage,g_dstImage; //-----------------------------------[main() function]-------------------------------------------- // Description: The entry function of the console application, our program starts here//----------------------------------------------------------------------------------------------- int main() { //Change the foreground and background colors of the console system("color5F"); //Read the image provided by the user g_srcImage= imread( "pic1.jpg"); if(!g_srcImage.data ) { printf("Oh, no, error in reading g_srcImage~! \n"); return false; } g_dstImage= Mat::zeros( g_srcImage.size(), g_srcImage.type() ); //Set the initial values of contrast and brightness g_nContrastValue=80; g_nBrightValue=80; //Create window namedWindow("【Effect Graph Window】", 1); //Create trackbar createTrackbar("Contrast:", "【Effect Graph Window】",&g_nContrastValue,300,ContrastAndBright ); createTrackbar("Brightness:","【Effect Graph Window】",&g_nBrightValue,200,ContrastAndBright ); //Call callback function ContrastAndBright(g_nContrastValue,0); ContrastAndBright(g_nBrightValue,0); //Output some help information cout<<endl<<"\t嗯。好了,请调整滚动条观察图像效果~\n\n" !="q" )="" )函数】------------------------------------="" *)="" +="" -----------------------------------------------------------------------------------------------="" -----------------------------【contrastandbright(="" 1);="" 3;="" <="" <<"\n\n\t\t\t\tby浅墨";="" <<"\t按下“q”键时,程序退出~!\n"="" b="" c="0;" c++="" contrastandbright(int,="" for(int="" g_dstimage(i,j)="a*g_srcImage(i,j)" g_dstimage.at<vec3b="" g_srcimage.cols;="" g_srcimage.rows;="" namedwindow("【原始图窗口】",="" return0;="" static="" void="" while(char(waitkey(1))="" x="0;" x++="" y="0;" y++="" {="" {}="" }="" 三个for循环,执行运算="" 创建窗口="" 按下“q”键时,程序退出="" 描述:改变图像对比度和亮度值的回调函数="">(y,x)[c] = saturate_cast<uchar>( (g_nContrastValue*0.01)*(g_srcImage.at<vec3b>(y,x)[c] ) + g_nBrightValue ); } } } //Display imageimshow("【Original image window】", g_srcImage); imshow("【Effect image window】", g_dstImage); }
复制代码 Finally, take a look at the running screenshot. Running this program will get two image display windows. The first is the original image window and the second is the effect image window. In the effect image window, you can adjust the two track bars to change the contrast and brightness of the current image. Original image: [ali gn=left] Adjustable effect picture:
|