【问题标题】:Search multiple colours simultaneously with opencv and c++使用opencv和c++同时搜索多种颜色
【发布时间】:2014-04-12 07:57:23
【问题描述】:

我正在尝试让下面的代码同时搜索多种颜色,例如红色,黄色和橙色。我在代码中添加了掩码,但无法正确应用我做错了什么我不确定将掩码添加到框架的行是否在正确的位置。

    #include "stdafx.h"
#include <cv.h>
#include <highgui.h>

using namespace std;

using namespace cv::gpu;



IplImage* GetThresholdedImage(IplImage* imgHSV){       
    IplImage* imgThresh=cvCreateImage(cvGetSize(imgHSV),IPL_DEPTH_8U, 1);
    cvInRangeS(imgHSV, cvScalar(170,160,60), cvScalar(180,255,256), imgThresh); 
    return imgThresh;
} 
int main(){
    //Char Firetype = type;
     CvCapture* capture = cvCaptureFromCAM(1);
     if(!capture){
        printf("Capture failure\n");
        return -1;
    }
    IplImage* frame=0;

    cvNamedWindow("Video");     
    cvNamedWindow("Fire");
    cvNamedWindow("Info");
    //iterate through each frame of the video     
    while(true){
        frame = cvQueryFrame(capture);           
        if(!frame) break;
        frame=cvCloneImage(frame); 
        cvSmooth(frame, frame, CV_GAUSSIAN,3,3); //smooth the original image using Gaussian kernel
        cv::Mat imgMat(frame);
        cv::Mat mask1;
        cv::inRange(imgMat, cv::Scalar(20, 100, 100), cv::Scalar(30, 255, 255), mask1);
        cv::Mat mask2;
        cv::inRange(imgMat, cv::Scalar(170,160,60), cv::Scalar(180,255,256), mask2);
        cv::Mat mask3;
        cv::inRange(imgMat, cv::Scalar(70,160,60), cv::Scalar(90,255,256), mask3);
        // combine them
        cv::Mat mask_combined = mask1 | mask2 | mask3;
        // now since our frame from the camera is bgr, we have to convert our mask to 3 channels:
        cv::Mat mask_rgb;
        cv::cvtColor( mask_combined, mask_rgb, CV_GRAY2BGR );
        IplImage framemask = imgMat & mask_rgb;
        IplImage* imgHSV = cvCreateImage(cvGetSize(framemask), IPL_DEPTH_8U, 3); 
        cvCvtColor(frame, imgHSV, CV_BGR2HSV); //Change the color format from BGR to HSV


        //This function threshold the HSV image and create a binary image
        // function below to get b&w image
        IplImage* imgThresh = GetThresholdedImage(imgHSV);
        cvSmooth(imgThresh, imgThresh, CV_GAUSSIAN,3,3); //smooth the binary image using Gaussian kernel
        cvShowImage("Fire", imgThresh);           
        cvShowImage("Video", frame);
        //          cvNamedWindow("Info", Firetype);           
        cvReleaseImage(&imgHSV);
        cvReleaseImage(&imgThresh);            
        cvReleaseImage(&frame);
        //Wait 50mS
        int c = cvWaitKey(10);
        //If 'ESC' is pressed, break the loop
        if((char)c==27 ) break;      
    }
    cvDestroyAllWindows() ;
    cvReleaseCapture(&capture);     
    return 0;
}

【问题讨论】:

  • 1.请不要使用 opencv 已弃用的 c-api,他们几年前就迁移到了 c++,你也应该这样做。
  • c+/c++ 这不是问题。 (你正在使用 c api,而你不应该)如果你看到使用 IplImages 的代码 - 避免它(特别是在 SO.. 上)
  • 我想指定范围以防止误报。在那种情况下,我可以使用 if 和 case 语句来声明范围吗?
  • 所以有几种颜色,你想“屏蔽”掉?
  • 没错,我正在尝试检测火灾,所以像香蕉黄这样的东西会是误报。

标签: opencv image-processing colors detection mask


【解决方案1】:

tl:dr;

使用bitwise-or 组合二进制掩码, bitwise_and 申请他们

cv::Mat mask1;
cv::inRange( hsv, cv::Scalar(20, 100, 100), cv::Scalar(30, 255, 255), mask1);
cv::Mat mask2;
cv::inRange( hsv, cv::Scalar(170,160,60),   cv::Scalar(180,255,256), mask2);
cv::Mat mask3;
cv::inRange( hsv, cv::Scalar(70,160,60),   cv::Scalar(90,255,256), mask3);

// combine them
cv::Mat mask_combined = mask1 | mask2 | mask3;

// now since our frame from the camera is bgr, we have to convert our mask to 3 channels:
cv::Mat mask_rgb;
cv::cvtColor( mask_combined, mask_rgb, CV_GRAY2BGR );

// finally, apply the mask to our image
frame = frame & mask_rgb;

【讨论】:

  • 我是放在检测部分吗?
  • 可能。老实说,我不知道你想做什么。在 opencv 中有几个操作,它们采用二进制掩码(如上面的 mask_combined),您可以使用它们。上面的例子只是众多方法中的一种
  • 如果我想将蒙版添加到 imgThresh,蒙版应该放在我添加它们的位置吗?
  • 不,你根本没有把它放到你的代码中。上面是c++,你的是c。因此,您要么必须将代码移植到 c++(无论如何都强烈推荐),要么找到一种方法使 idea 适应您的情况
  • 终于找到了我要找的东西!顺便说一句,这也适用于 python。
猜你喜欢
  • 1970-01-01
  • 2016-09-18
  • 2013-05-01
  • 2013-08-15
  • 2023-03-21
  • 2019-05-11
  • 1970-01-01
  • 1970-01-01
  • 2022-10-16
相关资源
最近更新 更多