I am currently starting to work on a vision system to detect blueberries out of a .jpg
I want to try to make code that displays three windows, one with my normal image (unfiltered) image, one with a set of sliders that control the upper and lower HSV limits, and one that displays my filtered image.
Currently this is my code:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
Mat image;
Mat imgHSV;
Mat OutputImage;
int iLowH;
int iHighH;
int iLowS;
int iHighS;
int iLowV;
int iHighV;
static void HSVthreshold(int, int, int, int, int, int, void*)
{
inRange(imgHSV, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), OutputImage);
}
int main(int argc, char** argv)
{
//Read image
image = imread("C:\\OpenCV-test-imgs\\blueberryTest2.jpg", 1);
if (image.empty())
{
cerr << "image was not read !" << endl;
return 1;
}
//convert RGB to HSV
cvtColor(image, imgHSV, COLOR_BGR2HSV);
//Create windows
namedWindow("image", WINDOW_FREERATIO); //window for original image
namedWindow("Control", WINDOW_AUTOSIZE); //window for HSV-control sliders
namedWindow("Output", WINDOW_AUTOSIZE); //window for output mask
//Create trackbars in "Control" window
createTrackbar("LowH", "Control", &iLowH, 179); //Hue (0 - 179)
createTrackbar("HighH", "Control", &iHighH, 179);
createTrackbar("LowS", "Control", &iLowS, 255); //Saturation (0 - 255)
createTrackbar("HighS", "Control", &iHighS, 255);
createTrackbar("LowV", "Control", &iLowV, 255); //Value (0 - 255)
createTrackbar("HighV", "Control", &iHighV, 255);
int key = 0;
while (key != 27) { // 27 is escape
HSVthreshold(iLowH, iHighH, iLowS, iHighS, iLowV, iHighV, 0);
imshow("Output", OutputImage);
imshow("image", imgHSV);
key = waitKey(1); // wait at most 1 ms for input, if nothing was pressed result is -1
}
return 0;
}
I have the three windows that I'm looking for, but the sliders don't seem to do anything. Does anyone know a way to fix this.
Sorry if i'm not understanding simple things in OpenCV, I'm quite new to this.
Edit: I edited the code slightly to remove some errors.
Edit2: Updated code, included error messages
Edit3: Updated code, is working now!, removed error messages
cv::waitKey
provides a "moment" for opencv to process stuff you want to display. You are only calling it twice so opencv recalculates images only two times.
In your code program hangs before creating "Control" window, but you should see "image" window. You press any button and program continues. It hangs again one more time just before return
. Then you should see "Control" window as well but basically nothing is going on in a meantime.
Add a loop to enable processing and remove each other call to cv::waitKey
from the rest of your code. This way program will recalulate both windows every milisecond.
// rest of your code
int key = 0;
while(key != 27) { // 27 is escape
// wait at most 1 ms for input, if nothing was pressed result is -1
key = cv::waitKey(1);
}
return 0;
Please, check out cv::waitKey
docs for more info.
I did not notice that your trackbars are created without callback argument - see createTrackbar docs. Also you may be interested in trackbar example. Having said that there are two approaches you can take:
HSVthreshold
function in the while
loopcreateTrackbar
Since I see that HSVthreshold
parameters are not needed anyway you can change this function signature to match one required by createTrackbar
and assign it as callback - so 2nd approach. Code should look like that:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
using namespace std;
Mat OutputImage;
Mat image;
int iLowH;
int iHighH;
int iLowS;
int iHighS;
int iLowV;
int iHighV;
double alpha;
double beta;
// From the docs:
// "Callback function should be prototyped as void Foo(int,void*);
// first parameter is the trackbar position and the second parameter is the user data"
// Both of these are not relevant to you at this point
static void HSVthreshold(int, void*)
{
inRange(image, Scalar(iLowH, iLowS, iLowV), Scalar(iHighH, iHighS, iHighV), OutputImage);
}
int main(int argc, char** argv)
{
image = imread("C:\\OpenCV-test-imgs\\blueberryTest1.jpg", 1);
// Create all windows
namedWindow("image", WINDOW_FREERATIO);
namedWindow("Control", WINDOW_AUTOSIZE);
namedWindow("Output", WINDOW_AUTOSIZE);
// Create trackbars in "Control" window - add callback HSVthreshold
createTrackbar("LowH", "Control", &iLowH, 179, HSVthreshold); //Hue (0 - 179)
createTrackbar("HighH", "Control", &iHighH, 179, HSVthreshold);
createTrackbar("LowS", "Control", &iLowS, 255, HSVthreshold); //Saturation (0 - 255)
createTrackbar("HighS", "Control", &iHighS, 255, HSVthreshold);
createTrackbar("LowV", "Control", &iLowV, 255, HSVthreshold); //Value (0 - 255)
createTrackbar("HighV", "Control", &iHighV, 255, HSVthreshold);
int key = 0;
while (key != 27) {
// Refresh images
imshow("Output", OutputImage);
imshow("image", image);
key = waitKey(1);
}
return 0;
}