【问题标题】:OpenCV HSV filter with range slider not working带有范围滑块的 OpenCV HSV 过滤器不起作用
【发布时间】:2020-07-19 16:47:28
【问题描述】:

我目前正在研究一种视觉系统,以检测 .jpg 文件中的蓝莓

我想尝试编写显示三个窗口的代码,一个带有我的普通图像(未过滤)图像,一个带有一组控制 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;
}

我有我正在寻找的三个窗口,但滑块似乎没有做任何事情。 有谁知道解决这个问题的方法。

抱歉,如果我不了解 OpenCV 中的简单内容,我对此很陌生。

编辑:我稍微编辑了代码以消除一些错误。

Edit2:更新代码,包含错误消息

Edit3:更新的代码,现在可以工作了!,删除了错误消息

【问题讨论】:

    标签: c++ opencv object-detection


    【解决方案1】:

    cv::waitKey 为 opencv 提供了一个“时刻”来处理您想要显示的内容。你只调用它两次,所以 opencv 只重新计算图像两次。

    在创建“控制”窗口之前,您的代码程序挂起,但您应该看到“图像”窗口。您按下任何按钮,程序将继续。它在return 之前又挂了一次。然后你应该也会看到“控制”窗口,但在此期间基本上什么都没有发生。

    添加一个循环以启用处理并从其余代码中删除对cv::waitKey 的相互调用。这种方式程序将每毫秒重新计算两个窗口。

    // 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 docs 了解更多信息。


    我没有注意到您的跟踪栏是在没有回调参数的情况下创建的 - 请参阅 createTrackbar docs。您也可能对trackbar example 感兴趣。 话虽如此,您可以采取两种方法:

    1. while 循环中调用HSVthreshold 函数
    2. 创建回调函数并在调用时将其分配为回调createTrackbar

    因为我看到无论如何都不需要HSVthreshold 参数,您可以更改此函数签名以匹配createTrackbar 所需的一个并将其分配为回调 - 所以第二种方法。代码应该是这样的:

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

    【讨论】:

    • 感谢您的帮助,我已更改 cv::waitKey 并更改了“HSVthreshold”函数的参数,因为我认为它们也有问题。但是我的代码仍然不起作用。如果你能找到我的另一个错误,你介意再看一次吗?我会用我的新代码更新我原来的帖子。
    • 再次,非常感谢!我已经在我的代码中实施了您的建议,并进行了一些一般性的清理和改进。可悲的是,它仍然不起作用。如果我尝试两种建议的方法,我目前会收到“断言失败错误”。我将用确切的错误和我的新代码更新我的原始帖子。
    • 等等,没关系!!,我要快速添加评论,看来我已经成功了。如果您有兴趣,我会将我的代码更新为有效的代码。再次感谢您指导初学者更好地理解 OpenCV。
    猜你喜欢
    • 1970-01-01
    • 2015-03-06
    • 2017-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多