在Opencv中提取图像中颜色(红色、蓝色、绿色、黄色、橙色)的百分比?

在Opencv中提取图像中颜色(红色、蓝色、绿色、黄色、橙色)的百分比?,opencv,colors,hsv,Opencv,Colors,Hsv,我必须区分5种类型的图像,它们可能大部分是红色、绿色、蓝色、橙色或黄色,还有一些白色或黑色。我必须找出图像中突出的颜色 图像的来源是网络摄像头,因此实际的颜色也取决于照明和图像与网络摄像头的距离。我的图片示例如下所示: 我试图根据“色调”值计算百分比。我为每种颜色指定了一些范围。我的范围是: 红色:0-10 绿色:50-65 黄色:18-21 蓝色:100-115 问题:即使显示的图像不是红色,但红色的比例仍然很高 我的代码如下: int findRect::checkByHSV(int sv

我必须区分5种类型的图像,它们可能大部分是红色、绿色、蓝色、橙色或黄色,还有一些白色或黑色。我必须找出图像中突出的颜色

图像的来源是网络摄像头,因此实际的颜色也取决于照明和图像与网络摄像头的距离。我的图片示例如下所示:

我试图根据“色调”值计算百分比。我为每种颜色指定了一些范围。我的范围是:

红色:0-10
绿色:50-65

黄色:18-21

蓝色:100-115

问题:即使显示的图像不是红色,但红色的比例仍然很高

我的代码如下:

int findRect::checkByHSV(int svmResult, Mat detectedSquare)
{

    Mat hsv_img;
    cvtColor(detectedSquare,hsv_img,CV_BGR2HSV);

    Vec3b pixel;
    float totalPixel=0; // to count the total number of pixels in an image---to get the Percentage later
    float totalClass[6];// because we want to test for 5 classes+ a garbage class.{{ Class-0 -> Garbage, Class-1->Orange, Class-2->Green, Class-3->Red, 
                        //  Class-4->Blue, Class-5->Yellow }} 

    for(int i=0; i<hsv_img.rows; i++)
    {
        for (int j=0; j<hsv_img.cols; j++)
        {

            totalPixel++;
            pixel= hsv_img.at<Vec3b>(i,j);

            if(  pixel[0]>0 &&  pixel[0]<1  )           totalClass[1]++;    // Class-1->Orange
            else if (  pixel[0]>50 &&  pixel[0]<65  )   totalClass[2]++;    // To check Green class-2 //svmResult==2 && 
            else if (  pixel[0]>0 &&  pixel[0]<10  )        totalClass[3]++;    // Class-3->Red
            else if (  pixel[0]>100 &&  pixel[0]<115  )     totalClass[4]++;    // Class-4->Blue
            else if (  pixel[0]>18 &&  pixel[0]<21  )       totalClass[5]++;    // Class-5->Yellow
        }

    }

    float percentage[5];
    totalClass[0]=0; //Putting zero to the Garbage class

    for (int i=0; i<=5; i++)
    {
        percentage[i] = (totalClass[i] / totalPixel )*100;
    }

    cout<<"\n Organge: "<<percentage[1]<<"  Green: "<<percentage[2]<<"  Red: "<<percentage[3]<<"  Blue: "<<percentage[4]<<"  Yellow: "<<percentage[5]<<"\n \n";

    return svmResult;
}
int findRect::checkByHSV(int svmResult,Mat detectedSquare)
{
Mat hsv_img;
CVT颜色(检测方形、hsv\U img、CV\U BGR2HSV);
矢量3b像素;
float totalPixel=0;//计算图像中的像素总数---稍后获取百分比
float totalClass[6];//因为我们要测试5个类+一个垃圾类。{{class-0->垃圾,class-1->橙色,class-2->绿色,class-3->红色,
//4级->蓝色,5级->黄色}
对于(int i=0;i50&&pixel[0]0&&pixel[0]红色
如果(像素[0]>100&&像素[0]蓝色
如果(像素[0]>18&&像素[0]为黄色
}
}
浮动百分比[5];
totalClass[0]=0;//将零放入垃圾类

对于(int i=0;i您可以使用函数countNonZero并除以图像的总像素数。使用示例:

vector<Mat> channels;
split(hsv_img,channels);

Mat red, blue, green;
inRange(channels[0], Scalar(0), Scalar(10), red); // red
// ... do the same for blue, green, etc only changing the Scalar values

double image_size = hsv_img.cols*hsv_img.rows;
double red_percent = ((double) cv::countNonZero(red))/image_size;
矢量信道;
分割(hsv_img、频道);
席红、蓝、绿;
在范围内(通道[0],标量(0),标量(10),红色);//红色
//…对蓝色、绿色等执行相同操作,仅更改标量值
双图像大小=hsv_img.cols*hsv_img.rows;
双红百分比=((双)cv::countNonZero(红色))/image\u size;

但是,根据应用程序的不同,它可能不是最佳的(例如,如果您需要扫描大量图像)。无论如何,您可以使用它来比较值。

您提到可以使用一些白色和/或黑色

HSV允许您对H组件具有任何值,并且:

  • 高V、低S表示白色
  • 低V表示黑色
  • 换句话说:如果你只根据H分量判断,白色和黑色可以给你红色、绿色、橙色或…等等


    就我个人而言,我会说坚持RGB(或BGR)或补偿S和V会影响颜色的事实。

    问题是黑色或白色的色调为0(红色)。但在这种情况下,饱和度非常低。你可以做的是将每个像素乘以某个地方的饱和度

    例如:

    • 使用阈值和and操作,创建一个二值图像,其中“红色”像素为白色,所有非红色像素为黑色
    • 将这个图像乘以饱和度。现在你将得到一个灰度图像,显示每个像素的红色程度
    • 如果需要二值图像,可以设置第二个图像的阈值

    纯黑色被计算为红色(色调=0),但蓝黑色(非常深的蓝色)也会有同样的问题。因此,对于要检测的所有颜色,都应重复前面的步骤。

    图像是什么颜色?此外,OpenCV色调光谱环绕。红色将为0-10和170-180@Osiris:正如我已经提到的,图像可以主要由红色、绿色、橙色、蓝色或黄色组成,也可以有一些黑色或白色ular图像。你是说显示的图像不是红色的。你希望得到什么输出?也许你可以在帖子中包含该图像。我现在无法在这里嵌入图像。我的意思是,任何不是红色的图像,即大部分是绿色、蓝色或黄色。问题是,对于此类图像,我的红色比例很高。主要问题是黄色的图像法师…谢谢你的回答。你的答案看起来很有条理,但我也在用其他代码做同样的事情。事实上,输入的图像不断变化,照明也可能会变化。这不会是一个问题,只是重新加载图像并再次使用代码的问题。关于照明的变化,你可以均衡直方图在执行操作之前。编辑:我没有看到您在问题中提到的网络摄像头。我认为可以实时运行代码。尝试测试并查看它是否有效。由于我没有得到预期的结果,因此我认为最好进行直方图匹配。现在,我想创建两幅图像的直方图(输入图像和示例图像)。由于两张图像的大小几乎相同,因此,我不想在某个窗口上滑动一张图像来计算直方图……你能告诉我怎么做吗?你可以问一个新问题来回答你的评论。我不确定我是否理解幻灯片部分,但要比较/匹配直方图,请看本教程:但我认为在RGB中是这样的在HSV中,我可以直接从色调成分中提取颜色。所有图像中的白色和黑色成分或多或少是相同的。图像因其主要颜色不同而不同,可能是红色、绿色、橙色、蓝色或黄绿色=>小红、小蓝,大部分是绿色红色,大部分蓝色,部分绿色。红色=>大部分红色,部分蓝色,部分绿色。橙色=>大部分红色,部分蓝色,部分绿色。黄色=>大部分红色,部分蓝色,部分绿色。