Существует ли формула для определения общего цвета с учетом значений BGR? (OpenCV и C ++)

Я делаю функцию с использованием C ++ и OpenCV, которая будет определять цвет пикселя в изображении, определять его цветовую гамму и заменять его на общий цвет. Например, зеленый может варьироваться от темно-зеленого до светло-зеленого, программа определит, что он все еще зеленый, и заменит его простым зеленым, что сделает выходное изображение очень простым. все настроено, но у меня возникают проблемы с определением характеристик каждого диапазона, и мне было любопытно, если кто-нибудь знает или формулу, которая, учитывая значения BGR, могла бы определить общий цвет пикселя. Если нет, мне придется много экспериментировать и делать это самому, но если что-то уже существует, это сэкономит время. Я провел много исследований и пока не нашел ничего.

 beaker12 янв. 2016 г., 17:18
Есть несколько. Посмотрите "квантование цвета".
 Pyrce12 янв. 2016 г., 03:07
«Общий цвет пикселя» несколько расплывчат - есть ли фиксированное количество цветов, в которое вы хотите отобразить все цвета? Вы можете разделить каждое цветовое пространство на k различных значений, чтобы создать небольшое пространство, которое можно пометить.int three_reds = int(floor(R / 3)); ... Затем вы можете просто сопоставить каждый диапазон с одним цветом из пространства RGB.
 MSalters12 янв. 2016 г., 09:30
Хотя есть тысячи способов сделать это, некоторые намного лучше, чем другие, я полагаю, что вы должны были бы предложить хотя бы базовую реализацию, как только увидели идею цветового куба. 8 угловых цветов: черный и белый, чистый RGB и дополнительные цвета. (так что все 6 цветов радуги). Просто выбрав ближайший угол, вы могли бы что-то показать.

Ответы на вопрос(3)

проще (то есть с меньшим количеством цветов), но хорошо выглядящий, у вас есть несколько вариантов:

Простой подход будет разделить (целочисленное деление) факторомN изображение, а затем умножить на коэффициентN.

Или вы можете разделить свое изображение наK цвета, используя некоторый алгоритм кластеризации, такой какkmeans показанный здесь, или алгоритм медианного разреза.

Исходное изображение:

Уменьшенные цвета (квантованные,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;
}
 bcrist12 янв. 2016 г., 04:37
Амбар Моултона <3

то ниже приведен код,

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

}

то, что вы, вероятно, подразумеваете под «общим цветом пикселя», является«Оттенок» или «Насыщенность» цвета.

Поэтому вам нужна формула, которая преобразует RGB в HSV (оттенок, насыщенность, значение), и тогда вас будут интересовать только значения оттенка или насыщенности.

Увидеть:Алгоритм преобразования RGB в HSV и HSV в RGB в диапазоне 0-255 для обоих

РЕДАКТИРОВАТЬ: вам может потребоваться максимизировать насыщенность, а затем преобразовать ее обратно в RGB и проверить, какое значение является самым высоким (например, (255,0,0) или (255,0255) и т. Д.

Ваш ответ на вопрос