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