获取图片某种颜色所占百分比

  • Post author:
  • Post category:其他


C++/C#获取蓝色在图片中所占百分比



思路

由于每种颜色都有一个阈值,单纯的计算RGB百分比的效果并不好,对于这点,网上已经有很多结论。于是,我想到采用hsv空间下每个像素点分量,获取某种颜色所占百分比(我这里采用的是蓝色)。因为,在hsv空间下,相近颜色都会被归于一个

范围

。所以,我们可以比较相近颜色,在图片中,所占百分比。C++与C#代码有些许不同。具体如下:



代码



C++

#include <iostream>
#include <opencv2/opencv.hpp>
#include <iomanip>
#include <cmath>
#include <string>
#include <opencv2/highgui/highgui_c.h>
#include <unordered_map>
#include <vector>
using namespace std;
using namespace cv;
//struct Triple
//{
//    char col[_MAX_PATH];
//    int h_min;
//    int s_min;
//    int v_min;
//    int h_max;
//    int s_max;
//    int v_max;
//};
/*
区分不同颜色,在图片中所占百分比
*/
unordered_map<string,float> hsv_percentage(Mat hsv_image) {
    int num_black = 0;
    int num_grey = 0;
    int num_white = 0;
    int num_red = 0;
    int num_orange = 0;
    int num_yellow = 0;
    int num_green = 0;
    int num_blue = 0;
    int num_purple = 0;
    //vector<float> record(9,0);
    unordered_map<string, float> record;
    float area = (float)(hsv_image.rows * hsv_image.cols);
    for (int i = 0; i < hsv_image.rows; i++) //行数
    {
        for (int j = 0; j < hsv_image.cols; j++)   //列数
        {
            //在这里操作具体元素
            //{"black", 0, 0, 0, 180, 255, 46}
           if ((hsv_image.at<Vec3b>(i, j)[0] >= 0 && hsv_image.at<Vec3b>(i, j)[0] <= 180)
             && (hsv_image.at<Vec3b>(i, j)[1] >= 0 && hsv_image.at<Vec3b>(i, j)[1] <= 255)
             && (hsv_image.at<Vec3b>(i, j)[2] >= 0 && hsv_image.at<Vec3b>(i, j)[2] <= 46)) {
                 num_black++;
           }
           //{ "grey",0,0,46,180,43,220 }
           else if ((hsv_image.at<Vec3b>(i, j)[0] >= 0 && hsv_image.at<Vec3b>(i, j)[0] <= 180)
                && (hsv_image.at<Vec3b>(i, j)[1] >= 0 && hsv_image.at<Vec3b>(i, j)[1] <= 43)
                && (hsv_image.at<Vec3b>(i, j)[2] >= 46 && hsv_image.at<Vec3b>(i, j)[2] <= 220)) {
                num_grey++;
            }
           // { "white",0,0,221,180,30,255 }
            else if ((hsv_image.at<Vec3b>(i, j)[0] >= 0 && hsv_image.at<Vec3b>(i, j)[0] <= 180)
                && (hsv_image.at<Vec3b>(i, j)[1] >= 0 && hsv_image.at<Vec3b>(i, j)[1] <= 30)
                && (hsv_image.at<Vec3b>(i, j)[2] >= 221 && hsv_image.at<Vec3b>(i, j)[2] <= 255)) {
               num_white++;
            }
           //{ "red", 156, 43, 46, 180, 255, 255 }
            else if ((hsv_image.at<Vec3b>(i, j)[0] >= 156 && hsv_image.at<Vec3b>(i, j)[0] <= 180)
                && (hsv_image.at<Vec3b>(i, j)[1] >= 43 && hsv_image.at<Vec3b>(i, j)[1] <= 255)
                && (hsv_image.at<Vec3b>(i, j)[2] >= 46 && hsv_image.at<Vec3b>(i, j)[2] <= 255)) {
                num_red++;
            }
            else if ((hsv_image.at<Vec3b>(i, j)[0] >= 0&& hsv_image.at<Vec3b>(i, j)[0] <= 10)
                && (hsv_image.at<Vec3b>(i, j)[1] >= 43 && hsv_image.at<Vec3b>(i, j)[1] <= 255)
                && (hsv_image.at<Vec3b>(i, j)[2] >= 46 && hsv_image.at<Vec3b>(i, j)[2] <= 255)) {
                num_red++;
            }
           //{ "orange",11,43,46,25,255,255 }
            else if ((hsv_image.at<Vec3b>(i, j)[0] >= 11 && hsv_image.at<Vec3b>(i, j)[0] <= 25)
                && (hsv_image.at<Vec3b>(i, j)[1] >= 43 && hsv_image.at<Vec3b>(i, j)[1] <= 255)
                && (hsv_image.at<Vec3b>(i, j)[2] >= 46 && hsv_image.at<Vec3b>(i, j)[2] <= 255)) {
                num_orange++;
            }
           // { "yellow", 26, 43, 46, 34, 255, 255 }
            else if ((hsv_image.at<Vec3b>(i, j)[0] >= 26 && hsv_image.at<Vec3b>(i, j)[0] <= 34)
                && (hsv_image.at<Vec3b>(i, j)[1] >= 43 && hsv_image.at<Vec3b>(i, j)[1] <= 255)
                && (hsv_image.at<Vec3b>(i, j)[2] >= 46 && hsv_image.at<Vec3b>(i, j)[2] <= 255)) {
                num_yellow++;
            }
           //{ "green",35,43,46,99,255,255 },
            else if ((hsv_image.at<Vec3b>(i, j)[0] >= 35 && hsv_image.at<Vec3b>(i, j)[0] <= 99)
                && (hsv_image.at<Vec3b>(i, j)[1] >= 43 && hsv_image.at<Vec3b>(i, j)[1] <= 255)
                && (hsv_image.at<Vec3b>(i, j)[2] >= 46 && hsv_image.at<Vec3b>(i, j)[2] <= 255)) {
                num_green++;
            }
           //{ "blue",100,43,46,124,255,255 },
            else if ((hsv_image.at<Vec3b>(i, j)[0] >= 100 && hsv_image.at<Vec3b>(i, j)[0] <= 124)
                && (hsv_image.at<Vec3b>(i, j)[1] >= 43 && hsv_image.at<Vec3b>(i, j)[1] <= 255)
                && (hsv_image.at<Vec3b>(i, j)[2] >= 46 && hsv_image.at<Vec3b>(i, j)[2] <= 255)) {
                num_blue++;
            }
           //  { "purple",125,43,46,155,255,255 }
            else if ((hsv_image.at<Vec3b>(i, j)[0] >= 125 && hsv_image.at<Vec3b>(i, j)[0] <= 155)
                && (hsv_image.at<Vec3b>(i, j)[1] >= 43 && hsv_image.at<Vec3b>(i, j)[1] <= 255)
                && (hsv_image.at<Vec3b>(i, j)[2] >= 46 && hsv_image.at<Vec3b>(i, j)[2] <= 255)) {
                num_purple++;
            }
        }
    }
    
    record.insert(make_pair("black", (float)num_black / area));
    record.insert(make_pair("grey", (float)num_grey / area));
    record.insert(make_pair("white", (float)num_white / area));
    record.insert(make_pair("red", (float)num_red / area));
    record.insert(make_pair("orange", (float)num_orange / area));
    record.insert(make_pair("yellow", (float)num_yellow / area));
    record.insert(make_pair("green", (float)num_green / area));
    record.insert(make_pair("blue", (float)num_blue / area));
    record.insert(make_pair("purple", (float)num_purple / area));
    //(float)num / (float)(hsv_image.rows * hsv_image.cols);
    return record;
}
/*
在图片里查找指定颜色的比例
*/
void Mat_color_Find(string qimage)
{
    Mat image = imread(qimage);//将图片加载进来
    if (image.empty())
    {
        cout << "could not load image...\n" << endl;
        return;
    }
    Mat hsv_image;
    cvtColor(image, hsv_image, CV_BGR2HSV);
    
    unordered_map<string, float> temp = hsv_percentage(hsv_image);
    //rat = (float)num / (float)(hsv_image.rows * hsv_image.cols);
    for (auto it = temp.begin(); it != temp.end();it++) {
        cout << it->first << " " <<it->second << endl;
    }
    return;
}
int main(){
    /*struct Triple colour[9] =
    {
        {"black",0,0,0,180,255,46},
        {"grey",0,0,46,180,43,220},
        {"white",0,0,221,180,30,255},
        {"red",156,43,46,180,255,255},
        {"orange",11,43,46,25,255,255},
        {"yellow",26,43,46,34,255,255},
        {"green",35,43,46,99,255,255},
        {"blue",100,43,46,124,255,255},
        {"purple",125,43,46,155,255,255}
    };*/
    string s = "C:/Users/wenhaofu/Desktop/picture/2021-07-01.png";
    Mat_color_Find(s);
    //cout << blue_temp << endl;
}




C#

public void Checkcolourgreaterthan(string colour, float percentage,string path)
        {
            Mat mat = new Mat(path, ImreadModes.AnyColor);
            Mat imgHSV = new Mat();
            Dictionary<string, float> temp = new Dictionary<string, float>();
            Cv2.CvtColor(mat, imgHSV, ColorConversionCodes.BGR2HSV);
            temp = Hsv_percentage(imgHSV);
            foreach (var item in temp)
            {
                Console.WriteLine($"key={item.Key},value={item.Value}");
                if (item.Key == colour) {
                    Assert.IsTrue(item.Value>=percentage, item.Value+" < "+ percentage);
                }
            }
        }
private static Dictionary<string, float> Hsv_percentage(Mat hsv_image)
        {
            int num_black = 0;
            int num_grey = 0;
            int num_white = 0;
            int num_red = 0;
            int num_orange = 0;
            int num_yellow = 0;
            int num_green = 0;
            int num_blue = 0;
            int num_purple = 0;
            //vector<float> record(9,0);
            Dictionary<string, float> record = new Dictionary<string, float>();
            float area = (float)(hsv_image.Rows * hsv_image.Cols);
            Console.WriteLine("area: " + area);
            for (int i = 0; i < hsv_image.Rows; i++) //行数
            {
                for (int j = 0; j < hsv_image.Cols; j++)   //列数
                {
                    //在这里操作具体元素
                    //{"black", 0, 0, 0, 180, 255, 46}
                    if ((hsv_image.Get<Vec3b>(i, j).Item0 >= 0 && hsv_image.Get<Vec3b>(i, j).Item0 <= 180)
                      && (hsv_image.Get<Vec3b>(i, j).Item1 >= 0 && hsv_image.Get<Vec3b>(i, j).Item1 <= 255)
                      && (hsv_image.Get<Vec3b>(i, j).Item2 >= 0 && hsv_image.Get<Vec3b>(i, j).Item2 <= 46))
                    {
                        num_black++;
                    }
                    //{ "grey",0,0,46,180,43,220 }
                    else if ((hsv_image.Get<Vec3b>(i, j).Item0 >= 0 && hsv_image.Get<Vec3b>(i, j).Item0 <= 180)
                         && (hsv_image.Get<Vec3b>(i, j).Item1 >= 0 && hsv_image.Get<Vec3b>(i, j).Item1 <= 43)
                         && (hsv_image.Get<Vec3b>(i, j).Item2 >= 46 && hsv_image.Get<Vec3b>(i, j).Item2 <= 220))
                    {
                        num_grey++;
                    }
                    // { "white",0,0,221,180,30,255 }
                    else if ((hsv_image.Get<Vec3b>(i, j).Item0 >= 0 && hsv_image.Get<Vec3b>(i, j).Item0 <= 180)
                        && (hsv_image.Get<Vec3b>(i, j).Item1 >= 0 && hsv_image.Get<Vec3b>(i, j).Item1 <= 30)
                        && (hsv_image.Get<Vec3b>(i, j).Item2 >= 221 && hsv_image.Get<Vec3b>(i, j).Item2 <= 255))
                    {
                        num_white++;
                    }
                    //{ "red", 156, 43, 46, 180, 255, 255 }
                    else if ((hsv_image.Get<Vec3b>(i, j).Item0 >= 156 && hsv_image.Get<Vec3b>(i, j).Item0 <= 180)
                        && (hsv_image.Get<Vec3b>(i, j).Item1 >= 43 && hsv_image.Get<Vec3b>(i, j).Item1 <= 255)
                        && (hsv_image.Get<Vec3b>(i, j).Item2 >= 46 && hsv_image.Get<Vec3b>(i, j).Item2 <= 255))
                    {
                        num_red++;
                    }
                    else if ((hsv_image.Get<Vec3b>(i, j).Item0 >= 0 && hsv_image.Get<Vec3b>(i, j).Item0 <= 10)
                        && (hsv_image.Get<Vec3b>(i, j).Item1 >= 43 && hsv_image.Get<Vec3b>(i, j).Item1 <= 255)
                        && (hsv_image.Get<Vec3b>(i, j).Item2 >= 46 && hsv_image.Get<Vec3b>(i, j).Item2 <= 255))
                    {
                        num_red++;
                    }
                    //{ "orange",11,43,46,25,255,255 }
                    else if ((hsv_image.Get<Vec3b>(i, j).Item0 >= 11 && hsv_image.Get<Vec3b>(i, j).Item0 <= 25)
                        && (hsv_image.Get<Vec3b>(i, j).Item1 >= 43 && hsv_image.Get<Vec3b>(i, j).Item1 <= 255)
                        && (hsv_image.Get<Vec3b>(i, j).Item2 >= 46 && hsv_image.Get<Vec3b>(i, j).Item2 <= 255))
                    {
                        num_orange++;
                    }
                    // { "yellow", 26, 43, 46, 34, 255, 255 }
                    else if ((hsv_image.Get<Vec3b>(i, j).Item0 >= 26 && hsv_image.Get<Vec3b>(i, j).Item0 <= 34)
                        && (hsv_image.Get<Vec3b>(i, j).Item1 >= 43 && hsv_image.Get<Vec3b>(i, j).Item1 <= 255)
                        && (hsv_image.Get<Vec3b>(i, j).Item2 >= 46 && hsv_image.Get<Vec3b>(i, j).Item2 <= 255))
                    {
                        num_yellow++;
                    }
                    //{ "green",35,43,46,99,255,255 },
                    else if ((hsv_image.Get<Vec3b>(i, j).Item0 >= 35 && hsv_image.Get<Vec3b>(i, j).Item0 <= 99)
                        && (hsv_image.Get<Vec3b>(i, j).Item1 >= 43 && hsv_image.Get<Vec3b>(i, j).Item1 <= 255)
                        && (hsv_image.Get<Vec3b>(i, j).Item2 >= 46 && hsv_image.Get<Vec3b>(i, j).Item2 <= 255))
                    {
                        num_green++;
                    }
                    //{ "blue",100,43,46,124,255,255 },
                    else if ((hsv_image.Get<Vec3b>(i, j).Item0 >= 100 && hsv_image.Get<Vec3b>(i, j).Item0 <= 124)
                        && (hsv_image.Get<Vec3b>(i, j).Item1 >= 43 && hsv_image.Get<Vec3b>(i, j).Item1 <= 255)
                        && (hsv_image.Get<Vec3b>(i, j).Item2 >= 46 && hsv_image.Get<Vec3b>(i, j).Item2 <= 255))
                    {
                        num_blue++;
                    }
                    //  { "purple",125,43,46,155,255,255 }
                    else if ((hsv_image.Get<Vec3b>(i, j).Item0 >= 125 && hsv_image.Get<Vec3b>(i, j).Item0 <= 155)
                        && (hsv_image.Get<Vec3b>(i, j).Item1 >= 43 && hsv_image.Get<Vec3b>(i, j).Item1 <= 255)
                        && (hsv_image.Get<Vec3b>(i, j).Item2 >= 46 && hsv_image.Get<Vec3b>(i, j).Item2 <= 255))
                    {
                        num_purple++;
                    }
                }
            }
            //Console.WriteLine("num_blue: " + num_blue);
            record.Add("black", (float)num_black / area);
            record.Add("grey", (float)num_grey / area);
            record.Add("white", (float)num_white / area);
            record.Add("red", (float)num_red / area);
            record.Add("orange", (float)num_orange / area);
            record.Add("yellow", (float)num_yellow / area);
            record.Add("green", (float)num_green / area);
            record.Add("blue", (float)num_blue / area);
            record.Add("purple", (float)num_purple / area);
            //(float)num / (float)(hsv_image.rows * hsv_image.cols);
            return record;

        }



运行结果

test



测试图片

Think_pad

获取其中各种颜色所占百分比



版权声明:本文为FuWen_Hao原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。