How to Change Pixel RGB Values of Webcam Video Using OpenCV [C++]
Today, in this tutorial, we are going to learn how to change pixels RGB values using a GUI with multiple trackbars. If you don't know what does RGB values mean, they are simply color parameters which indicate its red, green, and blue intensity. Each intensity value is between 0 and 255.
Step 1: Importing HPP files (Headers):
#include <opencv2\opencv.hpp> #include <iostream> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp>
Step 2 : Creating namespaces :
using namespace cv; using namespace std;
When we use namespaces we don't need to write certain terms like cv every time before calling an OpenCV function.
Example : Size(960, 960);
instead of cv::Size(960, 960);
Step 3: Writing the main function :
int main() { // Code Here return 0 ; }
If you don't know what a main function is, it's a function that presents the entry point of the program that we are going to run.
Step 4: Declaring the necessary variables :
Mat image ; int r_slider = 0; int g_slider = 0; int b_slider = 0;
- image is an empty matrix where we are going to store webcam frames.
- r_slider , b_slider and b_slider are the positions of the trackbar sliders.
- r refers to Red , g to Green and b to Blue .
- We set up the initial position of the trackbar slider at 0.
Step 5 : Creating the trackbars window :
namedWindow("trackbar panel");
- Trackbar panel is the name of the window.
- Pay attention about extra spaces in the trackbar name which can cause errors.
- Our trackbars will be attached to this window.
Step 6: Creating trackbars :
createTrackbar("r", "trackbar panel", &r_slider, 255); createTrackbar("g", "trackbar panel", &g_slider, 255); createTrackbar("b", "trackbar panel", &b_slider, 255);
- 1st parameter: name of the trackbar
- 2nd parameter: name of the trackbar window
- 3rd parameter: pointer of the slider value
- 4th parameter: maximum value of the slider
Step 7: Creating the window where the webcam video will be displayed :
namedWindow("Display window"); // Create a window for display
Step 8: Opening the webcam :
VideoCapture cap(0); if (!cap.isOpened()) { cout << "cannot open camera"; }
- 0 is the index of the Webcam. If you get an error, try changing that index to -1 or 1, 2 ... etc until you find the right index.
- We used an if statement to verify if a video device has been successfully initialized or not.
Step 9 : Writing an infinite While loop inside the main function:
int main() { while (true) { //code here } return 0 ; }
- We need an infinite loop to be able to show the video repeatedly frame by frame.
- In the infinite while loop we are going also to check every time if the trackbar slider value has been changed or not since we are not this time going to use the onChange trackbar callback function .
Step 10: Reading the Trackbar slider position :
r_slider = getTrackbarPos("r", "trackbar panel"); g_slider = getTrackbarPos("g", "trackbar panel"); b_slider = getTrackbarPos("b", "trackbar panel");
- In the while loop, we need repeatedly to get the trackbar slider value and store it in the empty variables (r_slider, g_slider , ...).
Step 11 : Inserting the webcam frame inside the image matrix :
cap >> image;
image = cap ; will give you back an error. So pay attention about the >>
Step 12: Resizing the image matrix :
resize(image, image, Size(960, 960));
- 1st Parameter: Input image matrix.
- 2nd Parameter: Output image matrix.
- 3rd Parameter: inside the Size function, we need to set the new dimensions
Step 13: Running double For loops inside the image matrix :
for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { Vec3b color = image.at(Point(i, j)); image.at(i, j)[2] = image.at(i, j)[2] + r_slider; } }
- The For loop with index i runs horizontally through the rows of the image matrix
- The For loop with index j runs vertically through the columns of the image matrix
- Running a For loop inside another For loop in this way will let us scan the whole pixels in the image matrix.
- image.rows gives back the total number of horizontal pixels
- image.cols gives back the total number of vertical pixels
- Vec3b is a vector with 3 byte entries. Those byte entries are between 0 and 255. Each byte presents the intensity of a single color channel.
- In other words, Vec3b is a single RGB pixel. So Vec3b [0] is the blue color, [1] green and [2] red.
- We will execute this double For Loop 3 times. Each time for each color channel.
Step 14: Displaying the image matrix inside the Window
imshow("Display window", image);
Step 15 : Setting up display time of the webcam frames
waitKey(25);
The value inside waitkey() will affect how fast webcam frames will be displayed. If this value is
too low, the video will looks very fast. If it's too high, the video will looks very slow and laggy.
25 milliseconds will be OK in normal cases and avoid choosing 0 ms, it will display the same frame infinitely until you press any key(it is suitable for image display not for video display).
Code [C++] :
#include <opencv2\opencv.hpp> #include <iostream> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace cv; using namespace std; int main() { Mat image; int r_slider = 0; int g_slider = 0; int b_slider = 0; namedWindow("trackbar panel"); createTrackbar("r", "trackbar panel", &r_slider, 255); createTrackbar("g", "trackbar panel", &g_slider, 255); createTrackbar("b", "trackbar panel", &b_slider, 255); namedWindow("Display window"); // Create a window for display VideoCapture cap(0); if (!cap.isOpened()) { // check if video device has been initialised std::cout << "cannot open camera"; } while (true) { r_slider = getTrackbarPos("r", "trackbar panel"); g_slider = getTrackbarPos("g", "trackbar panel"); b_slider = getTrackbarPos("b", "trackbar panel"); cap >> image; resize(image, image, Size(960, 960)); for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { Vec3b color = image.at(Point(i, j)); image.at(i, j)[2] = image.at(i, j)[2] + r_slider; } } for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { Vec3b color = image.at(Point(i, j)); image.at(i, j)[1] = image.at(i, j)[1] + g_slider; } } for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { Vec3b color = image.at(Point(i, j)); image.at(i, j)[0] = image.at(i, j)[0] + b_slider; } } imshow("Display window", image); // Show our image inside it waitKey(25); // Wait for a keystroke i } return 0; }