OpenCV HSV фильтр с ползунком диапазона не работает - PullRequest
0 голосов
/ 07 апреля 2020

В настоящее время я начинаю работать над системой видения для обнаружения черники из .jpg

Я хочу попробовать создать код, который отображает три windows, один с моим обычным изображением (без фильтра) один с набором ползунков, которые контролируют верхний и нижний пределы HSV, и один, который отображает мое отфильтрованное изображение.

В настоящее время это мой код:

#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;
}

У меня есть три windows, который я ищу, но ползунки, похоже, ничего не делают. Кто-нибудь знает способ исправить это.

Извините, если я не разбираюсь в простых вещах в OpenCV, я совершенно новичок в этом.

Редактировать: Я немного отредактировал код, чтобы удалить некоторые ошибки.

Edit2: обновлен код, включены сообщения об ошибках

Edit3: обновлен код, теперь работает !, удалены сообщения об ошибках

1 Ответ

0 голосов
/ 07 апреля 2020

cv::waitKey предоставляет "момент" для opencv для обработки материала, который вы хотите отобразить. Вы вызываете его только дважды, поэтому opencv пересчитывает изображения только два раза.

В вашем коде программа зависает перед созданием окна «Управление», но вы должны увидеть окно «изображение». Вы нажимаете любую кнопку, и программа продолжается. Он снова зависает еще раз перед return. Затем вы также должны увидеть окно «Управление», но в основном ничего не происходит в это время.

Добавьте al oop, чтобы разрешить обработку и удалите каждый вызов cv::waitKey из остальной части вашего кода. Таким образом, программа будет пересчитывать как windows каждую миллисекунду.

// 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;

Пожалуйста, проверьте cv::waitKey документы для получения дополнительной информации.


Я не заметил, что ваши трекбары созданы без аргумента обратного вызова - см. createTrackbar docs . Также вас может заинтересовать пример трекбара . Сказав, что есть два подхода, которые вы можете использовать:

  1. Вызовите функцию HSVthreshold в while l oop
  2. Создать функцию обратного вызова и назначьте ее в качестве обратного вызова, когда Вы вызываете createTrackbar

Поскольку я вижу, что параметры HSVthreshold в любом случае не нужны, вы можете изменить эту сигнатуру функции, чтобы она соответствовала той, которая требуется для createTrackbar, и назначить ее как обратный вызов - так что 2-й подход. Код должен выглядеть так:

#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;
}
...