Is there a formula to determine overall color given BGR values? (OpenCV and C++)

笑着哭i 提交于 2019-11-26 16:47:40

If you want to make your image simpler (i.e. with less colors), but good looking, you have a few options:

  • A simple approach would be to divide (integer division) by a factor N the image, and then multiply by a factor N.

  • Or you can divide your image into K colors, using some clustering algorithm such as kmeans showed here, or median-cut algorithm.

Original image:

Reduced colors (quantized, N = 64):

Reduced colors (clustered, K = 8):

Code Quantization:

#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;
}

Code 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;
}
Vincent

Yes, what you probably mean by "Overall color of a pixel" is either the "Hue" or "Saturation" of the color.

So you want a formula that transform RGB to HSV (Hue, Saturation, Value), and then you would only be interested by the Hue or Saturation values.

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

EDIT: You might need to max out the saturation, and then convert it back to RGB, and inspect which value is the highest (for instance (255,0,0), or (255,0,255), etc.

If you want to access RGB value of all pixels , then below is code,

#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);
       }
   }

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!