是否有一个公式来确定给定 BGR 值的整体颜色? (OpenCV 和 C++)

Posted

技术标签:

【中文标题】是否有一个公式来确定给定 BGR 值的整体颜色? (OpenCV 和 C++)【英文标题】:Is there a formula to determine overall color given BGR values? (OpenCV and C++) 【发布时间】:2016-04-16 12:29:01 【问题描述】:

我正在使用 C++ 和 OpenCV 制作一个函数,它将检测图像中像素的颜色,确定它所在的颜色范围,并将其替换为通用颜色。例如,绿色的范围可以从深绿色到浅绿色,程序会确定它仍然是绿色并将其替换为简单的绿色,从而使输出图像看起来非常简单。一切都设置好了,但是我在定义每个范围的特征时遇到了麻烦,并且很好奇是否有人知道或者有一个公式,给定 BGR 值,可以确定像素的整体颜色。如果不是,我将不得不做很多实验并自己制作,但如果已经存在某些东西,那将节省时间。我做了很多研究,到目前为止还没有发现任何东西。

【问题讨论】:

'像素的整体颜色'有点模糊——你想将所有颜色映射到固定数量的颜色吗?您可以将每个颜色空间划分为 k 个不同的值,以创建一个可以标记的小空间。 int three_reds = int(floor(R / 3)); ... 然后您可以将每个范围映射到 RGB 空间中的一种颜色。 虽然有数以千计的方法可以做到这一点,有些比其他的好得多,但我相信一旦你看到了颜色的想法,你至少应该能够想出一个基本的实现立方体。 8 种角颜色为黑白、纯 RGB 和互补色。 (所以所有 6 种彩虹色)。只需选择最近的角落就可以展示一些东西。 有几个。查找“颜色量化”。 【参考方案1】:

如果你想让你的图像更简单(即颜色更少),但好看,你有几个选择:

一种简单的方法是将图像除以(整数除法)系数N,然后乘以系数N

或者您可以使用一些聚类算法(例如此处显示的kmeans)或中值切割算法将图像划分为K 颜色。

原图:

减少颜色(量化,N = 64):

减少颜色(聚集,K = 8):

代码量化:

#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()

    Mat3b img = imread("path_to_image");

    imshow("Original", img);

    uchar N = 64;
    img  /= N;
    img  *= N;

    imshow("Reduced", img);
    waitKey();

    return 0;

代码kmeans:

#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()

    Mat3b img = imread("path_to_image");

    imshow("Original", img);

    // Cluster

    int K = 8;
    int n = img.rows * img.cols;
    Mat data = img.reshape(1, n);
    data.convertTo(data, CV_32F);

    vector<int> labels;
    Mat1f colors;
    kmeans(data, K, labels, cv::TermCriteria(), 1, cv::KMEANS_PP_CENTERS, colors);

    for (int i = 0; i < n; ++i)
    
        data.at<float>(i, 0) = colors(labels[i], 0);
        data.at<float>(i, 1) = colors(labels[i], 1);
        data.at<float>(i, 2) = colors(labels[i], 2);
    

    Mat reduced = data.reshape(3, img.rows);
    reduced.convertTo(reduced, CV_8U);


    imshow("Reduced", reduced);
    waitKey();

    return 0;

【讨论】:

【参考方案2】:

是的,“像素的整体颜色”可能是指"Hue" or "Saturation" of the color.

因此,您需要一个将 RGB 转换为 HSV(色相、饱和度、值)的公式,然后您只会对色相或饱和度值感兴趣。

见:Algorithm to convert RGB to HSV and HSV to RGB in range 0-255 for both

编辑:您可能需要最大化饱和度,然后将其转换回 RGB,并检查哪个值最高(例如 (255,0,0) 或 (255,0,255) 等。

【讨论】:

【参考方案3】:

如果你想访问所有像素的RGB值,那么下面是代码,

#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()

   Mat image = imread("image_path");

   for(int row = 1; row < image.rows; row++)
   
       for(int col = 1; col < image.cols; col++)
       
           Vec3b rgb = image.at<Vec3b>(row, col);
       
   


【讨论】:

以上是关于是否有一个公式来确定给定 BGR 值的整体颜色? (OpenCV 和 C++)的主要内容,如果未能解决你的问题,请参考以下文章

如何为任何给定的 RGB 背光颜色找到完美的文本颜色 [重复]

比较BGR图像是不是完全相同[重复]

确定透明度的公式

Excel表格变颜色公式

使用模型来表示视图的整体状态

如何从给定的基色生成多个阴影?